Mongodb 實戰優化

http://snoopyxdy.blog.163.com/blog/static/6011744020157511536993/


Mongodb 實戰優化  

Mongodb是一個高性能,可擴展數據庫,並具有低延遲,高吞吐率的性能。但是使用過程中難免會有所坑,下面將介紹一些優化方案。
以下建議翻譯自 亞馬遜的 《Performance Best Practices for MongoDB 2015
補充是自己在Mongodb實踐中的總結

1、Mongodb引擎
Mongodb 3.0 支持了2種引擎:
A、默認的 MMAPv1 引擎,老版本一種使用
B、WiredTiger 引擎,新支持的db引擎
這兩種引擎可以在一個副本集中共存,他們之前的遷移是很容易,也就是說,從 MMAPv1 老的引擎升級到新的 WiredTiger 引擎是不會破壞原有數據的。
這兩種引擎是爲不同的業務場景做的優化,下面的優化方案會提及支持的相關引擎。

2、硬件優化
2.1、確保足夠的內存:
保證內存大於數據存儲大小,優化內存是最顯而易見的方案
補充:實踐證明,儘量保證數據塊大小不要超出系統內存的一半,性能最優

2.2、在高寫入應用中,使用SSD硬盤
Mongodb的落盤操作是隨機的,一般60s落盤,100ms寫journal,所以使用SSD硬盤一般會有很顯著的寫入20-50倍的提升。
補充:當內存在合理範圍內,更換SSD硬盤並不會顯著提升寫性能,關閉journal會提升一些性能,但是可能會帶來數據丟失的風險

2.3、壓縮存儲和I/O密集型負載
新的存儲引擎 WiredTiger 允許壓縮存儲,設置合理的壓縮配置,可以防止壓縮過大導致的I/O密集型的CPU負載過高的情況。

2.4、使用更快的CPU
這點毋容置疑,新的存儲引擎WiredTiger可以比MMAPv1更好的利用多核。

2.5、儘量將Mongodb實例獨享物理設備
這兒也不用多說,獨享設備肯定是最好

2.6、使用多個mongos
當集羣增加後,也要相應的增加mongos

3、應用層優化
3.1、只更新需要更新的字段:
不是更新所有的字段,而只是更新需要更新的改變過的字段,這樣可以避免檢索文檔所有的字段,減少網絡傳輸和數據庫負載。

3.2、避免單一 非 條件的查詢:
如果單一的非條件查詢,會進行全表掃描,儘量避免它

3.3、在你的應用中,使用 explain() 測試你的每一條語句
執行計劃explain()可以讓你有很多意想不到的收穫

3.4、覆蓋索引的查詢
這個無需多說了,查詢的條件儘可能多的覆蓋索引

3.5、避免不帶片鍵查詢
在集羣中,如果不帶片鍵查詢,會去每片查詢,避免這樣的操作

3.6、讀寫分離
因爲主庫和從庫的同步延遲,如果應用能容忍延遲,最好是從庫讀,主庫寫

3.7、使用最新的客戶端連接庫
mongodb一直在不斷的更新,儘量使用官方提供的最新連接庫

3.8、分片均勻
如果 mongodb 採用分片,片鍵的選擇非常重要,又要能分片均勻,又要保證讀寫性能高,還要保證可擴展

3.9、選擇合適的片鍵
同上

補充:
4.0、大量更新批量操作
實際經驗,如果一個集合有大量的upate或insert操作,那麼與其一個個操作的去連接,不如匯聚到1000-5000條左右,一次性批量寫入,可以有效減少鎖的競爭情況,性能有顯著提高。

4、結構設計和索引
4.1、儘量把數據存成一個文檔
在合適的時候把數據存儲爲一個文檔,可以非常高效的利於查詢,這樣搜索的條數就很少,打開展平對於搜索是不利的,但是過重的一個文檔可能也會帶來寫的問題。

4.2、避免過大文檔
Mongodb一個文檔最大爲16MB,在實際情況中,很多文檔都是小於幾KB的,比如在文檔裏維護一個很大的列表,應該將列表打開,一行一條記錄。

4.3、避免文檔無限的增長
Mongodb爲了節約存儲空間,會以 usePowerOf2Sizes 來增長一個文檔的存儲空間,舉個例子:
比如:第一次插入這個文檔,文檔大小爲1KB,這時Mongodb會以2KB來存儲,在文檔增長到2KB以內時,是不會移動文檔和索引存儲塊的。當這個文檔增長到 2KB 後,Mongodb又會設置 4KB 來存儲它,每次都是以2倍的量存儲,保證了空間的利用和存儲塊移動之間的平衡。如果一個文檔不停的無限增長,可能會因爲頻繁的移動存儲塊而影響性能。
補充:實際情況中設置usePowerOf2Sizes這個參數,並沒有顯著的性能提升

4.4、避免大的索引數組
多字段索引可能會利於查詢,但是會讓寫操作變慢,所以要權衡一下。

4.5、避免過長的字段名
Mongodb的字段名和sql不同,會佔用文檔的空間,增加網絡傳輸壓力,儘量用短小精簡的字段名,可以在程序那邊做映射。
補充:實際情況,設置短小精簡的字段名,可以顯著提升查詢性能

4.6、避免 select * 的查詢
這點和sql一樣,用不到的字段不要返回了
補充:實際情況也是如此,不查詢不需要的字段,顯著提升性能

4.7、優化索引
避免索引命中不散列,比如對一個枚舉,布爾值做索引,都是無效的

4.8、組合索引可以包含單個索引
比如有一個組合索引 {"lastname":1, "firstname":1},是沒必要建立 {"lastname":1} 這個索引的,因爲已經被包括在了組合索引裏了

4.9、避免正則表達式沒有命中索引
這個類似sql的like,如果要命中索引,必須從頭開始匹配

4.10、使用 wiredtiger 引擎,索引放其他地方存儲
使用 wiredtiger 引擎,索引可以放在其他地方存儲,比如更快的硬盤,資源爭搶I/O更少的磁盤

5、磁盤I/O
5.1、readhead需要設置爲32
爲了mongodb的性能,readhead這個值不能設置少於32,如果設置過多會浪費內存。

5.2、使用EXT4或者XFS文件系統,避免EXT3
EXT3文件系統太過陳舊,沒有對數據庫進行優化,不夠高效

5.3、關閉 access time 設置
關閉對文件最後一次訪問的時間記錄,因爲database一直在訪問文件,所以關閉它能夠提升性能

5.4、不要使用大量的虛擬內存
將虛擬內存設置爲合理大小,不要設置過大

5.5、使用Raid10
使用Raid10來做存儲,性能和數據安全都有保證

6、性能配置
6.1、做好性能測試
在應用上線之前,需要做性能測試來評估

6.2、片鍵
如果沒有範圍的片鍵搜索,建議使用hash來使用片鍵,如果有範圍的搜索,建議將他們提前處理,然後並行搜索獲取。

6.3、關閉塊自動平衡
關閉自動移動塊平衡,提升性能
補充:實際情況中,這個設置沒有顯著提升性能,建議還是打開

6.4、預熱系統幾分鐘
這個看上去沒啥用

6.5、對系統瓶頸進行監控
這個也是必須的

發佈了21 篇原創文章 · 獲贊 7 · 訪問量 63萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章