最近一直在學習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
