Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用w=0的Mongodb更新保证_Mongodb_Pymongo_Mongodb Query - Fatal编程技术网

使用w=0的Mongodb更新保证

使用w=0的Mongodb更新保证,mongodb,pymongo,mongodb-query,Mongodb,Pymongo,Mongodb Query,我收集了50多万份文档,需要不断更新。为了实现这一点,我的第一种方法是使用w=1来确保写入结果,这会导致大量延迟 collection.update( {'_id': _id}, {'$set': data}, w=1 ) 所以我决定在我的更新方法中使用w=0,现在性能明显提高了 由于我过去对mongodb的痛苦经历,我不确定当w=0时是否所有的更新都能得到保证。我的问题是,是否保证使用w=0进行更新 编辑:还有,我想知道它是如何工作的?它是否创建内部队列并逐个异步执行

我收集了50多万份文档,需要不断更新。为了实现这一点,我的第一种方法是使用w=1来确保写入结果,这会导致大量延迟

collection.update(
    {'_id': _id},
    {'$set': data},
    w=1
)
所以我决定在我的更新方法中使用w=0,现在性能明显提高了

由于我过去对mongodb的痛苦经历,我不确定当w=0时是否所有的更新都能得到保证。我的问题是,是否保证使用w=0进行更新

编辑:还有,我想知道它是如何工作的?它是否创建内部队列并逐个异步执行更新?我在使用mongostat时看到,即使在python脚本退出之后,仍在处理一些更新。或者更新是即时的

编辑2:根据Sammaye的回答,任何错误都可能导致无声故障。但是如果有大量的更新,会发生什么呢?某些更新会失败吗?

否,w=0可能会失败,它只是:

未确认类似于忽略的错误;但是,如果可能,驱动程序将尝试接收和处理网络错误

这意味着在MongoDB本身中,写操作可能会无声地失败

如果你想具体保证,这是不可靠的。在一天结束时,如果您希望接触数据库并从中获得确认,那么您必须等待,物理定律。

w:0是否保证更新? 正如Sammaye所写:不,因为可能有一段时间数据只应用于内存中的数据,而没有写入日志。因此,如果在此期间发生中断,根据配置,j:1和日志以及数据文件在单独块设备上的时间介于10和100毫秒之间,默认情况下,您的更新可能会丢失

请记住,非法更新(如更改文档的_id)将自动失败

更新如何与w:0一起工作? 假设没有网络错误,驱动程序将在将操作发送到带有w:0的mongod/mongos实例后立即返回。但让我们看得更远一点,让你了解引擎盖下发生了什么

接下来,查询优化器将处理更新并将其应用于内存中的数据集。成功应用该操作后,现在将返回写关注点为w:1的写操作。应用的操作将同步到日志,每一次,日志除以3,写入关注点j:1。如果您有一个写问题{j:1},那么在操作成功存储在日志中后,驱动程序将返回。请注意,仍有一些边缘情况,其中记录到日志的数据不会应用于副本集成员,以防现在发生非常及时的停机

默认情况下,日志中的数据将应用于实际数据文件

关于您在mongostat中看到的情况:它的粒度不是很高,您很可能会看到过去发生的操作。如前所述,对内存中数据的更新不是即时的,因为更新首先必须通过查询优化器

重负载是否会使更新在w:0的情况下以静默方式失败? 一般来说,说“不”是安全的。原因如下:

对于每个连接,都会分配一定数量的RAM。如果负载太高,mongo无法分配任何进一步的RAM,则会出现连接错误——不管写问题如何,都会处理该错误,未确认的写操作除外

此外,对内存中数据的更新应用速度非常快——很可能比我们讨论的负载峰值时的更新速度还要快。如果mongod完全过载,例如在具有旋转磁盘的独立mongod上每秒更新150k,当然可能会出现问题,尽管从持久性的角度来看,底层操作系统通常会利用这些问题

但是,当写问题为w:0、j:0且在更新未同步到日志时发生中断时,如果发生中断,更新仍可能会自动消失

笔记: 最大性能和最小保证耐久性之间的最佳平衡是j:1的一个写关注点。通过适当的设置,您可以将延迟降低到略高于10ms。 为了进一步减少延迟/更新,如果这些适用于您的用例,那么可能值得一看。根据我的经验,他们经常这样做。在放弃这个想法之前,请先阅读并尝试一下。 非常不鼓励使用w:0、j:0执行写操作,以防您希望在数据持久性方面得到任何保证。使用一个新的方法来避免你自己的风险。这种写关注点只适用于便宜的数据,这些数据很容易重新获取,或者速度关注点超过了持久性的需要。大规模收集实时天气数据就是一个例子——即使有一两个数据点到处缺失,该系统仍能工作。对于大多数应用,耐久性是一个值得关注的问题。结论:至少使用w:1,j:1进行持久写入。
@Sammae没有错误,可以吗
l如果负载过大?@Dewsworld因为它应该能够捕获和处理网络错误,如果MongoDB中没有错误,包括索引错误等,那么可能性很小,可能也很小small@Dewsworld至于内部工作:它将在作业队列中工作,直到完成w:1,同步间隔大大缩短。你有参考资料吗?@Sammaye:我想这是在M102中提到的。一个简单的测试就证明了这一点:在默认设置和w:1的情况下,每一次写入都应该花费大约30秒的时间。这看起来确实很奇怪,因为它会使fsync队列变得无用,我已经完成了这一过程,但我不记得在另一方面提到过,这可能是我的一个误会——有时不以英语为母语会让人感到痛苦。文档中使用的术语可能也指将数据应用到内存视图中。我自己的理解是,w:1说它是在内存中完成的,然后同步设置保持不变,只是同步,唯一改变磁盘时间的是j:1如果这是多线程数据摄取,你应该看不出有什么区别。请注意,当您看到mongostat中不再发生插入时,插入就完成了,而不是当您的客户端返回时。