現在的位置: 首頁 > 資料庫 > 正文

Linux如何管理內存?Linux中MongoDB是如何使用內存

2020年07月02日 資料庫 ⁄ 共 3274字 ⁄ 字型大小 評論關閉

  初次接觸MongoDB的人,無不驚訝於它對內存的貪得無厭,那就先看一個MongoDB伺服器的top命令結果:shell>top-p$(pidofmongod),Mem:32872124ktotal,30065320kused,2806804kfree,245020kbuffers。下面學步園小編來講解下Linux如何管理內存?Linux中MongoDB是如何使用內存?

  Linux如何管理內存

  在Linux里(別的系統也差不多),內存有物理內存和虛擬內存之說,物理內存是什麼自然無需解釋,虛擬內存實際是物理內存的抽象,多數情況下,出於方便性的考慮,程序訪問的都是虛擬內存地址,然後操作系統會把它翻譯成物理內存地址。

  很多人會把虛擬內存和Swap混為一談,實際上Swap只是虛擬內存引申出的一種技術而已:操作系統一旦物理內存不足,為了騰出內存空間存放新內容,就會把當前物理內存中的內容放到交換分區里,稍後用到的時候再取回來,需要注意的是,Swap的使用可能會帶來性能問題,偶爾為之無需緊張,糟糕的是物理內存和交換分區頻繁的發生數據交換,這被稱之為Swap顛簸,一旦發生這種情況,先要明確是什麼原因造成的,如果是內存不足就好辦了,加內存就可以解決,不過有的時候即使內存充足也可能會出現這種問題,比如MySQL就有可能出現這樣的情況,解決方法是限制使用Swap:

  shell>sysctl-wvm.swappiness=0

  查看內存情況最常用的是free命令:

  shell>free-m

  totalusedfreesharedbufferscached

  Mem:32101293772723023925880

  -/+buffers/cache:325828842

  Swap:204702047

  新手看到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

  kbmemfreekbmemused%memusedkbbufferskbcached

  32243922964773290.1924611626070160

  31163242975580090.5224599226157372

  29595202991260491.0024555626316396

  27922483007987691.5124568026485672

  27182603015386491.7324568426563540

  shell>sar-W

  pswpin/spswpout/s

  0.000.00

  0.000.00

  0.000.00

  0.000.00

  0.000.00

  希望你沒有被%memused嚇到,如果不幸言中,請參考free命令的解釋。

  Linux中MongoDB是如何使用內存

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

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

  shell>ulimit-a|grep'virtual'

  多數操作系統預設都是把它設置成unlimited的,如果你的操作系統不是,可以這樣修改:

  shell>ulimit-vunlimited

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

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

  mongo>useadmin

  mongo>db.runCommand({closeAllDatabases:1})

  另外,通過調整內核參數drop_caches也可以釋放緩存:

  shell>sysctl-wvm.drop_caches=1

  平時可以通過mongo命令行來監控MongoDB的內存使用情況,如下所示:

  mongo>db.serverStatus().mem:

  {

  "resident":22346,

  "virtual":1938524,

  "mapped":962283

  }

  還可以通過mongostat命令來監控MongoDB的內存使用情況,如下所示:

  shell>mongostat

  mappedvsizeresfaults

  940g1893g21.9g0

  940g1893g21.9g0

  940g1893g21.9g0

  940g1893g21.9g0

  940g1893g21.9g0

  其中內存相關欄位的含義是:

  mapped:映射到內存的數據大小

  visze:佔用的虛擬內存大小

  res:實際使用的內存大小

  註:如果操作不能再內存中完成,結果faults列的數值不會是0,視大小可能有性能問題。

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

  如果想驗證這一點,可以在開啟或關閉journal後,通過pmap命令來觀察文件映射情況:

  shell>pmap$(pidofmongod)

  到底MongoDB配備多大內存合適?寬泛點來說,多多益善,如果要確切點來說,這實際取決於你的數據及索引的大小,內存如果能夠裝下全部數據加索引是最佳情況,不過很多時候,數據都會比內存大,比如本文說涉及的MongoDB實例:

  mongo>db.stats()

  {

  "dataSize":1004862191980,

  "indexSize":1335929664

  }

  本例中索引只有1G多,內存完全能裝下,而數據文件則達到了1T,估計很難找到這麼大內存,此時保證內存能裝下熱數據即可,至於熱數據有多少,這就是個比例問題了,取決於具體的應用。如此一來內存大小就明確了:內存>索引+熱數據。

  以上就是關於「Linux如何管理內存?Linux中MongoDB是如何使用內存」的內容,希望對大家有用。更多資訊請關注學步園。學步園,您學習IT技術的優質平台!

抱歉!評論已關閉.