writeConcern選項(xiàng)
MongoDB支持的WriteConncern選項(xiàng)如下
w: 數(shù)據(jù)寫入到number個節(jié)點(diǎn)才向用客戶端確認(rèn){w: 0} 對客戶端的寫入不需要發(fā)送任何確認(rèn),適用于性能要求高,但不關(guān)注正確性的場景{w: 1} 默認(rèn)的writeConcern,數(shù)據(jù)寫入到Primary就向客戶端發(fā)送確認(rèn){w: “majority”} 數(shù)據(jù)寫入到副本集大多數(shù)成員后向客戶端發(fā)送確認(rèn),適用于對數(shù)據(jù)安全性要求比較高的場景购撼,該選項(xiàng)會降低寫入性能
j: 寫入操作的journal持久化后才向客戶端確認(rèn)默認(rèn)為”{j: false},如果要求Primary寫入持久化了才向客戶端確認(rèn),則指定該選項(xiàng)為true
wtimeout: 寫入超時時間鞋怀,僅w的值大于1時有效双泪。當(dāng)指定{w: }時,數(shù)據(jù)需要成功寫入number個節(jié)點(diǎn)才算成功密似,如果寫入過程中有節(jié)點(diǎn)故障焙矛,可能導(dǎo)致這個條件一直不能滿足,從而一直不能向客戶端發(fā)送確認(rèn)結(jié)果残腌,針對這種情況村斟,客戶端可設(shè)置wtimeout選項(xiàng)來指定超時時間,當(dāng)寫入過程持續(xù)超過該時間仍未結(jié)束抛猫,則認(rèn)為寫入失敗蟆盹。
MongoDB journal與oplog區(qū)別
journal
journal 是 MongoDB 存儲引擎層的概念,目前 MongoDB主要支持 mmapv1闺金、wiredtiger逾滥、mongorocks 等存儲引擎,都支持配置journal掖看。
MongoDB 所有的數(shù)據(jù)寫入匣距、讀取最終都是調(diào)存儲引擎層的接口來存儲、讀取數(shù)據(jù)哎壳,journal 是存儲引擎存儲數(shù)據(jù)時的一種輔助機(jī)制毅待。
以wiredtiger 為例,如果不配置 journal归榕,寫入 wiredtiger 的數(shù)據(jù)尸红,并不會立即持久化存儲;而是每分鐘會做一次全量的checkpoint(storage.syncPeriodSecs配置項(xiàng)刹泄,默認(rèn)為1分鐘)外里,將所有的數(shù)據(jù)持久化。如果中間出現(xiàn)宕機(jī)特石,那么數(shù)據(jù)只能恢復(fù)到最近的一次checkpoint盅蝗,這樣最多可能丟掉1分鐘的數(shù)據(jù)。
所以建議「一定要開啟journal」姆蘸,開啟 journal 后墩莫,每次寫入會記錄一條操作日志(通過journal可以重新構(gòu)造出寫入的數(shù)據(jù))。這樣即使出現(xiàn)宕機(jī)逞敷,啟動時 Wiredtiger 會先將數(shù)據(jù)恢復(fù)到最近的一次checkpoint的點(diǎn)狂秦,然后重放后續(xù)的 journal 操作日志來恢復(fù)數(shù)據(jù)。
MongoDB 里的 journal 行為 主要由2個參數(shù)控制推捐,storage.journal.enabled 決定是否開啟journal裂问,storage.journal.commitInternalMs 決定 journal 刷盤的間隔,默認(rèn)為100ms,用戶也可以通過寫入時指定 writeConcern 為 {j: ture} 來每次寫入時都確保 journal 刷盤堪簿。
oplog
oplog 是 MongoDB 主從復(fù)制層面的一個概念痊乾,通過 oplog 來實(shí)現(xiàn)復(fù)制集節(jié)點(diǎn)間數(shù)據(jù)同步,客戶端將數(shù)據(jù)寫入到 Primary戴甩,Primary 寫入數(shù)據(jù)后會記錄一條 oplog符喝,Secondary 從 Primary(或其他 Secondary )拉取 oplog 并重放,來確保復(fù)制集里每個節(jié)點(diǎn)存儲相同的數(shù)據(jù)甜孤。
oplog 在 MongoDB 里是一個普通的 capped collection协饲,對于存儲引擎來說,oplog只是一部分普通的數(shù)據(jù)而已缴川。
MongoDB 的一次寫入
MongoDB 復(fù)制集里寫入一個文檔時茉稠,需要修改如下數(shù)據(jù)
1.將文檔數(shù)據(jù)寫入對應(yīng)的集合
2.更新集合的所有索引信息
3.寫入一條oplog用于同步
上面3個修改操作,需要確保要么都成功把夸,要么都失敗而线,不能出現(xiàn)部分成功的情況,否則如果數(shù)據(jù)寫入成功恋日,但索引寫入失敗膀篮,那么會出現(xiàn)某個數(shù)據(jù),通過全表掃描能讀取到岂膳,但通過索引就無法讀取
如果數(shù)據(jù)誓竿、索引都寫入成功,但 oplog 寫入不成功谈截,那么寫入操作就不能正常的同步到備節(jié)點(diǎn)筷屡,出現(xiàn)主備數(shù)據(jù)不一致的情況。