部署mongodb中需要注意的調參


        部署mongodb的生產服務器,給出如下相關建議:

  • 使用虛擬化環境;
  • 系統配置

     1)推薦RAID配置

RAID(Redundant Array of Independent Disk,獨立磁盤冗余陣列)是一種可以讓我們把多塊磁盤當做單獨一塊磁盤來使用的技術。可使用它來提高磁盤的可靠性或者性能,或二者兼有。一組使用RAID技術的磁盤被稱作RAID磁盤陣列。

RAID根據性能的不同,存在着多種配置方式,通常兼顧了速度與容錯性。下列是幾種最常見的配置方式:

  • RAID0 
    使用磁盤分割技術(disk striping)將多個磁盤並列起來以提升性能。每塊磁盤保存一部分數據,與mongodb中的分片類似。由於存在多個底層磁盤,因此大量數據可在同一時間寫入磁盤內。然而,如果其中一塊磁盤發生故障導致數據丟失,則這些數據不會存在備份,這也會導致讀取速度變慢(尤其是在Amazon 的Elastic Block Store 服務上),
    因為一些數據卷可能比另一些要慢。
  • RAID1
    使用鏡像來提高可靠性。同樣的數據副本會被寫入到陣列的每一個成員當中。這一方法的性能要比RAID0低,因為陣列中的一個速度慢的成員會拖慢整個陣列的寫入速度。然而,如果其中一塊磁盤發生故障,還可以在陣列中的其他成員上找到數據副本。
  • RAID5
    在使用磁盤分割技術的基礎上,額外存儲數據的校驗信息,以防服務器故障導致數據丟失。一般情況下,一塊磁盤發生故障時RAID5可以自動處理它,用戶並不會感覺到發生故障。然而,這也使得RAID5 成為這些RAID配置方案中最慢的一種,因為它需要在寫入數據時計算校驗信息。而mongodb所進行的恰恰是典型的多次少量的數據寫入工作,因此使用RAID5所帶來的代價尤為可觀。
  • RAID10
    RAID10是一種RAID0和RAID1的組合:數據被分割以提升速度,又被復制鏡像以提高可靠性。

推薦使用RAID10,它比RAID0更安全,也能解決RAID1的性能問題。在副本集的基礎上,再使用RAID1有些浪費,從而可選擇RAID0。

不要用RAID5,它會非常非常慢。

 

2)虛擬化

a)禁止內存過度分配

  內存過度分配(memory overcommitting)的設置值決定了當進程向操作系統請求過度內存是應采取的策略。基於這一設置,內核可能會為進程分配內存,哪怕那些內存當前是不可用的(期望的結果是,當進程用到這段內存時它已變為可用的)。這種內核向進程許諾不存在的內存的行為,就叫做內存過度分配。這一特性使得Mongodb無法很好的運作。

vm.overcomit_memory的值可能為0(讓內核來猜測過度分配的大小),可能為1(滿足所有內存分配請求),可能為2(分配的虛擬地址空間最多不超過交換空間與一小部分過度分配的和)。將此值設為2所代表的意義最為復雜,同時也是最佳選擇。運行以下命令將此值設為2:

$ echo 2>/proc/sys/vm/overcommit_memory

更改這一設置后,無需重啟Mongodb.

 

在此目錄下,/proc/sys/vm/overcommit_memory

該文件指定了內核針對內存分配的策略,其值可以是0、1、2。

0,   表示內核將檢查是否有足夠的可用內存供應用進程使用;如果有足夠的可用內存,內存申請允許;否則,內存申請失敗,並把錯誤返回給應用進程。

1,   表示內核允許分配所有的物理內存,而不管當前的內存狀態如何。

2,   表示內核允許分配超過所有物理內存和交換空間總和的內存(參照overcommit_ratio)。

缺省設置:0

 

3) 在查閱文檔中,對linux下proc里關於磁盤性能的參數有涉及,如下:

     mongodb的mmap不調用fsync強刷到磁盤,操作系統也是會幫我們自動刷到磁盤的,linux有個dirty_writeback_centisecs參數用於定義臟數據在內存停留的時間(默認為500,即5秒),過了這個timeout時間就會被系統刷到磁盤上。在這個自動刷的過程中是會阻塞所有的IO操作的,如果要刷的數據特別多的話,容易產生一些長耗時的操作,例如有些使用mmap的程序每隔一段時間就會出現有超時操作,一般的優化手段是考慮修改系統參數dirty_writeback_centisecs,加快臟頁刷寫頻率來減少長耗時。mongodb是定時強刷,不會有此問題。

 

在此目錄下,/proc/sys/vm/dirty_writeback_centisecs

這個參數控制內核的臟數據刷新進程pdflush的運行間隔。單位是 1/100 秒。缺省數值是500,也就是 5 秒。如果你的系統是持續地寫入動作,那么實際上還是降低這個數值比較好,這樣可以把尖峰的寫操作削平成多次寫操作。設置方法如下:

echo "100" > /proc/sys/vm/dirty_writeback_centisecs

如果你的系統是短期地尖峰式的寫操作,並且寫入數據不大(幾十M/次)且內存有比較多富裕,那么應該增大此數值:

echo "1000" > /proc/sys/vm/dirty_writeback_centisecs

 

    4)日志

    mongod默認將日志發送至stdout(標准輸出,通常為終端)。大多初始化腳本會使用–logpath選項,將日志發送至文件。如在同一台機器上有多個MongoDB實例(比如說一個mongod和一個mongos),注意保證各實例的日志分別存放在單獨的文件中。確保知道的日志的存放位置,並擁有文件的讀訪問權限。

Mongodb會輸出大量的日志消息,但請不要使用 --quiet選項(該選項會隱藏部分日志信息)。保持日志級別為默認值通常不錯,此時日志中有足夠的信息進行基本調試(如耗時過長或者啟動異常的原因等),但日志占用的空間並不大。調試應用某特定問題時,可使用一些選項從日志中獲取更多信息。

   首先,在重啟Mongodb時,可通過在參數中附加數目更多的“v”(即-v、-vv、-vvv、-vvvv或-vvvvv),或運行如下setParameter命令,完成日志級別(loglevel)的更改。

>db.adminCommand({"setParameter":1,"logLevel":3});

記得將日志級別重設為0,否則日志中會存在過多不必要的內容。可將日志級別調高至5,這時mongod會在日志中記錄幾乎所有的操作,包括每一個請求所處理的內容。由於mongod將所有內容都寫入了日志文件,因此可產生大量的磁盤讀寫操作(IO),從而拖慢一個忙碌的系統。如需即時看到正在進行的所有操作,打開分析器不失為更好的方法:

   MongoDB默認記錄耗時超過100毫秒的查詢信息。如100毫秒不適用於應用,可通過setProfilingLevel 命令來更改此閾值:

> // 只記錄耗時超過500毫秒的查詢操作

> db.setProfilingLevel(1,500)

{"was":0,"slowms":100,"ok":1}

>db.setProfilingLevel(0)

{"was":1,"slowms":500,"ok":1}

上述第二條指令將關閉分析器,但第一條指令中以毫秒為單位的值將繼續作為所有數據庫中日志記錄的閾值而生效。也可以用-slowms 選項重啟MongoDB來更改這一閾值。

最后,設置一個計划任務以便每天或每周分割(rotate)日志文件。如使用–logpath 選項啟動MongoDB,向進程發送一個SIGUSR1 信號即使其對日志進行分割。也可以使用logRotate命令以達到相同目的:

>db.adminCommand({"logRotate":1})

如不是通過 --logpath 選項啟動的MongoDB,則不能對日志進行分割。

 

5) 關閉數據庫文件的 atime

禁止系統對文件的訪問時間更新會有效提高文件讀取的性能。這個可以通過在/etc/fstab 文件中增加 noatime 參數來實現。例如:

/dev/xvdb /data ext4 noatime 0 0

修改完文件后重新 mount就可以:

# mount -o remount /data

 

6)禁止 NUMA

在一個使用NUMA技術的多處理器Linux 系統上,你應該禁止NUMA的使用。MongoDB在NUMA環境下運行性能有時候會可能變慢,特別是在進程負載很高的情況下。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM