这两天经常会收到hadoop namenode 内存使用百分比的告警,经常收到告警是一个讨厌的事情,是不是说明我们系统超负荷有问题了?怎么样解决这个问题?这两天一直在仔细查考测试这个问题,现将我的思考说明一下。
1. 首先,这个告警message说的是namenode这台机器真的内存的使用百分比,其实并不太准确。事实上它不是说明机器内存用光了,而是namenode的jvm进程堆内存使用快光了。
2. 我们知道jvm的堆内存是指HeapSize,这个由-Xmx设定最大值,-Xms设定初始值。如果Xms<Xmx,那么当前实际HeapSize是介于Xms与Xmx两者之间的,我们用CurrentHeapSize表示,其中包括使用了的(used)和未使用的(free)。而堆内存又分Young Generation和Old Generation,主要是两种采用了不同垃圾回收gc策略,我用YoungHeapSize和OldHeapSize表示,其中也包括使用了的(used)和未使用的(free),。当然Young Generation又分(Eden区和Survivor区),但在这里,事实上我们不需要关注Young Generation细分到的不同区。
3. 不管是Young 还是Old,当usedYoung等于Young或者usedOld等于Old,就会启动gc, 并且会增加YoungHeapSize和OldHeapSize直到两者相加等于Xmx.
4. 因此这个告警之前采集的百分比:usedCurrentHeapSize/Xmx=(usedCurrentYoungHeapSize+usedCurrentOldHeapSize)/Xmx,到full gc时刻,会最终等于(CurrentYoungHeapSize+CurrentOldHeapSize)/Xmx。现在收到超过90%的告警,说明的就是(CurrentYoungHeapSize + CurrentOldHeapSize)快接近Xmx了,并且到了即将full gc时刻。如果想要不收到超过90%的告警,也就是说我们必须(CurrentYoungHeapSize + CurrentOldHeapSize)最大值小一些,留一些缓冲。但是CurrentYoungHeap和CurrentOldHeap会不断增加,直到两者相加等于Xmx,除非能够设定MaxYoungHeapSize和MaxOldHeapSize.