hadoop yarn 获取日志_在 YARN 中简化用户日志的管理和使用
Hadoop 的用戶日志有很多的用途, 首先最重要的是, 它們能用來調試 MapReduce 應用(application)的問題, 可能是應用本身的問題, 或者在極少數的情況下, 當在集群中執行應用時, 日志可以用來調試硬件或者平臺的問題所引起的 task/job 的失敗. 其次, 人們可以通過分析歷史日志來了解單個任務(task)在 job/workflow 中的歷史表現, 甚至可以用 Hadoop 的 MapReduce 來分析 MapReduce 的用戶日志(user-logs)來確定性能問題.
在以前, 處理應用(application)生成的用戶日志已經成了安裝 Hadoop 過程中的一個最大痛點. 在 Hadoop 1.x, 用戶日志被 TaskTracker 留在每個節點上, 這樣長期來看在各個節點上的用戶日志的是難于管理并且也很難被獲取和使用到的. YARN 處理日志管理問題的辦法是讓 NodeManagers(NMs) 提供一個選項, 可以在應用結束后將日志文件安全地移到一個分布式文件系統中, 比如 HDFS.
動機
在 Hadoop 1.x 的各發行版中, MapReduce 是用戶唯一可用的編程模型. 每個 MapReduce job 會執行一堆 mapper 和 reducer, 每個 map/reduce task 在本地磁盤上直接生成日志, 比如 syslog/stderr/stdout 或者 profile.out/debug.out 等等. 這些 task 日志可以通過網頁讀取到, 這種方式也是最方便的方式, 其次就是直接登錄到節點服務器上去查看日志文件.
Hadoop 1.x 中日志管理的狀態
為了處理用戶的 task-logs, TaskTrackers(TTs) 要使用 UserLogManager, 它是由下面幾個組件構成:
UserLogCleaner: 它在 job 結束后的一段時間后就把這個 job 的日志清理. 這個時間的長度通過 mapred.userlog.retain.hours 配置來調整, 默認值是一天. 它把每個 job 的用戶日志文件夾加入線程中等待保留時間后就可以將其刪除.
在那之上, 每個 TaskTracker 重啟后, 所有在 ${mapred.local.dir}/userlogs 中的日志都會被加到 UserLogCleaner 上.
TaskLogsTruncater: 這個組件是在 task 結束后截斷超過一定長度的日志文件. 配置 mapreduce.cluster.map.userlog.retain-size 和 mapreduce.cluster.reduce.userlog.retain-size 就是控制日志文件可以保留多長. 這里的做的假設是, 如果一個 task 出錯, 它的錯誤信息通常會出現在日志文件的尾部, 這樣當日志文件超出一定大小后我們可以截斷丟棄日志的頭部內容.
mapred.userlog.limit.kb 是早于上面這個的一個解決方案: 當 task 在運行時, 它的 stdout 和 stderr 流數據會導向 unix 的 tail 程序, 并且設置 tail 程序只保留一定大小的日志, 然后寫入到 stdout/stderr 文件中.
下面還有一些最終沒有被并入生成環境的工作:
Log collection: 用戶可以啟動執行在 client/gateway 機器上的 LogCollector 程序來將每個 job 的日志存入一個緊格式.
殺掉日志文件超過 N GB 的 tasks, 因為一個失控的 task 的日志會填滿磁盤導致宕機.
現存日志管理的問題
截斷(Truncation): 用戶比預期的更頻繁抱怨截斷日志的問題, 又很少有用戶需要所有的日志內容. 不限制日志大小能滿足所有人, 100KB 大小能滿足一部分人, 但是不是所有.
失控的任務(Run-away tasks): TaskTrackers/DataNodes 還是有可能因為超大的日志文件把磁盤空間給占滿, 因為截斷只會發生在 task 結束之后.
保留時間不足(Insufficient retention): 用戶會抱怨很長的保留時間, 沒法滿足所有人的需求, 默認的一天保留時間對很多人都是夠用的, 但是還是有人抱怨沒法做后續的歷史分析.
獲取(Access): 通過 HTTP 來供日志查看完全依賴于 job 的完成時間和保留時間, 這不是很可靠.
收集狀態(Collection status): 同樣地, 日志收集工具也沒有很好的可靠性, 這種辦法需要建立更多的解決方案去檢測日志收集器的啟動和結束, 以及何時需要從 TTs 管理的日志文件切換到日志收集器.
mapred.userlog.limit.kb 增加每個 task 的內存使用, 并且也不支持 YARN 的更一般的 application container.
歷史日志分析: 所有通過 HTTP 可以訪問的日志僅當這些日志還存在節點服務器上, 如果用戶想要做歷史日志的分析就需要使用日志收集器以及相關的工具.
Load-balancing & SPOF: 所有的日志都寫入到一個日志文件夾中, 沒有跨磁盤的加載平衡, 如果一個磁盤出了問題, 那么所有 job 的日志都會丟失.
現存的解決方案是解決了最基礎的問題, 我們現在有機會去做得更好, 啟用平臺內的日志聚合.
YARN 中日志聚合的詳細描寫
NodeManager 就沒有像之前 TaskTracker 那樣去截斷用戶日志, 把日志留在每個節點的本地, 它通過提供一個選項可以在應用結束后將日志安全地移動到分布式文件系統中, 比如 HDFS.
對屬于同一個應用(Application), 跑在一個 NM 上的所有容器(containers)的日志都會被聚合并寫入一個配置好地址的(很可能是壓縮過的)日志文件中.
在當前的實現中, 一個應用一結束就會得到如下:
應用級別的日志日志目錄和
此節點上該應用的所有的容器的日志文件
用戶能通過 YARN 的命令行工具, 網頁端或者直接從文件系統(FS)中來查看這些日志, 沒必要只局限于網頁端一種形式.
通過將日志文件存儲在分布式文件系統中, 比起第一代的實現, 現在可以讓日志文件存儲更長的時間.
我們不再需要去截斷日志文件, 只要日志文件的長度是合理的, 我們就會保存整個日志文件.
除此之外, 在容器運行中時, 日志會被寫入多個節點的目錄中, 這樣可以實現有效的負載均衡, 增加容錯.
AggregatedLogDeletionService 是一個定期刪除聚合后的日志的服務. 現在它只運行在 MapReduce JobHistoryServer 中.
用法
網頁端訪問(Web UI)
通過網頁端訪問, 需要知道的事情是, 日志的聚合操作用戶是感覺不到的.
當 MapReduce 應用還在執行中時, 用戶查看日志是通過 ApplicationMaster UI 來訪問的, 后者會自動跳轉到 NodeManager UI 上.
一旦應用結束, 所有的日志都會歸屬到 MapReduce 的 JobHistoryServer 中, 此時將由后者來提供日志訪問.
對于 非-MapReduce 應用, 由更一般性質的 ApplicationHistoryServer 來提供一樣的日志訪問服務.
命令行訪問
除了可以通過網頁端訪問, 我們同樣可以命令行工具來和日志做交互.
> $HADOOP_YARN_HOME/bin/yarn logs
Retrieve logs for completed YARN applications.
usage: yarn logs -applicationId [OPTIONS]
general options are:
-appOwner AppOwner (assumed to be current user if
not specified)
-containerId ContainerId (must be specified if node
address is specified)
-nodeAddress NodeAddress in the format nodename:port
(must be specified if container id is
specified)
所以, 要打印出一個給定應用的所有日志, 命令如下
> yarn logs -applicationId
如果只要一個給定容器的所有日志, 可以如下:
> yarn logs -applicationId -containerId -nodeAddress
使用命令行工具的一個顯著優勢是可以使用常規的 shell 工具, 如 grep, sort 等等, 來過濾出我們想要的信息.
管理
日志相關的一般配置項
yarn.nodemanager.log-dirs: 確定當容器還在執行中時, 容器日志在節點上的存儲位置, 默認值是 ${yarn.log.dir}/userlogs.
一個應用的本地化日志目錄是這樣的格式 ${yarn.nodemanager.log-dirs}/application_${appid}
一個獨立的容器的日志文件夾會在上面的文件夾下, 文件夾命名格式是這樣 container_${containerid}
對于 MapReduce 的應用, 每個容器目錄下會包含容器生成的三個文件, stderr, stdin 和 syslog
其他的框架可以自行選擇放置多少個日志文件, YARN 對文件名的文件數量都沒有限制
yarn.log-aggregation-enable: 選擇是否啟用日志聚合. 如果不啟用聚合, NMs 會把日志存儲在節點本地(就像第一代所做的那樣).
日志聚合啟用后的相關配置
yarn.nodemanager.remote-app-log-dir: 這是 NMs 將日志聚合后存放在默認的文件系統(一般就是 HDFS 上的)上的地址. 這個地址不應是本地的文件系統, 否則日志服務器會無法提供聚合后日志的能力. 默認值是 /tmp/logs.
yarn.nodemanager.remote-app-log-dir-suffix: 日志目錄會這樣創建 {yarn.nodemanager.remote-app-log-dir}/${user}/{thisParam}, 默認值是 logs.
yarn.log-aggregation.retain-seconds: 配置多久后聚合后的日志文件被刪除, 配置成 -1 或者一個負值就不會刪除聚合日志.
yarn.log-aggregation.retain-check-interval-seconds: 確定多長時間去檢查一次聚合日志的留存情況以執行日志的刪除. 如果設置為 0 或者負值, 那這個值就會用聚合日志的留存時間的十分之一來自動配置, 默認值是 -1.
yarn.log.server.url: 一旦一個應用結束, NMs 會將網頁訪問自動跳轉到聚合日志的地址, 現在它指向的是 MapReduce 的 JobHistory.
日志聚合未啟用的相關配置
yarn.nodemanager.log.retain-seconds: 保存在本地節點的日志的留存時間, 默認值是 10800.
yarn.nodemanager.log.deletion-threads-count: 確定 NMs 啟動的進程數去刪除本地的日志文件.
其他一些配置指導
遠端的聚合日志的地址的文件夾權限應該是 1777, ${NMUser} 和 ${NMGroup} 是所有者和所有組.
每個應用層次的日志的權限是 770, 但是文件夾所有人是應用的提交者, 文件夾的所有群組是 ${NMGroup}, 這樣安排可以讓應用的提交者能訪問到聚合后的日志, 并且 ${NMGroup} 可以訪問和修改日志.
${NMGroup} 應該是一個有限訪問的群組, 這樣才不會造成訪問泄露.
結論
在這篇文章中, 我們描敘了實現日志聚合的動機以及如何面向用戶和管理者. 日志聚合到目前為止證明是一個非常有用的特性.
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的hadoop yarn 获取日志_在 YARN 中简化用户日志的管理和使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 点击展开 表格_CAD怎么将excel表
- 下一篇: phpmailer 发送邮件空隙太大_W