故障處理--mongos count不準

故障現象

業務上並無對這個表的delete操作,通過mongostat可以查看。但是mongos對一個表進行count操作時,發現它的計數結果會慢慢變少,然後突然有一個大幅增長,隨後又逐漸減少,現象如下

mongos> db.ebay_us_detail.count()
154462481
mongos> db.ebay_us_detail.count()
154462463
mongos> db.ebay_us_detail.find().count()
154686915
mongos> db.ebay_us_detail.find().count()
154686850
mongos> db.ebay_us_detail.find().count()
154686769
mongos> db.ebay_us_detail.find().count()
154873243
mongos> db.ebay_us_detail.find().count()
154873088

故障原因

我查了下oplog,發現某個分片上存在這麼一個操作,標記爲d,即delete操作

udb-dm5jbg:PRIMARY> db.oplog.rs.findOne({"ns":"ebay.ebay_us_detail","op":"d"})
{
"ts" : Timestamp(1514210377, 16),
"t" : NumberLong(2),
"h" : NumberLong("-6024794084103163788"),
"v" : 2,
"op" : "d",
"ns" : "ebay.ebay_us_detail",
"fromMigrate" : true,
"o" : {
"_id" : ObjectId("5a3a5f1d71c2475fee1f26b6")
}
}

通過這條記錄大概猜測後臺正在move chunk,通過mongod日誌確認後臺確實正在針對該表進行move chunk,猜測這是一個bug

1  通常情況下,一個分片上的數據屬於該分片上的chunk

2  然而在move chunk過程中,如果move chunk沒有完成,數據雖然還在這個分片上,但是這個chunk已經不屬於這個分片了

3 這時在這個分片上執行count時,只會統計在這個分片上並且屬於這個分片的chunk的記錄數,不會統計在這個分片上但不屬於這個分片的chunk上的記錄數,所以count操作會不準,出現上述的故障現象,慢慢減少,突然又增加

4 如果是非count操作,普通的query肯定無法容忍這種錯誤的,所以非count操作會額外去查看在這個分片上,需要的chunk確實屬於該分片;如果該chunk不屬於該分片,則操作會被阻塞,直到move chunk完成。所以move chunk時的性能會急劇下降,但是確保數據正確

5 count爲啥不去額外統計不屬於這個分片的chunk呢,這既是一個bug,也是一種折中的考慮。可以認爲一般業務並不需要非常精準的count結果,但是count速度比較重要,不去額外統計的話,就可以使用覆蓋索引,而檢查某個記錄是否屬於一個有效的chunk這種操作是個比較費時的操作,無法使用索引

改進措施

1 修改源碼,count統計方法和普通query一樣,即正確性第一,效率第二

2 設置負載均衡窗口期,在窗口期內業務不要指望準確的count操作

參考

https://jira.mongodb.org/browse/SERVER-8405


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