日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

mongodb 对内存的严重占用以及解决方法

發布時間:2024/8/26 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mongodb 对内存的严重占用以及解决方法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
mongodb 對內存的嚴重占用以及解決方法【轉載】?

剛開始使用mongodb的時候,不太注意mongodb的內存使用,但通過查資料發現mongodb對內存的占用是巨大的,在本地測試服務器中,8G的內存居然被占用了45%。汗呀。?
本文就來剖析一下mongodb對內存的具體使用方法,以及生產環境針對mongodb占大量內存的問題的解決。?
先看一個MongoDB服務器的top命令結果?
shell> top -p $(pidof mongod)?
Mem:? 32872124k total, 30065320k used,? 2806804k free,?? 245020k buffers?
Swap:? 2097144k total,????? 100k used,? 2097044k free, 26482048k cached?
VIRT? RES? SHR %MEM?
1892g? 21g? 21g 69.6?

或者 先top后,然后 shift+m 把當前進場按占用內存的多少排序。看看你的mongodb能占用多少內存。?


先了解一下linux對內存的管理方式:?
在Linux里(別的系統也差不多),內存有物理內存和虛擬內存之說,物理內存是什么自然無需解釋,虛擬內存實際是物理內存的抽象,多數情況下,出于方便性的考慮,程序訪問的都是虛擬內存地址,然后操作系統會把它翻譯成物理內存地址。?
很多人會把虛擬內存和Swap混為一談,實際上Swap只是虛擬內存引申出的一種技術而已:操作系統一旦物理內存不足,為了騰出內存空間存放新內容,就會把當前物理內存中的內容放到交換分區里,稍后用到的時候再取回來,需要注意的是,Swap的使用可能會帶來性能問題,偶爾為之無需緊張,糟糕的是物理內存和交換分區頻繁的發生數據交換,這被稱之為Swap顛簸,一旦發生這種情況,先要明確是什么原因造成的,如果是內存不足就好辦了,加內存就可以解決,不過有的時候即使內存充足也可能會出現這種問題,比如MySQL就有可能出現這樣的情況,解決方法是限制使用Swap:?
shell> sysctl -w vm.swappiness=0?
查看內存情況最常用的是free命令:?
shell> free -m?
???????????? total?????? used?????? free???? shared??? buffers???? cached?
Mem:???????? 32101????? 29377?????? 2723????????? 0??????? 239????? 25880?
-/+ buffers/cache:?????? 3258????? 28842?
Swap:???????? 2047????????? 0?????? 2047?
新手看到used一欄數值偏大,free一欄數值偏小,往往會認為內存要用光了。其實并非如此,之所以這樣是因為每當我們操作文件的時候,Linux都會盡可能的把文件緩存到內存里,這樣下次訪問的時候,就可以直接從內存中取結果,所以cached一欄的數值非常的大,不過不用擔心,這部分內存是可回收的,操作系統會按照LRU算法淘汰冷數據。除了cached,還有一個buffers,它和cached類似,也是可回收的,不過它的側重點在于緩解不同設備的操作速度不一致造成的阻塞,這里就不多做解釋了。?
知道了原理,我們就可以推算出系統可用的內存是free + buffers + cached:?
shell> echo "2723 + 239 + 25880" | bc -l?
28842?
至于系統實際使用的內存是used – buffers – cached:?
shell> echo "29377 - 239 - 25880" | bc -l?
3258?
除了free命令,還可以使用sar命令:?
shell> sar -r?
kbmemfree kbmemused? %memused kbbuffers? kbcached?
? 3224392? 29647732???? 90.19??? 246116? 26070160?
? 3116324? 29755800???? 90.52??? 245992? 26157372?
? 2959520? 29912604???? 91.00??? 245556? 26316396?
? 2792248? 30079876???? 91.51??? 245680? 26485672?
? 2718260? 30153864???? 91.73??? 245684? 26563540?

shell> sar -W?
pswpin/s pswpout/s?
??? 0.00????? 0.00?
??? 0.00????? 0.00?
??? 0.00????? 0.00?
??? 0.00????? 0.00?
??? 0.00????? 0.00?
希望你沒有被%memused嚇到,如果不幸言中,請參考free命令的解釋。?

接著咱們分析一下mongodb是怎么使用內存的:?

目前,MongoDB使用的是內存映射存儲引擎,它會把磁盤IO操作轉換成內存操作,如果是讀操作,內存中的數據起到緩存的作用,如果是寫操作,內存還可以把隨機的寫操作轉換成順序的寫操作,總之可以大幅度提升性能。MongoDB并不干涉內存管理工作,而是把這些工作留給操作系統的虛擬緩存管理器去處理,這樣的好處是簡化了MongoDB的工作,但壞處是你沒有方法很方便的控制MongoDB占多大內存,事實上MongoDB會占用所有能用的內存,所以最好不要把別的服務和MongoDB放一起。?

有時候,即便MongoDB使用的是64位操作系統,也可能會遭遇臭名昭著的OOM問題,出現這種情況,多半是因為限制了虛擬內存的大小所致,可以這樣查看當前值:?

shell> ulimit -a | grep 'virtual'?
多數操作系統缺省都是把它設置成unlimited的,如果你的操作系統不是,可以這樣修改:?

shell> ulimit -v unlimited?
不過要注意的是,ulimit的使用是有上下文的,最好放在MongoDB的啟動腳本里。?

有時候,出于某些原因,你可能想釋放掉MongoDB占用的內存,不過前面說了,內存管理工作是由虛擬內存管理器控制的,所以通常你只能通過重啟服務來釋放內存,你一定不齒于這樣的方法,幸好可以使用MongoDB內置的closeAllDatabases命令達到目的:?

mongo> use admin?
mongo> db.runCommand({closeAllDatabases:1})?
另外,通過調整內核參數drop_caches也可以釋放緩存:?

shell> sysctl -w vm.drop_caches=1?
平時可以通過mongo命令行來監控MongoDB的內存使用情況,如下所示:?

mongo> db.serverStatus().mem:?
{?
??? "resident" : 22346,?
??? "virtual" : 1938524,?
??? "mapped" : 962283?
}?
還可以通過mongostat命令來監控MongoDB的內存使用情況,如下所示:?
shell> mongostat?
mapped? vsize??? res faults?
? 940g? 1893g? 21.9g????? 0?
? 940g? 1893g? 21.9g????? 0?
? 940g? 1893g? 21.9g????? 0?
? 940g? 1893g? 21.9g????? 0?
? 940g? 1893g? 21.9g????? 0?

其中內存相關字段的含義是:?
mapped:映射到內存的數據大小?
visze:占用的虛擬內存大小?
res:實際使用的內存大小?
注:如果操作不能再內存中完成,結果faults列的數值不會是0,視大小可能有性能問題。?

在上面的結果中,vsize是mapped的兩倍,而mapped等于數據文件的大小,所以說vsize是數據文件的兩倍,之所以會這樣,是因為本例中,MongoDB開啟了journal,需要在內存里多映射一次數據文件,如果關閉journal,則vsize和mapped大致相當。?

如果想驗證這一點,可以在開啟或關閉journal后,通過pmap命令來觀察文件映射情況:?
shell> pmap $(pidof mongod)?
到底MongoDB配備多大內存合適?寬泛點來說,多多益善,如果要確切點來說,這實際取決于你的數據及索引的大小,內存如果能夠裝下全部數據加索引是最佳情況,不過很多時候,數據都會比內存大,比如本文說涉及的MongoDB實例:?
mongo> db.stats()?
{?
??????? "dataSize" : 1004862191980,?
??????? "indexSize" : 1335929664?
}?
本例中索引只有1G多,內存完全能裝下,而數據文件則達到了1T,估計很難找到這么大內存,此時保證內存能裝下熱數據即可,至于熱數據有多少,這就是個比例問題了,取決于具體的應用。如此一來內存大小就明確了:內存 > 索引 + 熱數據。?

根據以上的分析我們可以得出幾點結論:?
1. mongodb 直接用操作系統的內存管理器來管理內存。而操作系統采用的是LRU算法淘汰冷數據。?
2. mongodb可以用重啟服務、調整內核參數以及mongodb內部的語法去清理mongodb對內存的緩存。可能存在的問題是:這幾種清理方式都是全部清理,這樣的話mongodb的內存緩存就失效了。?
3. mongodb 對內存的使用是可以被監控的,在生產環境中要定時的去監控這些數據。?
4. mongodb 對內存這種占用方式使其盡量的和其他占用內存的業務分開部署,例如memcahe,sphinx,mysql等。?
5. 操作系統中的交換分區swap 如果操作頻繁的話,會嚴重降低系統效率。要解決可以禁用交換分區,以及增加內存以及做分布式。?
6.? 生產環境中mongodb所在的主機應該盡量的大內存。?

總結

以上是生活随笔為你收集整理的mongodb 对内存的严重占用以及解决方法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。