[英]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.