學習Hadoop生態第一步:Yarn基本原理和資源排程解析!

趙鈺瑩發表於2018-09-05

本文作為《Hadoop從入門到精通》專題第二章的第一小節(第一章:《Hadoop生態系統及執行MapReduce任務介紹》,文章連結:http://blog.itpub.net/31077337/viewspace-2213549/),主要介紹如何從命令列開始使用Yarn以及解決使用資源排程過程中遇到的各種問題。一旦你開始瞭解Yarn,就會發現MapReduce是如何被重寫為YARN應用程式的(MapReduce 2或MRv2),並瞭解MapReduce的體系結構更改。

2.1 Yarn概述

Yarn是Yet Another Resource Negotiator的縮寫。根據Yarn中文官網的顯示,這是一個快速、可靠、安全的依賴管理工具,目前提供的穩定版本為v1.9.4(截至發稿時)。在Hadoop 1.0及更早版本中,我們只能執行MapReduce,這導致圖形處理、迭代計算等任務無法有效執行。在Hadoop 2.0及後續版本中,MapReduce的排程部分被外部化並重新編寫為名為Yarn的新元件,Yarn最大的特點是執行排程與Hadoop上執行的任務型別無關。

圖2.1 新舊Hadoop堆疊展示(Hadoop 1.0和Hadoop 2.0)

2.1.1 為什麼選擇Yarn?

首先,上文已經提到Yarn可在Hadoop上執行除MapReduce以外的工作。MapReduce是一個功能強大的分散式框架和程式設計模型,允許在多節點叢集上執行基於批處理的並行化工作。儘管MapReduce功能強大,但它也有一些缺點,比如不適合實時甚至近實時的資料處理。但是,Yarn可以彌補MapReduce的不足,其核心是分散式排程程式,負責兩項工作:

  • 響應客戶端建立容器的請求——容器本質上可理解為一個程式(也有人理解為服務程式),其中包含允許使用的物理資源。

  • 監視正在執行的容器,並在需要時終止。如果YARN排程程式想要釋放資源以便其他應用程式的容器執行,或者容器使用的資源多於其分配的資源,則可以選擇終止容器。

2.1.2 Yarn元件

Yarn主要由ResourceManager、NodeManager、ApplicationMaster和Container等元件構成。Yarn框架執行主要功能,即在叢集中排程資源(上文提到的容器)。叢集中的應用程式與YARN框架通訊,要求分配特定於應用程式的容器資源,Yarn框架會評估這些請求並嘗試實現。Yarn排程的一個重要部分是監視當前正在執行的容器,一旦容器完成,排程程式就可以釋放容量來安排其他工作。此外,每個容器都有一個協議,指定允許使用的系統資源,並在容器超出邊界的情況下終止容器,以避免惡意影響其他應用程式。

Yarn框架有意設計的儘可能簡單,它不知道或不關心正在執行的應用程式型別,不保留有關叢集上執行內容的任何歷史資訊,這些設計是Yarn可以擴充套件到MapReduce之外的主要原因。

  • ResourceManager——Hadoop叢集具有至少一個ResourceManager(RM)。ResourceManager是Yarn的主程式,其唯一功能是仲裁Hadoop叢集上的資源,響應客戶端建立容器請求,排程程式根據特定的多租戶規則確定何人可以在何時何地建立容器,正如Hadoop 1.0版本,ResourceManager排程程式是可選擇的,這意味著你可以選擇最適合的排程程式,而實際建立的容器被委託給NodeManager。

  • NodeManager——NodeManager是在叢集每個節點上執行的從屬程式。它的主要工作是建立、監視和殺死容器。它為來自ResourceManager和ApplicationMaster的請求提供服務以建立容器,並向ResourceManager報告容器的狀態。ResourceManager使用這些狀態訊息中包含的資料對請求做出排程決策。在非HA模式下,只存在ResourceManager單個例項。

Yarn應用程式具備在Hadoop上執行的特定功能,MapReduce是YARN應用程式的一個示例,Hoya等專案允許多個HBase例項在單個叢集上執行,而Storm-yarn允許Storm在Hadoop叢集內執行。

圖2.2 YARN框架元件及其互動,不顯示特定於應用程式的元件,比如YARN客戶端,ApplicationMaster和容器等。

圖2.3 YARN應用程式典型互動

Yarn應用程式涉及三大元件 - 客戶端,ApplicationMaster(AM)和容器,如圖2.3所示。啟動新的Yarn應用程式需從Yarn客戶端開始,該客戶端與ResourceManager通訊以建立新的Yarn ApplicationMaster例項,此過程Yarn客戶端會讓ResourceManager通知ApplicationMaster物理資源要求。

ApplicationMaster是Yarn應用程式主程式,不執行任何特定於應用程式的工作,因為這些函式被委託給容器。但是,它負責管理特定於應用程式的容器:詢問ResourceManager其建立容器的意圖,然後與NodeManager聯絡以實際執行容器建立。作為此過程的一部分,ApplicationMaster必須根據主機啟動容器,並確定容器的記憶體和CPU要求以指定容器所需資源。

ResourceManager根據資源要求安排工作,它使主機能夠執行混合容器,如圖2.4所示。ApplicationMaster負責應用程式的特定容錯,在容器失敗時從ResourceManager接收狀態訊息,並基於具體事件採取操作(透過要求ResourceManager建立新容器解決)或忽略這些事件。

圖2.4 在單個YARN管理的Hadoop節點上執行的各種容器配置

容器是由NodeManager代表ApplicationMaster建立的特定於應用程式的程式。ApplicationManager本身也是一個由ResourceManager建立的容器。由ApplicationManager建立的容器可以是任意程式——例如,容器程式可以是簡單的Linux命令,例如awk,Python應用程式或可由作業系統啟動的任何程式,這也是YARN強大功能的體現——可以在Hadoop叢集的任何節點啟動和管理任何程式。

2.1.3 Yarn配置

Yarn為各元件帶來了強大的配置,例如UI、遠端程式呼叫(RPC)等。在選擇之前,你需要弄清楚想要訪問的正在執行的Hadoop叢集配置,你可以使用ResourceManager UI檢視相關配置。

該功能的亮點在於UI不僅可以顯示屬性值,還可以顯示檔案來源。如果未在<component> site.xml檔案中定義該值,則將顯示預設值和檔名。該UI的另一功能是可顯示來自多個檔案的配置,包括HDFS、Yarn和MapReduce等檔案,可以從NodeManager UI以相同的方式導航到單個Hadoop從屬節點的配置。在使用由異構節點組成的Hadoop叢集時,這一功能非常有用,因為這些叢集通常會有不同的配置來滿足不同的硬體資源。

圖2.5 叢集配置的YARN ResourceManager UI

2.1.4  Yarn開箱即用

Hadoop 2捆綁了兩個Yarn應用程式——MapReduce 2和DistributedShell。如果你不清楚叢集配置,則有兩個辦法可以解決:

  1. 檢查yarn-site.xml的內容以檢視屬性值。如果不存在自定義值,則預設值將生效。

  2. 使用ResourceManager UI,它提供了有關執行配置的詳細資訊,包括預設值以及是否生效。

如果希望在Hadoop叢集節點上執行Linux命令,可以使用與Hadoop捆綁在一起的DistributedShell示例應用程式。該應用程式也是在Hadoop叢集中並行執行命令的便捷實用程式。

首先在單個容器中發出Linux find命令:

如果叢集一切正常,則執行上述命令將出現以下訊息:

INFO distributedshell.Client: Application completed successfully

你可以在此行之前的命令輸出中看到其他日誌記錄語句,但它們都不包含find命令的實際結果。這是因為DistributedShell ApplicationMaster在單獨的容器中啟動find命令,並且find命令的標準輸出被重定向到容器的日誌輸出目錄。要檢視命令輸出,必須訪問該目錄。如果想訪問容器日誌檔案,可以使用Yarn的UI和命令。Yarn中執行的每個容器都有自己的輸出目錄,其中包括標準輸出等資訊。

圖2.6容器日誌位置和資料保留

在使用Yarn命令列訪問容器日誌時,Yarn附帶了用於訪問應用程式日誌的命令列介面(CLI)。但是,使用CLI的前提是知道應用程式ID。大多數Yarn客戶端將在其輸出和日誌中顯示應用程式ID。例如,之前執行的DistributedShell命令將應用程式ID回顯到標準輸出:

$ hadoop o.a.h.y.a.d.Client ... ... 
INFO impl.YarnClientImpl: 
Submitted application application_1388257115348_0008 to 
ResourceManager at /0.0.0.0:8032 
...

或者,我們可以使用CLI(使用yarn application -list)和ResourceManager UI進行瀏覽並找到應用程式ID。如果應用程式在執行時嘗試使用CLI,則會顯示以下錯誤訊息:

$ yarn logs -applicationId application_1398974791337_0070 
Application has not completed. Logs are only available after 
an application completes

該訊息表明:CLI僅在應用程式完成後才可用。在應用程式執行時,我們需要使用UI來訪問容器日誌。應用程式完成後,如果再次嘗試執行該命令,則可能會看到以下輸出:

$ yarn logs -applicationId application_1400286711208_0001 
Logs not available at /tmp/.../application_1400286711208_0001 
Log aggregation has not completed or is not enabled.

基本上,Yarn CLI僅在應用程式已完成且啟用日誌聚合時才有效。如果啟用日誌聚合,CLI將提供應用程式中所有容器日誌,如下所示:

$ yarn logs -applicationId application_1400287920505_0002 
client.RMProxy: Connecting to ResourceManager at /0.0.0.0:8032
Container: container_1388248867335_0003_01_000002 
on localhost.localdomain_57276 
============================================================== 
LogType: stderr 
LogLength: 0 
Log Contents:
LogType: stdout
LogLength: 1355 
Log Contents: 
/tmp default_container_executor.sh 
/launch_container.sh 
/.launch_container.sh.crc 
/.default_container_executor.sh.crc 
/.container_tokens.crc 
/AppMaster.jar 
/container_tokens
Container: container_1400287920505_0002_01_000001 
on localhost.localdomain_57276 
================================================= 
LogType: AppMaster.stderr 
LogLength: 17170 
Log Contents: distributedshell.ApplicationMaster: Initializing ApplicationMaster 
...
LogType: AppMaster.stdout 
LogLength: 8458 
Log Contents: 
System env: key=TERM, val=xterm-256color 
...

上述輸出顯示了執行DistributedShell示例的日誌內容。輸出中有兩個容器——用於執行的find命令和用於ApplicationMaster的命令。使用Yarn UI訪問日誌時,Yarn透過ResourceManager UI提供對ApplicationMaster日誌的訪問。在偽分散式設定上,將瀏覽器指向http:// localhost:8088 / cluster。如果正在使用多節點Hadoop叢集,請將瀏覽器指向http://$yarn.resourcemanager.webapp.address/cluster,如圖2.7所示。

不幸的是,ResourceManager為了保證輕量級,不會跟蹤應用程式的容器ID。因此,ResourceManager UI僅提供訪問應用程式ApplicationMaster日誌的方法。一個典型的例子是DistributedShell應用程式,它不提供ApplicationMaster UI或跟蹤啟動的容器。

圖2.7 顯示ApplicationMaster容器的YARN ResourceManager UI

幸運的是,MapReduce Yarn應用程式提供了一個ApplicationMaster UI,你可以使用它來訪問容器(map和reduce任務)日誌,並在MapReduce作業完成後訪問日誌的JobHistory UI。當執行MapReduce作業時,ResourceManager UI會提供MapReduce ApplicationMaster UI的連結。

圖2.8 訪問正在執行作業的MapReduce UI

Yarn應用程式提供了一些方法來識別容器ID及其執行的主機,則可以使用NodeManager UI訪問容器日誌,也可以使用shell ssh到執行容器的從屬節點。用於訪問容器日誌的NodeManager URL是http://<nodemanagerhost>:8042/node/containerlogs/<container-id>/<username>。或者,你可以ssh到NodeManager主機並訪問$yarn .nodemanager.log -dirs/<application-id>/<container-id>中的容器日誌目錄。實際上,最佳建議是啟用日誌聚合,這將允許使用CLI,HDFS和UI(例如MapReduce ApplicationMaster和JobHistory)來訪問應用程式日誌。

日誌聚合是Hadoop 1中缺少的功能,但Hadoop 2具有此功能,你可以透過多種方式訪問聚合日誌檔案。如果啟用日誌聚合功能,它會在Yarn應用程式完成後將容器日誌檔案複製到Hadoop檔案系統(如HDFS)中。預設情況下,此行為已禁用,需要將yarn.log-aggregation-enable設定為true以啟用此功能。

使用CLI訪問日誌檔案需要使用應用程式ID,可以使用命令列獲取所有日誌並將其寫入控制檯:

$ yarn logs -applicationId application_1388248867335_0003 Enabling log aggregation

如果yarn logs命令產生以下輸出,那麼很可能沒有啟用Yarn日誌聚合:

Log aggregation has not completed or is not enabled.

圖2.9 從本地檔案系統到HDFS的日誌檔案聚合

這將轉儲Yarn應用程式的所有容器日誌,每個容器輸出都用一個標題表示容器ID,然後是容器輸出目錄中每個檔案的詳細資訊。例如,如果執行了執行ls -l的DistributedShell命令,那麼yarn logs命令的輸出將產生如下所示的內容:

Container: container_1388248867335_0003_01_000002 on localhost ============================================================== 
LogType: stderr 
LogLength: 0 
Log Contents:
LogType: stdout
LogLength: 268 
Log Contents: 
total 32 -rw-r--r-- 1 aholmes 12:29 container_tokens
-rwx------ 1 aholmes 12:29 default_container_executor.sh 
-rwx------ 1 aholmes launch_container.sh 
drwx--x--- 2 aholmes tmp
Container: container_1388248867335_0003_01_000001 on localhost ============================================================== 
LogType: AppMaster.stderr 
(the remainder of the ApplicationMaster logs removed for brevity)

如上,stdout檔案包含ls程式當前目錄的列表,該目錄是特定於容器的工作目錄。同樣,JobHistory UI也可以訪問聚合日誌。如果啟用了日誌聚合,則需要更新yarn-site.xml並將yarn.log.server.url設定為指向作業歷史記錄的伺服器,以便ResourceManager UI呈現日誌。

訪問HDFS中的日誌檔案,預設情況下將進入HDFS中的以下目錄:

/tmp/logs/${user}/logs/application_<appid>

我們可以透過yarn.nodemanager.remote-app-log-dir屬性配置目錄字首。類似地,使用者名稱之後的路徑名(前一個示例中的“logs”,這是預設值)可以透過yarn.nodemanager.remote-app-log-dir-suffix自定義。本地檔案系統和HDFS中的日誌檔案之間的差異如前所述,每個容器在本地檔案系統中產生兩個日誌檔案:一個用於標準輸出,另一個用於標準錯誤。作為聚合過程的一部分,給定節點的所有檔案將連線在一起,形成特定於節點的日誌。例如,如果有五個容器在三個節點上執行,那麼最終將在HDFS中使用三個日誌檔案。壓縮預設情況下禁用聚合日誌壓縮,但你可以透過將yarn.nodemanager.log-aggregation.compression-type的值設定為lzo或gzip來啟用,具體取決於壓縮要求。從Hadoop 2.2開始,這是唯一支援的兩種壓縮編解碼器。

當關閉日誌聚合時,本地主機上的容器日誌檔案將保留為yarn.nodemanager.log.retain-seconds seconds,預設值為10,800(3小時)。開啟日誌聚合時,將忽略yarn.nodemanager.log.retain-seconds可配置,而是將本地容器日誌檔案複製到HDFS後立即刪除。如果想將它們保留在本地檔案系統上,那麼所有這些都不會丟失 - 只需將yarn.nodemanager.delete.debug-delay-sec設定為想保留檔案的值即可。請注意,這不僅適用於日誌檔案,還適用於與容器關聯的所有其他後設資料(例如JAR檔案)。HDFS中檔案的資料保留是透過設定不同的yarn.log-aggregation.retain-seconds來配置的。

替代解決方案

如果你有日誌挖掘或者視覺化方面的需求,你也可以考慮其他替代解決方案,例如Hunk,支援聚合來自Hadoop 1和Hadoop 2的日誌;提供一流的查詢、視覺化和監控功能,就像普通的Splunk一樣。如果要擁有日誌管理過程,還可以使用Logstash、ElasticSearch和Kibana等工具設定查詢和視覺化管道。

2.1.5 Yarn面臨的挑戰

目前,我們使用Yarn時需要注意一些問題:Yarn不適用於長時間執行的程式,這受到了來自Impala和Tez等專案的挑戰,這些專案受益於此類功能。目前,該功能正在引入YARN,國內不少企業也在這方面進行了相應的定製化;編寫Yarn應用程式非常複雜,因為需要實現容器管理和容錯,這可能需要一些複雜的ApplicationMaster和容器狀態管理,以便在失敗時可回滾至前一狀態;原生Yarn不支援組合排程,即並行快速啟動大量容器的能力,這是Impala和Hamster(OpenMPI)等專案的一大優勢。到目前為止,本節一直專注於Yarn的核心功能,下一節將為大家介紹MapReduce如何作為YARN應用程式工作等內容。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31077337/viewspace-2213602/,如需轉載,請註明出處,否則將追究法律責任。

相關文章