部署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)日誌
mongodb預設將日誌發送至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環境下運行效能有時候會可能變慢,特別是在進程負載很高的情況下。
------------------------------------------分割線------------------------------------------
CentOS 6 使用 yum 安裝MongoDB及伺服器端配置
Ubuntu 13.04下安裝MongoDB2.4.3
MongoDB入門必讀(概念與實戰並重)
Ubunu 14.04下MongoDB的安裝指南
《MongoDB 權威指南》(MongoDB: The Definitive Guide)英文文字版[PDF]
Nagios監控MongoDB分區叢集服務實戰
基於CentOS 6.5作業系統搭建MongoDB服務
MongoDB 的詳細介紹:請點這裡
MongoDB 的:請點這裡
本文永久更新連結地址: