[英]Mongodb update guarantee using w=0
我有一個很大的集合,其中包含超過半百萬的文檔,我需要不斷對其進行更新。 為此,我的第一種方法是使用w=1
來確保寫入結果,這會導致大量延遲。
collection.update(
{'_id': _id},
{'$set': data},
w=1
)
因此,我決定在更新方法中使用w=0
,現在性能顯着提高了。
由於我過去對mongodb的痛苦經歷,所以我不確定w=0
時是否可以保證所有更新。 我的問題是,是否保證使用w=0
進行更新?
編輯 :另外,我想知道它是如何工作的? 它是否創建內部隊列並異步異步執行更新? 我看到使用mongostat
,即使python腳本退出后, mongostat
處理一些更新。 還是更新是即時的?
編輯2 :根據Sammaye link的回答,任何錯誤都可能導致靜默故障。 但是,如果提供大量更新,會發生什么? 某些更新會失敗嗎?
不, w=0
可能會失敗,僅是:
http://docs.mongodb.org/manual/core/write-concern/#unacknowledged
未確認類似於被忽略的錯誤。 但是,驅動程序將盡可能嘗試接收和處理網絡錯誤。
這意味着寫操作可能會在MongoDB本身內靜默失敗。
如果您要特別保證,則不可靠。 歸根結底,如果您希望接觸數據庫並從中獲得確認,則必須等待物理定律。
w:0
保證更新嗎? 正如Sammaye所寫:否,因為可能存在將數據僅應用於內存中數據而尚未寫入日志的時間。 因此,如果在這段時間內發生斷電(默認情況下,斷電取決於配置)介於10( j:1
,並且日志和數據文件位於單獨的塊設備上)之間,並且默認情況下為100ms,則更新可能會丟失。
請記住,非法更新(例如更改文檔的_id
)將自動失敗。
w:0
? 假設沒有網絡錯誤,驅動程序將使用w:0
將操作發送到mongod / mongos實例后立即返回。 但是,讓我們進一步了解一下引擎蓋下發生的情況。
接下來,更新將由查詢優化器處理,並應用於內存中的數據集。 成功執行該操作后,現在將返回寫關注為w:1
的寫操作。 所應用的操作將在每個commitIntervalMs同步到日志,該日志將被寫關注j:1
除以3。 如果您有{j:1}
的寫問題,驅動程序將在操作成功存儲在日志中后返回。 請注意,在某些極端情況下,如果現在發生非常“適時”的定時中斷,則寫入日志的數據將不會應用於副本集成員。
默認情況下,每個syncPeriodSecs ,日記中的數據將應用於實際數據文件。
關於您在mongostat中看到的內容:它的粒度不是很高,您很可能會過去進行過操作。 如前所述,內存中數據的更新不是即時的,因為更新首先必須通過查詢優化器。
w:0
嗎? 通常,可以肯定地說“不”。 這就是為什么:
對於每個連接,都會分配一定數量的RAM。 如果負載如此之高,以致mongo無法再分配任何RAM,則將出現連接錯誤-無論未考慮寫入問題,都將處理連接錯誤。
此外,對內存中數據進行更新的應用非常快-最有可能仍比我們談論負載峰值時要快。 如果mongod完全過載(例如,在具有旋轉磁盤的獨立mongod上150k更新一秒鍾),當然,即使從底層操作系統的持久性角度來看,即使這樣通常也會發生問題。
但是,當寫關注點為w:0,j:0
時,如果發生中斷,更新仍然可能會靜默消失,而中斷是在更新未同步到日志時發生的。
j:1
的寫入問題。 通過適當的設置,您可以將延遲減少到略超過10ms。 w:0,j:0
寫操作,以防您希望保證數據的持久性。 使用風險自負。 這種寫入問題僅用於“便宜”的數據,該數據很容易獲得,或者速度問題超出了對耐用性的需求。 大規模收集實時天氣數據就是一個例子–即使在此丟失一個或兩個數據點,系統仍然可以正常工作。 對於大多數應用,耐久性是一個問題。 結論: 至少要使用w:1,j:1
進行持久寫入。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.