55最佳實務系列:MongoDB最佳實務

來源:互聯網
上載者:User
@鄭昀匯總 建立日期:2012/9  Application Design: 1) 如果發現query沒使用你預期的索引,請用hint強制使用指定索引主站商品中心所使用的文檔欄位很多,各種索引建得也不少。在沙創排查慢查詢時,曾百思不得其解,為什麼明明建的有聯合索引,查詢起來還是非常慢呢,直到顯式指定使用該聯合索引。hint的例子:    db.collection.find({"age" : 18, "username" : /.*/}).hint({"username" : 1, "age" : 1})  2) Design documents to be self-sufficient, 設計 自給自足的文檔MongoDB 應該是一個大的、無聲的資料存放區(big, dumb data store)。它幾乎不需做任何處理,只是負責儲存和讀取資料。你應該堅持這個目的,避免強迫 MongoDB 做一些用戶端可以進行的計算工作。如果真的想算一些文檔裡沒有顯式儲存的資料,你有兩個選擇:——招致嚴重的效能懲罰(讓 MongoDB 用JavaScript 做運算);——在文檔中顯式儲存這些資料。  Implementation: 3) Override _id when you have your own simple, unique id如果你的文檔自己有明確的唯一索引值,不需要 ObjectId 屬性,那麼請覆蓋預設的 _id 欄位,反正你也要在自己的 unique id 上建唯一索引。  Optimization: 4)資料量很大時,建聯合索引時,不妨對比下索引升序和降序的查詢效率db.collection.ensureIndex({"store_id":- 1, "shop_id": 1})上面的1代表ascending升序,-1代表descending降序。單個欄位建索引時,不需要考慮索引升序還是降序,都行。但聯合索引下的排序或範圍查詢(包括$in, $gt, $lt 等),需要重視索引設為升序還是降序。孫國璽認為,最好用大資料類比一下業務情境,商戶中心曾發現設-1比1快10倍以上。  5)如需在聯合索引下排序,索引的建立方法MongoDB 和 MySQL 都是B-Tree結構索引,所以一般來說,聯合索引都可以這麼建:查詢語句是:    db.collection.find({x : 1,y : 2}).sort({z : 1})那麼,索引可以是:    db.collection.ensureIndex({x : 1, y : 1,z : 1})//即x+y+z也可以是:    db.collection.ensureIndex({y : 1, x : 1,z : 1})//即y+x+z排序欄位總在聯合索引的最後。盡量把能過濾資料量多的欄位放在前面。但如果涉及範圍查詢(Range Queries),就要小心了。查詢語句是:    db.collection.find({"country": {"$in": ["ZH", "EN"]}}).sort({"cars": 1})那麼較好的索引是:    db.collection.ensureIndex({"cars": 1,"country": 1})即,在範圍查詢(包括$in, $gt, $lt 等)時,其實刻意在後面追加排序索引通常是沒有效果的。因為在進行範圍查詢的過程中,我們得到的結果集本身並不是按追加的這個欄位來排的,還需要進行一次額外的排序才行。而在這種情況下,可能反序建立索引(排序欄位在前、範圍查詢欄位在後)反而會是一個比較優的選擇。當然,是否更優也和具體的資料集有關,還是要實測。再舉一個例子:查詢語句是:    db.collection.find({x : 1,y : {$in:[1,2]}}).sort({z : 1})那麼較好的索引是:    db.collection.ensureIndex({x : 1, z : 1,y : 1})//即x+z+y  6)養成用 explain 確認是否充分利用了索引的 習慣請確認你的查詢是否充分利用到了索引,用explain命令查看一下查詢執行的情況,添加必要的索引,避免掃表操作。  7)查詢盡量採用分頁,並且儘快釋放遊標  8) 避免使用不會命中索引的文法,如 $nin  Data Safety and Consistency:

9)總是使用 Replica Sets (複製群集,複本集):

背景:Replica Sets 通過自動 failover 機制提供MongoDB的高可用性。Replica sets are a form of asynchronous master/slave replication, adding automatic failover and automatic recovery of member nodes應用點:在應用中,如 primary 機器出現故障,那麼某一台 secondary 機器就會通 過選舉成為新的 primary ,整個叢集仍然能夠提供正常服務。我們的服務不會支援無同步機制的 MongoDB 部署方案。圖例:
另,使用 Replica Sets 時,最好加1台仲裁伺服器。   10) 預設開啟 journaling 日誌:背景:64-bitMongoDB 1.9.2+以上預設開啟 Journaling 功能。32-bit或1.9.2以下版本,則需在命令列啟動時加上 --journal 。Journaling 的出現歸因於某使用者在單機使用 MongoDB 時執行了 kill -9 操作,導致資料不可用後提出的。開啟該功能時,變更會先寫入 Journaling 日誌,定期集中提交,然後在真實資料上進行這些變更。如果伺服器安全關閉,日誌會被清除。在伺服器啟動時,如果存在 Journaling 日誌,則會進行回放。這保證了那些已寫入、但在伺服器崩潰前還沒有回放的日誌能在使用者串連前被執行。 應用點:鄭昀強烈建議你在部署時開啟 Journaling 日誌。注意資料檔案的存放位置。在使用時,請確認你的資料檔案處於一個持久化儲存中(比如/data /mongodb目錄)。也可以使用非持久化的裝置進行資料檔案儲存,不過你最好小心再小心,因為這可能會對你的叢集架構造成影響。熱資料最好能放在記憶體中。能夠保持熱資料(以及索引資料)一直放在記憶體中,這一點非常重要,它將對整個叢集的效能造成影響。如果通過監控發現 page fault 的數量增加,那麼很可能就是熱資料量超出了可用記憶體大小。當熱資料量超出了可用記憶體量時,通常有兩種解決方案:增加記憶體和資料分區。建議先增加記憶體,再考慮通過資料分區的方式解決。  Administration: 11) 保持版本更新:應用點:保持版本更新很重要,10gen 在每個版本中都會修複一些問題,使 MongoDB 的運行更出色。比如在 2.0.x版本中,MongoDB 的儲存效能和並發效能就有極大提高,同時還包括索引最佳化、Bug修複以及 compaction 命令等一系列改進。  12) 不要在32位系統上使用MongoDB:背景:在32位機器上,MongoDB只能儲存約2.5GB的資料。因為 MongoDB在內部實現上是通過記憶體映射的方式來提高效能的,所以在32位機器上其記憶體位址本身就限制了資料容量。  13) 壓力過大升級伺服器配置:應用點:如果機器負載達到65%,那麼應該考慮升級機器配置。在日常使用中,最好保持負載低於65%。同時這也對資料恢複和縱向擴充有影響。  14) 確定熱資料大小:使用MongoDB,你最好保證你的熱資料在你機器的記憶體大小之下,保證記憶體能容納所有熱資料。  15) 選擇正確的檔案系統:MongoDB 的資料檔案是採用的預分配模式,並且在 Replication 裡面,Master 和 Replica Sets 的非 Arbiter 節點都是會預先建立足夠的空檔案用以儲存動作記錄。這些檔案分配操作在一些檔案系統上可能會非常慢,導致進程被 Block 。所以我們應該選擇那些空間分配快速的檔案系統。這裡的結論是盡量不要用ext3,用ext4或者xfs。  16) 選用合適的raid和磁碟:盡量使用raid10,避免使用raid5,經濟條件允許的情況下最好使用ssd硬碟。  17)如何 關閉 MongoDB:MongoDB 資料庫在關閉的時候使用 kill -2 <mongo-pid>,或者在 mongo 終端中使用  use admindb.shutdownServer()  18) 分區( sharding) 需謹慎:應用點:分區策略會受資料訪問特點的影響,所以在進行資料分區前,最好先理清楚資料的訪問模式,並想明白是否確實需要分區。由於 Shard Key 對效能的影響非常大,所以選擇一個好的 Sharding Key 是非常重要的。對於 Shard Key 的選定直接決定了叢集中資料分布是否均衡、叢集效能是否合理。選擇 Shard Key 的一個非常重要因素是萬一某一個分區徹底不可訪問了,受到影響的Chunk有多大(即使是用 Replica Set)。Config Server 對整個叢集的健康運行是至關重要的,所以一旦你選擇使用 分區機制,就一定要保證生產環境裡有3個 Config Servers 。永遠不要刪除 Config Servers 的資料,要確保頻繁地對這些資料進行日常備份。如果可能,通過網域名稱來指定節 點的地址,比如在/etc/hosts檔案中指定相應的本地區名,這能讓你在叢集配置上更靈活。Config Servers 的壓力很小,但還是必須運行在 64-bit instances 上。千萬不要把3個 Config Servers 都放在同一個 instance 上!  本文首發於旁觀者-鄭昀的55最佳實務系列,連結:http://www.cnblogs.com/zhengyun_ustc/archive/2012/12/15/mongodb_bp.html 參考資源:1)程式員雜誌:Engine Yard眼中的MongoDB最佳實務英文原文: http://www.engineyard.com/blog/2011/mongodb-best-practices/ 2)Kristina Chodorow,50 Tips and Tricks for MongoDB Developers3)部分內容來自宋濤,劉奎波和孫國璽4)nosqlfan,mongodb資料匯總專題贈圖幾枚: 
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.