簡體   English   中英

使用w = 0的Mongodb更新保證

[英]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時,如果發生中斷,更新仍然可能會靜默消失,而中斷是在更新未同步到日志時發生的。

筆記:

  1. 最佳性能與最低保證耐用性之間的最佳平衡是j:1的寫入問題。 通過適當的設置,您可以將延遲減少到略超過10ms。
  2. 為了進一步減少延遲/更新,如果這些批量寫操作適用於您的用例,則可能值得一看。 以我的經驗,他們經常這樣做。 請先閱讀並嘗試,然后再取消該想法。
  3. 強烈建議不要使用w:0,j:0寫操作,以防您希望保證數據的持久性。 使用風險自負。 這種寫入問題僅用於“便宜”的數據,該數據很容易獲得,或者速度問題超出了對耐用性的需求。 大規模收集實時天氣數據就是一個例子–即使在此丟失一個或兩個數據點,系統仍然可以正常工作。 對於大多數應用,耐久性一個問題。 結論: 至少要使用w:1,j:1進行持久寫入。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM