最近一直在學習hadoop的一些原理和優化,然後也做了一些實踐,也有沒有去做實踐的,反正個人觀點都記錄下來
一、yarn的介紹
YARN的基本結構由一個ResourceManager與多個NodeManager組成。ResourceManager負責對NodeManager所持有的資源進行統一管理和排程。當在處理一個作業時ResourceManager會在NodeManager所在節點建立一全權負責單個作業執行和監控的程式ApplicationMaster。
1、ResouceManager(簡稱RM)
資源管理器負責整個叢集資源的排程,該元件由兩部分構成:排程器(Scheduler)和ApplicationsManager。排程器會根據特定排程器實現排程演算法,結合作業所在的佇列資源容量,將資源按排程演算法分配給每個任務。分配的資源將用容器(container)形式提供,容器是一個相對封閉獨立的環境,已經將CPU、記憶體及任務執行所需環境條件封裝在一起。通過容器可以很好地限定每個任務使用的資源量。YARN排程器目前在生產環境中被用得較多的有兩種:能力排程器(Capacity Scheduler)和公平排程器(Fair Scheduler)(FIFO一般都不使用)。
2、ApplicationMaster(簡稱AM)
每個提交到叢集的作業(job)都會有一個與之對應的AM 來管理。它負責進行資料切分,併為當前應用程式向RM 去申請資源,當申請到資源時會和NodeManager 通訊,啟動容器並執行相應的任務。此外,AM還負責監控任務(task)的狀態和執行的進度。
3、NodeManage(簡稱NM)
NodeManager負責管理叢集中單個節點的資源和任務,每個節點對應一個NodeManager, NodeManager負責接收ApplicationMaster的請求啟動容器,監控容器的執行狀態,並監控當前節點狀態及當前節點的資源使用情況和容器的執行情況,並定時回報給ResourceManager
更具體點的知識可以參考hadoop之yarn詳解(基礎架構篇)、hadoop之yarn詳解(框架進階篇)和hadoop之yarn詳解(命令篇)這幾篇文章
二、yarn的優化
丟個官網:https://hadoop.apache.org/docs/stable/hadoop-yarn/hadoop-yarn-common/yarn-default.xml
這裡不說排程器的配置,一般都是選用能力排程器(Capacity Scheduler)和公平排程器(Fair Scheduler),這些一般都是根據公司的具體情況進行配置,比如根據使用者配置資源比例,或者更具時間點的不同配置,畢竟有時候離線計算在某些時候壓力會比較大,可以根據公司的具體情況,對具體的一些時間段進行相應的調整,防止叢集壓力過大,造成叢集不健康。
2.1、資源配置
在YARN中可供分配和管理的資源有記憶體和CPU資源,在Hadoop 3.0中將GPU、FPGA資源也納入可管理的資源中。
既然yarn是用來管理資源的,所以資源的來源還是來源於伺服器的cpu和記憶體。所以也就是我們配置伺服器的多少資源作為yarn的資源。這裡有兩種配置,一種是自己更具伺服器的資源,自己判斷預留給伺服器多少資源提供給其他服務,其他配置給yarn作為資源,還有一種就是讓yarn去掃描伺服器的資源,按照比例進行配置(這個理論上可行,沒有實踐)
這裡再說一句,優化這個東西呢其他在叢集沒有出現瓶頸的時候就不要去優化,一個是看不出效果,還有就是浪費時間,反正資源夠用,沒啥好優化的,優化的目的就是在有限的資源下,保證叢集的穩定,又能挺高資源的利用率和提高叢集的併發能力。
首先我們說第一種:手動配置固定的資源給yarn
yarn.nodemanager.resource.cpu-vcores,預設值為-1。預設表示叢集中每個節點可被分配的虛擬CPU個數為8。為什麼這裡不是物理CPU個數?因為考慮一個叢集中所有的機器配置不可能一樣,即使同樣是16核心的CPU效能也會有所差異,所以YARN在物理CPU和使用者之間加了一層虛擬CPU,一個物理CPU可以被劃分成多個虛擬的CPU。這裡確實可以配置超過物理cpu的個數,確實能夠提高併發,但是嘗試了一把,這樣子伺服器的負載就很大了,基本上是處理不過來,而且這樣配置沒有個伺服器留有空餘的cpu去執行其他的任務或者其他的叢集。因為是生產環境,也沒敢去做壓測,檢測到伺服器的負載都是cpu核數的十倍了,所以負載太大,不太敢太激進,所以最終配置是比物理cup核數少那麼幾個,預留幾個cpu給伺服器或者其他服務使用。
yarn.nodemanager.resource.memory-mb,預設值為-1。當該值為-1時,預設表示叢集中每個節點可被分配的實體記憶體是8GB。這個一般配置是給伺服器預留20%的記憶體即可。
接下來說說第二種:讓yarn自動探測伺服器的資源,然後預留一定比例給伺服器,然後就可以把vcore調的大一些,這樣既能提高cpu的使用率,有能保證給伺服器留有一定的cpu
首先yarn.nodemanager.resource.cpu-vcores和yarn.nodemanager.resource.memory-mb都要採用預設值-1,這樣如下的配置才會生效:
yarn.nodemanager.resource.detect-hardware-capabilities 配置為true,表示可以讓yarn自動探測伺服器的資源,比如cpu和記憶體等
然後我們就配置可以留給伺服器的記憶體和可以使用物理cpu的比例:
yarn.nodemanager.resource.system-reserved-memory-mb:YARN保留的實體記憶體,給非YARN任務使用,該值一般不生效,只有當yarn.nodemanager.resource.detect-hardware-capabilities為true的狀態才會啟用,會根據系統的情況自動計算
yarn.nodemanager.resource.percentage-physical-cpu-limit:預設是100,表示100%使用,這裡我們比如可以配置80%,表示預留給伺服器或者其他應用20%的cpu
yarn.nodemanager.resource.pcores-vcores-multiplier:預設為1,表示一個物理cpu當做一個vcore使用,如果我們已經預留給了伺服器cpu的話,那我們這裡可以調整問題2或者3,這樣一個物理cpu可以當做2個或者3個vcore使用,畢竟每個map和reduce作業都要配置cpu,但是有些map和reduce作業又不是計算型作業,所以這樣就可以更合理的利用資源。類似把蛋糕切小塊,少需的拿一塊,多需求的多拿幾塊,這樣提高了cpu的利用率和提高了叢集的併發能力。(這麼配置的前提是叢集的瓶頸在於cpu不夠使用)
yarn.nodemanager.vmem-pmem-ratio,預設值為2.1。該值為可使用的虛擬記憶體除以實體記憶體,即YARN 中任務的單位實體記憶體相對應可使用的虛擬記憶體。例如,任務每分配1MB的實體記憶體,虛擬記憶體最大可使用2.1MB,如果叢集缺記憶體,可以增大該值。
注意:如果叢集的資源很充足,就不要把一個物理cpu當2個或者3個使用,也不要吧虛擬記憶體比例調大,資源夠用就是不用優化,優化只是在資源不夠的情況進行的。
如上我們配置yarn叢集的資源,cpu和記憶體,但是在作業的執行的過中是以container為單位的,現在我們來配置container的資源。
yarn.scheduler.minimum-allocation-mb:預設值1024MB,是每個容器請求被分配的最小記憶體。如果容器請求的記憶體資源小於該值,會以1024MB 進行分配;如果NodeManager可被分配的記憶體小於該值,則該NodeManager將會被ResouceManager給關閉。
yarn.scheduler.maximum-allocation-mb:預設值8096MB,是每個容器請求被分配的最大記憶體。如果容器請求的資源超過該值,程式會丟擲InvalidResourceRequest Exception的異常。
yarn.scheduler.minimum-allocation-vcores:預設值1,是每個容器請求被分配的最少虛擬CPU 個數,低於此值的請求將被設定為此屬性的值。此外,配置為虛擬核心少於此值的NodeManager將被ResouceManager關閉。
yarn.scheduler.maximum-allocation-vcores:預設值4,是每個容器請求被分配的最少虛擬CPU個數,高於此值的請求將丟擲InvalidResourceRequestException的異常。如果開發者所提交的作業需要處理的資料量較大,需要關注上面配置項的配置
2.2、執行緒配置
資源配置固然重要,但是影響yarn效能的不單單只是資源,還有各個元件之間的配合,執行緒的數量直接影響到併發的能力,當然也不能配置的太高,這樣會給叢集造成不小的壓力,所以要根據自己叢集的狀態進行合理的配置。
yarn.resourcemanager.client.thread-count:預設50,用於處理應用程式管理器請求的執行緒數
yarn.resourcemanager.amlauncher.thread-count:預設50,用於啟動/清理AM的執行緒數
yarn.resourcemanager.scheduler.client.thread-count:預設50,處理來自ApplicationMaster的RPC請求的Handler數目,比較重要
yarn.resourcemanager.resource-tracker.client.thread-count:預設50,處理來自NodeManager的RPC請求的Handler數目,比較重要
yarn.resourcemanager.admin.client.thread-count:預設1,用於處理RM管理介面的執行緒數。
yarn.nodemanager.container-manager.thread-count:預設20,container 管理器使用的執行緒數。
yarn.nodemanager.collector-service.thread-count:預設5,收集器服務使用的執行緒數
yarn.nodemanager.delete.thread-count:預設4,清理使用的執行緒數。
yarn.nodemanager.localizer.client.thread-count:預設5,處理本地化請求的執行緒數。
yarn.nodemanager.localizer.fetch.thread-count:預設4,用於本地化獲取的執行緒數
yarn.nodemanager.log.deletion-threads-count:預設4,在NM日誌清理中使用的執行緒數。在禁用日誌聚合時使用
yarn.timeline-service.handler-thread-count:用於服務客戶端RPC請求的處理程式執行緒計數。
2.3、log日誌和檔案目錄配置
yarn.nodemanager.log-dirs:日誌存放地址(建議配置多個目錄),預設值:${yarn.log.dir}/userlogs
yarn.nodemanager.local-dirs:中間結果存放位置,建議配置多個目錄,分攤磁碟IO負載,預設值:${hadoop.tmp.dir}/nm-local-dir
yarn.log-aggregation-enable:預設false,是否啟用日誌聚合
yarn.log-aggregation.retain-seconds:聚合日誌的保留時長,設定到3-7天即可,預設-1
yarn.nodemanager.remote-app-log-dir:預設/tmp/logs,本地聚合在hdfs上的日誌目錄
yarn.nodemanager.remote-app-log-dir-suffix:{yarn.nodemanager.remote-app-log-dir}/${user}/{thisParam}用於存放聚合後的日誌
yarn.nodemanager.recovery.dir:預設${hadoop.tmp.dir}/yarn-nm-recovery,本地檔案系統目錄,當啟用恢復時,nodemanager將在其中儲存狀態。只有當yarn.nodemanager.recovery.enabled為true的情況下才有用,該值預設false
yarn.resourcemanager.recovery.enabled:預設fasle,當RM啟用高可用的時候預設啟用,但是必須配置yarn.resourcemanager.store.class,該值預設為org.apache.hadoop.yarn.server.resourcemanager.recovery.FileSystemRMStateStore,最好配置配org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore