<h2><div class="image-package"><img src="https://upload-images.jianshu.io/upload_images/5149787-9b10aa71b2bad3a8.jpeg" img-data="{"format":"jpeg","size":279883,"width":1920,"height":1280,"space":"srgb","channels":3,"depth":"uchar","density":72,"chromaSubsampling":"4:2:0","isProgressive":false,"hasProfile":false,"hasAlpha":false}" class="uploaded-img" style="min-height:200px;min-width:200px;" width="auto" height="auto"/>
</div></h2><h2><span>告警</span><span/><span> </span></h2><p>公司有個(gè)3.2.7版本的mongo復(fù)制集,最近幾天頻繁告警內(nèi)存過高。</p><p>服務(wù)器配置16C+64G內(nèi)存。mongo備節(jié)點(diǎn)內(nèi)存使用到55G,觸發(fā)告警。</p><p>以下內(nèi)容基于3.2.7版本,3.2.7版本已經(jīng)太老,很多后來的命令和配置,3.2.7都沒有。</p><h2><span/><span>排查</span><span/><span> </span></h2><p>排查mongo配置</p><p>主要是檢查cacheSizeGB</p> wiredTiger:
engineConfig:
cacheSizeGB: 20
<p>MongoDB 3.2 及以后,默認(rèn)使用 WiredTiger 存儲引擎,可通過 cacheSizeGB 選項(xiàng)配置 WiredTiger 引擎使用內(nèi)存的上限,一般建議配置在系統(tǒng)可用內(nèi)存的一班左右。</p><p>默認(rèn)值是(RAM – 1GB) / 2。出發(fā)點(diǎn)是防止系統(tǒng)OOM kill。因?yàn)檫@里的配置只是wiredTiger的內(nèi)存cache限額,并不是mongo的全部使用內(nèi)存限額,整個(gè)mongo進(jìn)程的內(nèi)存占用要比這個(gè)值大,所以cacheSizeGB萬萬不可設(shè)置超過RAM的60%。</p><p>我們這里配置到了20G。但是實(shí)際運(yùn)行中發(fā)現(xiàn),在并發(fā)查詢很高的情況下,wt的cacheSize還是會超過這個(gè)配置一點(diǎn)點(diǎn)。</p><p>查看mongo實(shí)例的內(nèi)存使用情況</p>db.serverStatus().wiredTiger.cache
<p>返回結(jié)果中 bytes currently in the cache 后的值為緩存數(shù)據(jù)的大小</p>...
"bytes currently in the cache" : 21483838298,
...
<p>已經(jīng)用滿了,這種情況可以加一下內(nèi)存了。但是內(nèi)存太貴,業(yè)務(wù)也沒有那么高的性能要求,保障不宕機(jī)是更有性價(jià)比的方案。</p><p>既然cache只用了20G,</p><p>看看tcmalloc的情況</p>db.serverStatus().tcmalloc
------------------------------------------------
MALLOC: 22351254936 (21315.8 MiB) Bytes in use by application
MALLOC: + 24922800128 (23768.2 MiB) Bytes in page heap freelist
MALLOC: + 449403872 ( 428.6 MiB) Bytes in central cache freelist
MALLOC: + 262144 ( 0.2 MiB) Bytes in transfer cache freelist
MALLOC: + 841870984 ( 802.9 MiB) Bytes in thread cache freelists
MALLOC: + 109572256 ( 104.5 MiB) Bytes in malloc metadata
MALLOC: ------------
MALLOC: = 48675164320 (46420.3 MiB) Actual memory used (physical + swap)
MALLOC: + 8663441408 ( 8262.1 MiB) Bytes released to OS (aka unmapped)
MALLOC: ------------
MALLOC: = 57338605728 (54682.4 MiB) Virtual address space used
MALLOC:
MALLOC: 378600 Spans in use
MALLOC: 1451 Thread heaps in use
MALLOC: 8192 Tcmalloc page size
------------------------------------------------
Call ReleaseFreeMemory() to release freelist memory to the OS (via madvise()).
Bytes released to the OS take up virtual address space but no physical memory.
<p>可以看到page heap freelist占了大頭。</p><p>解釋一下,57338605728 (54682.4 MiB) Virtual address space used 是mongo總的使用的虛擬內(nèi)存。</p><p>48675164320 (46420.3 MiB) Actual memory used (physical + swap)是mongo總的使用的實(shí)際內(nèi)存。(我沒有開swap)</p><p>實(shí)際內(nèi)存又分成兩部分,freelist中的和非freelist的。freelist的就是已經(jīng)分配后來又用完釋放的內(nèi)存,存在這個(gè)freelist數(shù)據(jù)結(jié)構(gòu)中,已備后面重用這些內(nèi)存,我的理解就是我用完了,但是我先拿著。這樣后面的業(yè)務(wù)來了,mongo就不需要再向os申請分配內(nèi)存這一步了,從性能和效率的維度來看更好。</p><p>但是缺點(diǎn)是內(nèi)存一直沒有還給os,導(dǎo)致os角度來看,內(nèi)存的使用率很高。</p><p>tcmalloc 為性能考慮,每個(gè)線程會有自己的 local free page cache,還有 central free page cache;內(nèi)存申請時(shí),按 local thread free page cache ==> central free page cache 查找可用內(nèi)存,找不到可用內(nèi)存時(shí)才會從堆上申請;<strong>當(dāng)釋放內(nèi)存時(shí),也會歸還到 cache 里,tcmalloc 后臺慢慢再歸還給 OS操作系統(tǒng)</strong>, 多數(shù)情況下,內(nèi)存使用率高的原因是 tcmalloc 未能及時(shí)將內(nèi)存歸還給操作系統(tǒng),導(dǎo)致內(nèi)存最大可能達(dá)到幾十GB。mongo為了提高性能,傾向于利用os上盡可能多的內(nèi)存。</p><h2><span/><span>解決</span><span/><span> </span></h2><p>所以可以將freelist的內(nèi)存及時(shí)釋放給os,可以解決內(nèi)存水位過高的問題。</p>db.adminCommand({setParameter:1,tcmallocAggressiveMemoryDecommit:1})
<p>tcmallocAggressiveMemoryDecommit 是一個(gè)服務(wù)器參數(shù),用于控制 TCMalloc 內(nèi)存分配器在什么程度上積極地將不再使用的內(nèi)存釋放回操作系統(tǒng)。當(dāng)設(shè)置為 1(開啟狀態(tài))時(shí),tcmallocAggressiveMemoryDecommit 會使 TCMalloc 更積極地釋放不再使用的內(nèi)存。這意味著當(dāng)應(yīng)用程序釋放內(nèi)存后,TCMalloc 會嘗試將這部分內(nèi)存標(biāo)記為空閑并返回給操作系統(tǒng),而不是保留在進(jìn)程的地址空間中以便快速重用。</p><p>
</p>
MongoDB內(nèi)存過高問題分析解決
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
相關(guān)閱讀更多精彩內(nèi)容
- 0 - 概述 系統(tǒng)的物理內(nèi)存是有限的,而對內(nèi)存的需求是變化的, 程序的動(dòng)態(tài)性越強(qiáng),內(nèi)存管理就越重要,選擇合適的內(nèi)存...
- 官方介紹:tcmalloc[https://google.github.io/tcmalloc/]參考文章:TCM...
- 前言 在互聯(lián)網(wǎng)時(shí)代,大部分的應(yīng)用程序基本都是IO密集型,而IO密集型的程序運(yùn)行效率的關(guān)鍵在于內(nèi)存管理,因此充分理解...
- 問題現(xiàn)象 7月25號,我們一服務(wù)的內(nèi)存占用較高,約13G,容器總內(nèi)存16G,占用約85%,觸發(fā)了內(nèi)存報(bào)警(閾值85...