MongoDB開發最佳實踐


MongoDB開發最佳實踐

  1. 連接到MongoDB · 關於驅動程序:總是選擇與所用之MongoDB相兼容的驅動程序。這可以很容易地從驅動兼容對照表中查到;

     · 如果使用第三方框架(如Spring Data),則還需要考慮框架版本與驅動的兼容性;
    

    · 關於連接對象MongoClient:使用MongoClient對象連接到MongoDB實例時總是應該保證它單例,並且在這個生命周期 中都從它獲取其他操作對象。

    · 關於連接字符串:連接字符串中可以配置大部分連接選項,建議總是在連接字符串中配置這些選項;

    // 連接到復制集 mongodb://節點1,節點2,節點3.../database?[options]

    // 連接到分片集 mongodb://mongos1,mongos2,mongos3.../database?[options]

  2. 常見連接字符串參數 · maxPoolSize

     · 連接池大小
    

    · maxWaitTime

     · 建議設置,自動殺掉太慢的查詢
    

    · writeConcern

     · 建議majority保證數據安全
    

    · readConcern

     · 對於數據一致性要求高的場景適當使用 
    
  3. 連接字符串節點和地址 · 無論對於復制集或分片集,連接字符串中都應盡可能多地提供節點地址,建議全部列出;

     · 復制集利用這些地址可以更有效地發現集群成員;
     
     · 分片集利用這些地址可以更有效的分散負載;
    

    · 連接字符串中盡可能使用與復制集內部配置相同的域名或IP;

  4. 使用域名連接集群 在配置集群時使用域名可以為集群變更時提供一層額外的保護。例如要將集群整體遷移到新網段,直接修改域名解析即可。

    另外,MongoDB提供的mongoDB+srv://協議可以提供額外一層保護。該協議允許通過域名解析得到所有mongos或節點的地址, 而不是寫在連接字符串中。

    mongodb+srv://server.example.com/

    Record TTL Class Priority Weight Port Target _mongodb._tcp.server.example.com.86400

    IN SRV 0 5 27317 mongodb1.example.com._mongodb._tcp.server.example.86400 IN SRV 0 5 27017 mongodb2.example.com.

  5. 不要在mongos前面使用負載均衡 基於前面提到的原因,驅動已經直銷在不同的mongos之間實現負載均衡,而復制集則需要根據節點的角色來選擇發送請求的目標。 如果在mongos或復制集上層部署負載均衡:

    · 驅動會無法探測具體那個節點存活,從而無法完成自動故障恢復;

    · 驅動會無法判斷游標是在哪個節點創建的,從而遍歷游標時出錯;

    結論:不要在mongos或復制集上層放置負載均衡器,讓驅動處理負載均衡和自動故障恢復。

  6. 游標使用 如果一個游標已經遍歷完,則自動關閉;如果沒有遍歷完,則需要手動調用close()方法,否則該游標將在服務器上存在 10分鍾(默認值)后超時釋放,造成不必要的資源浪費。

    但是,如果不能遍歷完一個游標,通常意味着查詢條件太寬泛,更應該考慮的問題是如何將條件收緊。

  7. 關於查詢及索引 · 每一個查詢都必須要有對應的索引

    · 盡量使用覆蓋索引Covered indexes(可以避免讀數據文件)

    · 使用projection來減少返回客戶端的文檔內容

  8. 關於寫入 · 在update語句里只包括需要更新的字段

    · 盡可能使用批量插入語句來提升寫入性能

    · 使用TTL自動過期日志類型的數據

  9. 關於文檔結構 · 防止使用太長的字段名(浪費空間)

    · 防止使用太深的數組嵌套(超過2層操作比較負責)

    · 不使用中文,標點符號等非拉丁字母作為字段名

  10. 處理分頁問題-避免使用count 盡可能不要計算總頁數,特別是數據量大和查詢條件不能完整命中索引時。

    考慮以下場景:假設集合總共有1000W條數據,在沒有索引的情況下考慮以下查詢:

    db.coll.find({x:100}).limit(50);
    db.coll.count({x:100});
    

    · 前者只需要遍歷前n條,直到找到50條隊伍 x = 100 的文檔即可結束;

    · 后者需要遍歷完1000W條所有符合要求的文檔才能得到結果。

    為了計算總頁數而進行count()往往是拖慢頁面真題加載速度的原因。

  11. 處理分頁問題——巧分頁 避免使用skip/limit形式的分頁,特別是數據量大的時候;

    替代方案:使用條件查詢+唯一條件排序;

    例如:

    第一頁:db.find({}).sort({_id: 1}).limit(20);

    第二頁:db.find({_id:{$gt:<第一頁最后一個_id>}}).sort({_id: 1}).limit(20);

    第三頁:db.find({_id:{$gt:<第二頁最后一個_id>}}).sort({_id: 1}).limit(20);

    ······

  12. 關於事務 使用事務的原則:

    · 無論何時,事務的使用總是能避免則避免;

    · 模型設計先於事務,盡可能用模型設計規避事務;

    · 不要使用過大的事務(盡量控制在1000個文檔更新以內);

    · 當必須使用事務時,盡可能讓涉及事務的文檔分布在同一片上,這將有效地提高效率;


免責聲明!

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



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