天天看點

MongoDB writeConcern原了解析

mongodb支援的writeconncern選項如下

w: <number>,資料寫入到number個節點才向用用戶端确認

{w: 0} 對用戶端的寫入不需要發送任何确認,适用于性能要求高,但不關注正确性的場景

{w: 1} 預設的writeconcern,資料寫入到primary就向用戶端發送确認

{w: "majority"} 資料寫入到副本集大多數成員後向用戶端發送确認,适用于對資料安全性要求比較高的場景,該選項會降低寫入性能

j: <boolean> ,寫入操作的journal持久化後才向用戶端确認

預設為"{j: false},如果要求primary寫入持久化了才向用戶端确認,則指定該選項為true

wtimeout: <millseconds>,寫入逾時時間,僅w的值大于1時有效。

當指定{w: }時,資料需要成功寫入number個節點才算成功,如果寫入過程中有節點故障,可能導緻這個條件一直不能滿足,進而一直不能向用戶端發送确認結果,針對這種情況,用戶端可設定wtimeout選項來指定逾時時間,當寫入過程持續超過該時間仍未結束,則認為寫入失敗。

{w: 1}、{j: true}等writeconcern選項很好了解,primary等待條件滿足發送确認;但{w: "majority"}則相對複雜些,需要确認資料成功寫入到大多數節點才算成功,而mongodb的複制是通過secondary不斷拉取oplog并重放來實作的,并不是primary主動将寫入同步給secondary,那麼primary是如何确認資料已成功寫入到大多數節點的?

MongoDB writeConcern原了解析

client向primary發起請求,指定writeconcern為{w: "majority"},primary收到請求,本地寫入并記錄寫請求到oplog,然後等待大多數節點都同步了這條/批oplog(secondary應用完oplog會向主報告最新進度)。

secondary上有單獨的線程,當oplog的最新時間戳發生更新時,就會向primary發送replsetupdateposition指令更新自己的oplog時間戳。

當primary發現有足夠多的節點oplog時間戳已經滿足條件了,向用戶端發送确認。

<a href="https://www.aliyun.com/product/mongodb">mongodb雲資料庫</a>

<a href="https://docs.mongodb.com/manual/reference/command/find/#dbcmd.find">find command</a>

<a href="https://docs.mongodb.com/manual/reference/write-concern/">writeconcern</a>

下一篇: 新的啟程