1. 程式人生 > >大資料叢集JVM調優&記憶體管理

大資料叢集JVM調優&記憶體管理

大資料叢集的工作,很大一部分精力花在了調整叢集的jvm引數上面。由於現在的開源大資料產品無論是HadoopHbase、yarn還是Spark等等,都運行於jvm環境中,因此而產生的垃圾收集問題是影響叢集可用性的是工作中的重點。

本文首先歸納一些常見的因jvm垃圾收集導致的常見叢集問題,這些歸納來自於平時工作的總結,歡迎和大家一起交流:

1、Namenode的堆記憶體配置過小導致頻繁產生full GC導致namenode宕機,在hadoop中,資料的寫入&讀取經由namenode,所以namenode的jvm記憶體需要足夠多,尤其是在出現大量資料流動的場景中。

      此外Hadoop叢集中的檔案數越多,Namenode的記憶體壓力越大,可以通過archive歸檔命令定期合併一些目錄以減少namenode的壓力。hadoop不適於儲存海量小檔案的原因也在於此。

2、DataNode的記憶體可以相應調小。

3、NodeManager充當shuffle任務的server端,記憶體應該調大,否則會出現任務連線錯誤,日誌Too Many fetch failures.Failing the attempt。

4、ResourceManager垃圾回收時間過長導致與zk的連線超時,出現active RM的頻繁切換,此過程中會導致一些MR任務失敗。

5、HRegionServer的堆記憶體配置過少,hbase的讀寫直接與RegionServer交換,Regionserver中預留了資料讀寫的快取,入Memstore&blockCache等等,因此留給RegionServer的堆記憶體應足夠其快取

資料庫中的資料。

JVM的引數調整視應用環境、叢集環境、業務背景的不同而不同,因此,很難統一出一個適用的標準,更多的是手藝活。下文,我們會列出各個jvm引數的含義,力求能夠讓大家一目瞭然所有引數的意義。至於具體的引數應該如何配置,視不同的需求而不同。

-Xmx:JVM最大允許分配的堆記憶體;

-Xms:JVM初始分配的堆記憶體(一般等於-Xmx);

-Xmn:JVM堆中年輕代的大小;

-Xss:每個執行緒都需要一定的棧空間,-Xss定義棧空間的大小;

-XX:StackYellowPages:執行緒棧尾部會預留兩塊受保護的記憶體區域,分別是yellow page和red page,此引數配置yellow page的大小。訪問到此處的程式碼會丟擲StackOverflowError異常;

-XX:StackRedPages:同上,red page的大小

-XX:+UseConcMarkSweepGC:該標誌意味著啟用CMS收集器;

-XX:UseParNewGC:一般與上述標誌配合使用,啟用年輕代使用多執行緒並行執行垃圾收集;

-XX:+CMSConcurrentMTEnbaled:啟動該標誌,併發的CMS階段以多執行緒執行;

-XX:ConcGCThreads:定義了上述併發CMS過程執行時的執行緒數;

-XX:CMSInitiatingOccupancyFraction:JVM滿了之後,會啟動並行收集器開始full GC,此時JVM STW,為了儘量減少Full GC,需要在應用程式用完記憶體之間儘量使用CMS GC回收儘量多的空間,這個引數指定了CMS GC啟動的時機,表示記憶體消耗達到此比例時開啟CMS GC,預設68%。

-XX:+CMSClassUnloadingEnabled:設定此標誌,開啟永久代垃圾回收。

-XX:+CMSIncrementalMode:開啟CMS收集器的增量模式,所謂增量模式是指CMS GC的過程中可以暫停,以對應用程式作出讓步。很明顯,開啟此標誌會延長CMS GC的時間。

-XX:+DisableExplicitGC:通知JVM忽略所有的系統GC呼叫;

-XX:+UseCompactAtFullCollection:由於在CMS的回收步驟中,不會對記憶體進行壓縮,所以會有記憶體碎片出現,CMS提供了一個整理碎片的功能,通過此標誌開啟。預設為0,意味著每次GC結束後都會進行記憶體碎片整理。記憶體碎片會導致不可預知的full GC行為,因此該值建議取0。

-XX:+UseCompressedOops:壓縮普通物件的指標,可用於壓縮應用消耗的記憶體空間。需要注意的是:堆大於32G時,該標誌會失效。

-XX:+CMSScavengeBeforeRemark:意思是在執行CMS remark之前進行一次youngGC,這樣能有效降低remark的時間。

-XX:+SoftRefLRUPolicyMSPerMB:貼一下官方解釋softly reachable objects will remain alive for some amount of time after the last time they were referenced.The default value is one second of lifetime per free megabyte in the heap,沒有必要等1s,可以設定成0.

上面是一些常見的JVM引數,歡迎一起補充。