繁体   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