Mongodb 開發之路 24 MongoDB 開發最佳實踐

一,連接 MongoDB 

1. 關於驅動程序: 總是選擇與所用之MongoDB 相兼容的驅動程序。這可以很容易地從驅動兼容對照表中查到;
    . 如果使用第三框架(Spring Data),則需要考慮框架版本與驅動的兼容性;
2. 關於連接對象MongoClient: 使用MongoClient 對象連接到MongoDB 實例時總是應該保證它單例,並且在整個生命週期中都從它獲取其他操作對象

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

// 連接到複製集
mongodb://節點1,節點2,節點3/database?[options]
//連接到分片集
mongodb://mongos1,mongos2,mongo3/database?[options]

 二,常見連接字符串參數
 
 1. maxPoolSize
     1.1 連接池大小
 2. Max wait Time 
     2.1  建議設置,自動殺掉太慢的查詢
 3. Write Concern
     3.1 建議majority 保證數據安全
 4. Read Concern
     4.1 對於數據一致性要求高的場景適當使用


三, 連接字符串節點和地址
 1. 無論對於複製集或分片集,連接字符串中都應儘可能地提供節點地址,建議全部列出
     1.1 複製集利用這些地址可以更有效地發現集羣成員
     1.2 分片集利用這些地址可以更有效地分散負載
  2. 連接字符串中儘可能使用與複製集內部配置相同的域名或ip

  3.使用域名連接集羣
      3.1在配置集羣時使用域名可以爲集羣變更時提供一層額外的保護,例如需要將集羣整體遷移到新網段,直接修改域名解析即可
      另外,MongoDB 提供的mongodb+srv://協議可以提供額外一層的保護。該協議允許通過域名解析得到所有mongos 或節點的
      的地址,而不是寫在連接字符串中。

      mongodb+srv://server.example.com

四,不要在mongos 前面使用負載均衡
     基於前面提到的原因,驅動已經知曉在不同的mongos 之間實現負載均衡,而複製集則需要根據節點的角色來選擇發送請求的目標,
     如果在mongos 或者複製集上層部署負載均衡:
     1. 驅動會無法探測具體哪個節點存活,從而無法完成自動故障恢復
     2. 驅動會無法判斷遊標是在哪個節點創建的,從而遍歷遊標時出錯
     結論:不要在mongod 或者複製集上層放置負載均衡器,讓驅動處理負載均衡和自動故障恢復

五, 遊標使用
     如果一個遊標已經遍歷完,則會自動關閉;如果沒有遍歷完,則需要手動調成close()方法,否則遊標將在服務器上存在10分鐘(默認值)後
     超時釋放,造成不必要的資源浪費。
     但是,如果不能遍歷完一個遊標,通常以爲着查詢條件太寬泛,更應該考慮的問題是如何將條件收緊

六, 關於查詢及索引
     1. 每一個查詢都必須要有對應的索引
     2. 儘量使用覆蓋索引 covered indexes (可以避免讀數據文件)
     3. 使用projection 來減少返回到客戶端的文檔的內容


七,關於寫入
    1. 在update 語句裏只包括需要更新的字段
    2. 儘可能使用批量插入來提升寫入性能
    3. 使用TTL 自動過期日誌類型的數據

 八, 關於文檔結構

 1. 防止使用太長的字段名(浪費空間)
 2. 防止使用太深的數組嵌套(超過2層操作比較複雜)
 3. 不使用中文,標點符號等非拉丁字母作爲字段名


 九,處理分頁問題--避免使用count()

 儘可能不要計算總頁數,特別是數據量大和查詢條件不能完整命中索引時。
 考慮以下場景: 假設集合總共有1000w 條數據,在沒有索引的情況下考慮以下查詢
 db.coll.find({x: 100}).limit(50)
 db.coll.count({x:100})
     1. 前者只需要遍歷前n條,直到50條隊伍x=100 的文檔即可結束
     2. 後者需要遍歷完1000w 條找到所有符合要求的文檔才能得到結果
  爲了計算總頁數而進行的count() 往往是拖慢頁面整體加載速度的原因


 10, 處理分頁問題--巧分頁
 避免使用skip/limit 形式的分頁,特別是數據量大的時候
 替代方案: 使用查詢條件+ 唯一排序條件
 例如:
   第一頁: db.posts.find({}).sort({_id:1}).limit(20);
   第二頁: db.posts.find({_id:{$gt:<第一頁最後一個_id>}}).sort({_id:1}).limit(20)
   第三頁: db.posts.find({_id:{$gt:<第二頁最後一個_id>}}).sort({_id:1}).limit(20)


 11,關於事務

 使用事務的原則:
 1. 無論何時,事務的使用總是能避免則避免;
 2. 模型設計先於會務,儘可能用模型設計規避事務
 3. 不要使用過大的事務(儘量控制在1000個文檔更新以內)
 4. 當必須是使用事務時,儘可能讓涉及事務的文檔分佈在同一分片上,這將有效地提高效率
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章