集群namenode與journalNode通訊超時導致namenode掛掉問題分析


背景:

  因業務要求進行了一次業務數據的全量采集,采集過程中集群namenode與journalNode通訊超時導致namenode掛掉。如下圖

	
Error: starting log segment 11771414 failed for required journal (JournalAndStream(mgr=QJM to [192.168.0.21:8485, 192.168.0.22:8485, 192.168.0.23:8485], stream=null))
java.io.IOException: Timed out waiting 20000ms for a quorum of nodes to respond.

 

問題分析:

  這種問題通常是Full GC導致的問題, namenode這個時間點進行了一次時間比較長的 full gc,導致寫 journalnode 超時(默認是20s), namenode進程退出。

結合集群namenode jvm參數

-XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=70 -XX:+CMSParallelRemarkEnabled

 

為什么Namenode JVM一般選用CMS,可以參考:NameNode Garbage Collection Configuration: Best Practices and Rationale 

可能是以下原因:

 1. Perm(jdk1.8后是元數據空間)空間不足; 2. CMS GC時出現promotion failed和concurrent mode failure(concurrent mode failure發生的原因一般是CMS正在進行,但是由於老年代空間不足,需要盡快回收老年代里面的不再被使用的對象,這時停止所有的線程,同時終止CMS,直接進行Serial Old GC); 3. 主動觸發Full GC(執行jmap -histo:live [pid])來避免碎片問題。

再結合如下監控及heap情況:

 

 

 

 

 

 

 

 

  我們可以看到,E伊甸園區使用比例 和M元數據區使用比例都很高,O老年代使用比例很低,且元數據區默認只有20M,所以判斷是元數據空間不足導致的 full gc。

另外新生代和老生代比例為1:4,容易造成大對象在做gc時,大對象直接進入老生代,造成老生代內存快速增長,full gc更加頻繁。

調優方向:

  1.提升堆內存大小,降低Old區使用比例,修改新生代和老生代比例為1:3,規避壓縮式GC的STW風險

  2.調節journalnode 的寫入超時時間  dfs.qjournal.write-txns.timeout.ms = 90s

  3.設置Java8的永生代初始值MetaspaceSize為較大的值128m,避免MetaSpace用滿需要增長而引發的Full GC,-XX:MetaspaceSize=128m

-XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=70 -XX:+UseCMSInitiatingOccupancyOnly -XX:+CMSParallelRemarkEnabled -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9004 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -XX:NewRatio=3  -XX:MetaspaceSize=128m -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps 

  

 

補充:

jdk8的JVM 內存划分

  GC 主要工作在 Heap 區和 MetaSpace 區(上圖藍色部分)

什么是Matespace,它使用的是什么內存,Metadata GC Threshold的含義是什么

Mateapce:元空間,是JDK1.8中用來代替Perm的。它使用的是本地堆內存(native heap),所以Matespace並不受JVM可使用內存大小限制。可以使用” -XX:MaxMetaspaceSize “參數指定Matespace最大可使用的空間,-XX:MaxMetaspaceSize默認是沒有限制的。

Matespace主要由Class Metaspace和Non-Class MetaSpace組成。

  • Class Matespace:主要包括byte code、class等信息。如果開啟了壓縮指針 -XX:+UseCompressedClassPointers (默認開啟),這一塊的數據會被放到”Compressed Class Space” 中,可以通過 -XX:CompressedClassSpaceSize 參數來控制大小(默認1G,最大3G)。
  • Non-Class Metaspace:專門來存class相關的其他的內容,比如method,constantPool等

Metadata GC Threshold 顧名思義,就是 Metaspace 的空間大小超過了這個閾值,嘗試FullGC收集可以卸載的類加載器來復用空間,如果空間仍然不足,則嘗試對Metaspace進行擴容。如此循環,直到達到 MaxMetaspaceSize 指定的上限。

如果頻繁發生原因是 Metadata GC Threshold 的FullGC ,那么需要做如下排查:

  1. MaxMetaspaceSize 設定的是否過小
  2. 使用的類加載,是否存在內存泄漏的情況

類加載器負責分配Metaspace的空間,當一個類加載器被卸載后,且發生GC時,這個類加載器加載的類所占用的Metaspace空間,將會被釋放。釋放的Metaspace空間並不會歸還給系統內存,而是會被 JVM 保留下來。

 

 參考文章:

  https://tech.meituan.com/2017/12/29/jvm-optimize.html

  https://ericsahit.github.io/2016/12/25/Namenode%E5%86%85%E5%AD%98%E5%88%86%E6%9E%90/

  https://tech.meituan.com/2020/11/12/java-9-cms-gc.html

  https://russxia.com/2020/03/06/%E7%94%B1MateSpace%E7%A9%BA%E9%97%B4%E4%B8%8D%E8%B6%B3%E5%BC%95%E5%8F%91%E7%9A%84FullGC/

  https://toutiao.io/posts/155svp/preview

  https://cache.one/read/3461413

  http://blog.itpub.net/30089851/viewspace-2122226/

  https://community.cloudera.com/t5/Support-Questions/Name-Node-instability-flush-failed-for-required-journal/td-p/128161

 

 

   


免責聲明!

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



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