一、問題再現
由於項目需要,採購電信天翼雲,由於是新搭建的集羣,在yarn上跑Spark任務時,每個幾個小時或者半天出現節點丟失(Lost Nodes),訪問http://cloudera01:8088,如下圖,可以看到2個節點和集羣失去了聯繫
二、問題排查
1、登錄cm管理界面
首先登錄cm管理界面,去查看yarn的運行狀況,看到2個NodeManager運行不良,點擊不良鏈接
2、點擊NodeManager查看
3、NodeManager與ResourceManager失聯
這就去查看NodeManager的日誌進一步查找問題,去查看cloudera03這臺機日誌
4、查看NodeManager日誌
其日誌默認路徑在/var/log/hadoop-yarn下,less hadoop-cmf-yarn-NODEMANAGER-cloudera03.log.out
先看到container_1554798900283_0001_01_000008 與內存使用情況的日誌
Memory usage of ProcessTree 11630 for container-id container_1554798900283_0001_01_000025: 695.6 MB of 2.5 GB physical memory used; 4.0 GB of 5.3 GB virtual memory used
之後該container_1554798900283_0001_01_000008 狀態從RUNNING到KILLING
Container container_1554798900283_0001_01_000008 transitioned from RUNNING to KILLING
接着這個container_1554798900283_0001_01_000008 退出
Exit code from container container_1554798900283_0001_01_000008 is : 143
最終完成殺死,清理container相關信息,這大概就是一個container被殺死的過程
Container container_1554798900283_0001_01_000008 transitioned from KILLING to CONTAINER_CLEANEDUP_AFTER_KILL
根據以上情況,可以初步斷定是由於NodeManager分配給container虛擬內存分配不足引起的自殺,從而緩解內存不足狀況,保證其它container運行。
三、嘗試解決方案
1、問題分析
相關屬性說明
yarn.scheduler.minimum-allocation-mb | 1024 | 分配給AM單個容器可申請的最小內存,默認1024M | RM屬性 |
yarn.scheduler.maximum-allocation-mb | 8192 |
分配給AM單個容器可申請的最大內存,默認8192M, 不能超過NM節點最大可用內存 |
RM屬性 |
yarn.nodemanager.resource.memory-mb | 8192 | NM節點最大可用內存,默認8192M | NM屬性 |
yarn.nodemanager.vmem-check-enabled | true | 是否檢查虛擬內存,默認true檢查 | NM屬性 |
yarn.nodemanager.vmem-pmem-ratio | 2.1 | 虛擬內存率,默認值是2.1 | NM屬性 |
分析:Memory usage of ProcessTree 11630 for container-id container_1554798900283_0001_01_000025: 695.6 MB of 2.5 GB physical memory used; 4.0 GB of 5.3 GB virtual memory use
默認物理內存是1GB,動態申請到了2.5GB,其中使用了695.6 MB。物理內存╳2.1=虛擬內存,2.5GB╳2.1≈5.3GB ,5.3GB虛擬內存中使用了4.0GB,當虛擬內存不夠時候,NM的container就會自殺,這裏雖然沒耗盡,但也自殺了。所以有兩個解決方案,或調整yarn.nodemanager.vmem-pmem-ratio值大點,或yarn.nodemanager.vmem-check-enabled=false,關閉虛擬內存檢查
2、在cloudera-manager控制檯界面調整
登錄cloudera-manager管理系統http://192.xxx.xxx.71:7180,進入YARN (MR2 Included)配置界面,完成後保存
因爲調整需要重啓服務,這裏爲了防止以後不夠用,順便把RM的yarn.scheduler.maximum-allocation-mb和NM的yarn.scheduler.maximum-allocation-mb調大點,避免頻繁修改參數重啓服務影響生產。
NM的yarn.scheduler.maximum-allocation-mb,默認約8.05G,我改爲以G爲單位,設爲12G,保存修改
yarn.scheduler.maximum-allocation-mb調大點,也改爲以G爲單位,這裏設置爲12G,保存修改。
完成之後重新啓動YARN (MR2 Included)服務,再提交我們的spark任務,觀察2天,仍然有此問題出現,看來以上方案不能解決問題。
四、最終有效解決方案
這次可以看到GC持續時間未知提示,看到這句話可以猜到可能是GC一直卡在那兒了
查看Nodemanager日誌,仍然報同樣的問題,看來並不是虛擬內存不足導致container被殺的問題
接着往下看,看到Full compaction cycle completed in 11 msec ,觸發了Full gc,下邊還有這樣的日誌,Full GC時間太長了,持續11秒,而且也頻繁了,這肯定不正常。
於是去查看NodeManager啓動參數 $ jps -v
看到-Xmx1000m,後邊還有-Xms52428800 -Xmx5242880。可以看到最大堆內存設置了兩個,後邊50m覆蓋了前邊的1000m,最終-Xms、 -Xmx都是50m,$ jmap -heap pid 查看NodeManager最大堆內存也是50m(當時忘記截圖了),太小了肯定不行,必然導致頻繁的full gc,停頓時間長。
於是乎去平臺修改Nodemanager的JVM參數,到ClouderaManager yarn服務, 找到非默認參數,看到NM、RM都被改成了50m,點擊恢復過來。
或者直接在高級選項中,新增-Xms1073741824 -Xmx1073741824, 就會覆蓋CDH自動設置的50m
保存重啓yarn服務,又觀察幾天,沒有出現NodeManager堆內存不足而導致container被殺的情況
回想一下,關於這個Nodemanager的JVM參數-Xms -Xmx,爲什麼會設置50m呢
抱着追根問底的好奇心,去查看了其他環境下的參數設置。測試環境(內存16G)有的節點分配的是1024m,有的是730m,還有的是668m。而另一個集羣生產環境(內存64G),看來幾個節點,都是1024m,且幾個地方用的cdh 5.12.2版本都一樣,而此處(內存32G)被設置了50m。初步判斷cdh是根據可用內存自動分配的,可能是啓動NodeManager時某些機器內存不足導致堆內存分配了50m,一方面堆內存不足container自殺,另一方面不斷full gc來回收空間,停頓時間長,到最終失聯。