Hadoop 服務SYS CPU過高導致宕機問題


   最近某hadoop集群多次出現機器宕機,現象為瞬間機器的sys cpu增長至100%,機器無法登錄。只能硬件重啟,ganglia cpu信息如下:

首先懷疑有用戶啟動了比較奇葩的job,導致不合理的系統調用出現的問題。隨后加了ps及pidstat信息收集job信息(公共集群蛋疼的地方),然后出現問題的時候,各類腳本已經無法工作,

一直沒有抓到現場。

終於在某一次看到一台機器sys 瞬間增長,且機器還能登錄。立馬查看現場,發現竟然元凶是datanode:datanode一個進程占用cpu 1600%,sys cpu占用超過40%

 

Datanode的進程棧信息,大量dataxceiver線程block,並且都是在發送數據塊過程中 getVisibleLength操作:

"DataXceiver for client /10.16.136.65:34464 [sending block blk_341818443393496218_612191861]" daemon prio=10 tid=0x00007f7500a33000 nid=0x4135 waiting for monitor entry [0x00007f74ec5a5000]

   java.lang.Thread.State: BLOCKED (on object monitor)

        at org.apache.hadoop.hdfs.server.datanode.FSDataset.getVisibleLength(FSDataset.java:1116)

        - waiting to lock <0x000000051237f860> (a org.apache.hadoop.hdfs.server.datanode.FSDataset)

        at org.apache.hadoop.hdfs.server.datanode.BlockSender.<init>(BlockSender.java:118)

        at org.apache.hadoop.hdfs.server.datanode.DataXceiver.readBlock(DataXceiver.java:271)

        at org.apache.hadoop.hdfs.server.datanode.DataXceiver.run(DataXceiver.java:176)

   Locjava:118)

        at org.apache.hadoop.hdfs.server.datanode.DataXceiver.writeBlock(DataXceiver.java:394)

        at org.apache.hadoop.hdfs.server.datanode.DataXceiver.run(DataXceiver.java:184)

   Locked ownable synchronizers:

        - None

從這里看,似乎並沒有什么問題,只是大量線程堵塞在文件的操作上。問題依然沒有進展。

這樣大概持續了一段時間,發現出問題的機器有一個共同點,dmesg信息有大量此類log:

shrink_slab: xfs_buftarg_shrink+0x0/0x160 [xfs] negative objects to delete nr=-6

參考:http://www.ibm.com/developerworks/cn/linux/l-cn-pagerecycle/

函數 shrink_slab()

函數 shrink_slab() 是用來回收磁盤緩存所占用的頁面的。Linux 操作系統並不清楚這類頁面是如何使用的,所以如果希望操作系統回收磁盤緩存所占用的頁面,那么必須要向操作系統內核注冊 shrinker 函數,shrinker 函數會在內存較少的時候主動釋放一些該磁盤緩存占用的空間。函數 shrink_slab() 會遍歷 shrinker 鏈表,從而對所有注冊了 shrinker 函數的磁盤緩存進行處理。

從實現上來看,shrinker 函數和 slab 分配器並沒有固定的聯系,只是當前主要是 slab 緩存使用 shrinker 函數最多。

也就是這些dmesg信息應該是在內存回收磁盤緩存頁面階段出現的。

而看到某數字公司的一篇文章,同為hadoop服務sys cpu過高:

http://blogs.360.cn/360xitong/2013/03/26/hadoop%E9%9B%86%E7%BE%A4system-cpu%E6%B6%88%E8%80%97%E8%BF%87%E9%AB%98%E9%97%AE%E9%A2%98%E5%88%86%E6%9E%90-by-%E6%9D%82%E8%B4%A7%E5%BA%97%E5%BA%97%E9%95%BF/

作者追查的原因為compact_zone,同樣為內存管理。

並且IBM提到了CFS對java性能的影響:

http://www-01.ibm.com/support/docview.wss?uid=swg21372909

處理的辦法是/proc/sys/kernel/sched_compat_yield置為1,而RHEL6上面貌似這個參數已經不生效。

綜上,可以基本推斷出,這個問題跟RHEL6的內存管理密切相關。我們對RHEL6內存管理相關的的參數調整:

(1)   關閉大頁內存:echo never > /sys/kernel/mm/redhat_transparent_hugepage/defrag && echo never >  /sys/kernel/mm/redhat_transparent_hugepage/enabled

(2)   Vfs_cache置為零:/sbin/sysctl vm.vfs_cache_pressure=0

於是從內存管理入手,首先調整了vm.vfs_cache_pressure,將其改回默認值100,觀察一天,果然dmesg里shrink_slab相關信息消失,並且改過的機器沒有出現過宕機。因此問題定位為

內存cache回收。此參數在RHEL5上運行時一直置為0並運行平穩,RHEL6真是坑人啊。。

我們將vm.vfs_cache_pressure置為0,目的是讓系統不要主動回收cache,以使hadoop進程有足夠多的內存cache。對datanode和task性能有比較好的提升。如果恢復回默認值,性能會有很大的下降,用戶又不干了。於是經過測試,將vm.vfs_cache_pressure調整為5--10,這樣系統會傾向於主動回收一部分cache,同時hadoop也有足夠的cache供進程用。也再沒有出現sys cpu升高導致的宕機問題。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM