數據庫連接
使用DDS時,可能(neng)會遇到(dao)因為(wei) Mongod/Mongos 連(lian)(lian)接(jie)數(shu)用滿了(le),導致客(ke)戶(hu)端無法連(lian)(lian)接(jie)的問題(ti)。在Mongod/Mongos的服務端,收到(dao)一(yi)個(ge)(ge)新的連(lian)(lian)接(jie)由一(yi)個(ge)(ge)單獨(du)的線程(cheng)來(lai)處(chu)理,每個(ge)(ge)線程(cheng)配置(zhi)了(le)1MB的棧空間,當(dang)網絡連(lian)(lian)接(jie)數(shu)太多時,過多的線程(cheng)會導致上下(xia)文(wen)切(qie)換(huan)開(kai)銷(xiao)變大(da),同(tong)時內存開(kai)銷(xiao)也會上漲。
- 客戶端連接數據庫的時候,要計算業務一共有多少個客戶端,每個客戶端配置的連接池大小是多少,總的連接數不要超過當前實例能承受的最大連接數的80%。
- 對于副本集,客戶端需要同時配置主備節點的IP地址, 對于集群,至少配置兩個mongos的IP地址。
- DDS默認提供rwuser用戶,使用rwuser用戶登錄時認證庫必須是admin。
可靠性
write concern設置(zhi)規則:對于關鍵業(ye)務(wu),write concern設置(zhi)為{w:n},n>0,數字越大,一致性實現更好,但性能(neng)較差。
- w:1表示實際寫入主節點完成返回。
- w:1,journal:true表示寫主節點和日志后返回。
- w:majority表示大多數備節點寫入后返回。
對于可靠性有較高要(yao)求的(de),建議采用3az部署的(de)集群。
性能相關
規范
- 業務程序禁止執行全表掃描的查詢。
- 執行查詢時,只選擇需要返回的字段,不需要的字段不要返回。從而減少網絡和進程處理的負載,修改數據時,只修改變化需要修改的字段,不要整個對象直接存儲全部修改。
- 避免使用not。DDS并不會對缺失的數據進行索引,因此not的查詢條件將會要求在一個結果集中掃描所有記錄。如果$not是唯一的查詢條件,會對集合執行全表掃描。
- 用and時把匹配最少結果的條件放在最前面,用or時把匹配最多結果的條件放在最前面。
- 單個實例中,數據庫的總的個數不要超過200個,總的集合個數不要超過500個。
- 業務上線前,一定要對數據庫進行性能壓測,評估業務峰值場景下,對數據庫的負載情況
- 禁止同時執行大量并發事務,且長時間不提交。
- 業務正式上線前, 所有的查詢類別,都應該先執行查詢計劃檢查查詢性能
建議:
- 每個連接在后臺都是由一個單獨線程處理,每個線程會分配1MB的棧內存。所以連接數不宜過多,否則會占用過多的內存。
- 使用連接池,避免頻繁的建立連接和斷開連接,否則會導致CPU過高。
- 減少磁盤讀寫:避免使用不必要的upsert命令,避免查詢不必要的數據。
- 優化數據分布:對數據進行分片,同時分散熱點數據,均衡地使用實例資源。
- 減少鎖沖突:避免對同一個Key,過頻繁地操作。
- 減少鎖等待:避免前臺創建索引。
注意:
開發過(guo)程中(zhong)對(dui)集(ji)合的每一個(ge)操作(zuo)都要通過(guo)執(zhi)(zhi)行explain()檢查其(qi)執(zhi)(zhi)行計劃,如:
db.T_DeviceData.find({"deviceId":"ae4b5769-896f"}).explain();
db.T_DeviceData.find({"deviceId":"77557c2-31b4"}).explain("executionStats");
對于查(cha)詢而言(yan),因為覆蓋查(cha)詢不需要讀取(qu)文檔,而是(shi)直接從索(suo)引(yin)中返回結果(guo),這樣的查(cha)詢性能好,所以(yi)盡(jin)可能使用索(suo)引(yin)覆蓋查(cha)詢。如果(guo)explain()的輸出顯示indexOnly字段為真,則(ze)說明(ming)這個查(cha)詢就被(bei)一(yi)個索(suo)引(yin)覆蓋。
執行計劃解析:
看執行時間:executionStats.executionStages.executionTimeMillisEstimate和executionStats.executionStages.inputStage. executionTimeMillisEstimate時間越短越好。
? executionStats.executionTimeMillis表示執行(xing)計劃選擇和執行(xing)的所(suo)有(you)時間。
? executionStats.executionStages.executionTimeMillisEstimate表示最優執(zhi)行(xing)(xing)計劃的(de)執(zhi)行(xing)(xing)完成時間。
? executionStats.executionStages.inputStage. executionTimeMillisEstimate表(biao)示最優執(zhi)行計劃下(xia)的子階段執(zhi)行完(wan)成時間。
看(kan)掃(sao)描條數(shu):三個條目數(shu)相同為(wei)最佳。
? executionStats. nReturned表示匹配(pei)查(cha)詢(xun)條件(jian)的文檔數。
? executionStats .totalKeysExamined表(biao)示索引(yin)掃描(miao)條(tiao)目數。
? executionStats .totalDocsExamined表示文檔掃描(miao)條(tiao)目數。
看(kan)Stage狀態(tai),性能較(jiao)好的Stage狀態(tai)組合(he)如下。
? Fetch+IDHACK
? Fetch+ixscan
? Limit+(Fetch+ixscan)
? PROJECTION+ixscan
表 狀態說明
| 狀態名稱 | 描述 |
|---|---|
| COLLSCAN | 全表掃描 |
| SORT | 內存中進行排序 |
| IDHACK | 根據_id進行查詢 |
| TEXT | 全文索引 |
| COUNTSCAN | 未用索引計數 |
| FETCH | 索引掃描 |
| LIMIT | 使用Limit限制返回數 |
| SUBPLA | 未用索引的$or查詢階段 |
| PROJECTION | 限定返回字段時stage的返回 |
| COUNT_SCAN | 使用索引計數 |
Cursor使用規則
如果cursor不使用了要立(li)即關閉。由(you)于cursor在10分鐘內不活動(dong),就會關閉,立(li)即手動(dong)關閉會節省(sheng)資源。
4.2版本分布式事務使用規則
- Spring Data MongoDB不支持事務報錯后重試機制,如果客戶端使用Spring Data Mongo作為連接MongoDB的客戶端,需要依照Spring Data Mongo的參考文件,使用Spring Retry進行事務的重試操作。
- 分布式事務操作數據的大小不能超過16MB。