【问题标题】:Confirm basic understanding of MongoDB's acknowledged write concern确认对 MongoDB 公认的写入关注点的基本了解
【发布时间】:2014-08-18 17:09:33
【问题描述】:

在默认的“已确认”写入关注模式下使用 MongoDB(通过 PyMongo),如果我有一行写入数据库(例如,输出新集合的 mapReduce)后跟一行读取从数据库中,读取总是会看到写入的变化?

此外,对于所有比“已确认”更严格的写入关注点,即“已记录”和“已确认副本”,上述内容是否正确,但在“未确认”的情况下不正确?

【问题讨论】:

  • Map reduce 是一个不好的例子,因为它以原子方式写入输出集合
  • @Sammaye - 是的,但是考虑到“已确认”的写入问题,mapReduce 的(原子)写入是否总是发生在读取发生之前?更新的情况是否有所不同?
  • 不,这取决于,MongoDB 不知道您的读取正在等待该 MR,因此它将读取您查询时的内容,它不会等待有关写入的操作完成,除非它是单个文档,因为在 MongoDB 中每个文档都存在事务
  • @Sammaye - 好的,在这种情况下,给定第 1 行的写入和第 2 行的读取,我如何确保第 2 行看到第 1 行的写入?
  • 在同一个脚本中?如果我记得正确的 python 是同步的(与 JS 不同),它应该可以在公认的情况下工作,对不起,我没有意识到你在谈论一个程序脚本

标签: mongodb pymongo


【解决方案1】:

如果写入已被确认,则应该已将其写入内存,因此任何后续查询都应​​获取当前数据。如果您有副本集并允许从辅助节点读取,这将不起作用。

日志写入会写入磁盘上的日志文件,这样可以在电源/硬件故障等情况下保护您的数据。这不应该对一致性产生影响,只要数据在内存中,一致性就会受到影响。

写入关注点中的任何副本配置都将确保写入需要得到副本集中的大多数/所有节点的确认。仅当您从副本中读取数据或保护您的数据免受无法访问/死机的服务器的影响时,这才会有所作为。

【讨论】:

  • 小说明:副本集配置不需要大多数人确认写入。仅当写入关注点w 设置为大于副本集成员数量的一半或w=majority 时,才需要这样做。例如,您仍然可以使用 w=1 在副本集中执行仅主要确认的写入。
  • 我可以看到我的困惑来自哪里。 MongdoDB 文档在确认写入问题上的开头是:“收到确认写入问题后,mongod 会确认收到写入操作。”这意味着确认只是收到写入;这并不意味着客户端等待成功继续。但是,在说明图的标题中,文档说:“客户端等待确认成功或异常。”这更清楚 - 并且有些矛盾,即确认是成功/失败,而不仅仅是写的“收据”。
  • 注:我指的文档在这里:docs.mongodb.org/manual/core/write-concern/…
  • 如果您有w = 1, j = 0,读取将在确认之后看到写入(对于某些文档也可能在确认之前),但写入可能在提交到磁盘之前丢失。在w = 1, j = 1 中,一旦写入返回,数据将被提交到磁盘,并且如果 mongod 意外关闭,数据将持续存在。 j = 1 需要w > 0w = 0, j = 1 的行为类似于 w = 1, j = 1
【解决方案2】:

例如,在 WiredTiger 数据库引擎的情况下,内存中会有一个页面缓存,这些页面会根据内存压力定期从磁盘写入和读取。而且,在 MMAPV1 存储引擎的情况下,会有一个内存映射地址空间,对应于磁盘上的页面。现在,称为期刊的二级结构。日志是数据库处理的每一件事的日志 - 请注意日志也在内存中。

日志何时写入磁盘?

当应用程序通过 TCP 连接向mongodb 服务器请求某些内容时,服务器将处理该请求。它会将其写入内存页面。但是它们可能很长一段时间都不会写入磁盘,具体取决于内存压力。它还将更新请求到日志中。默认情况下,在MongoDB 驱动程序中,当我们发出数据库请求时,我们等待响应。说一个确认的插入/更新。但是我们不会等待日志被写入磁盘。表示 - 我们是否要等待此写入被服务器确认的值称为 w

w = 1 j = false

默认情况下,它设置为 11 表示,等待此服务器响应写入。默认情况下,j等于false,j代表journal,代表我们是否等待这个journal被写入磁盘,然后再继续。那么,这些默认值的含义是什么?好吧,这意味着当我们进行更新/插入时 - 我们实际上是在内存中进行操作,而不一定是在磁盘中进行操作。当然,这意味着它非常快。并且定期(每隔几秒钟)将日志写入磁盘。时间不会长,但是在这个漏洞窗口期间,当数据已经写入服务器的内存到页面中,但是日志还没有持久化到磁盘,如果服务器崩溃,我们可能会丢失数据。我们还必须意识到,作为一名程序员,仅仅因为写入返回良好并且成功写入内存。如果服务器随后崩溃,它可能永远不会保存到磁盘。这是否是问题取决于应用程序。对于某些应用程序,写入量大,记录的数据量很少,如果我们等待日志写入磁盘,我们可能会发现甚至很难跟上数据流,因为磁盘是每次写入都会比内存慢 100 倍,1000 倍。但是对于其他应用程序,我们可能会发现完全有必要等待它被记录并知道它已经被持久化到磁盘上,然后再继续。所以,这真的取决于我们。

wj 值一起称为写入关注点。它们可以在驱动程序、集合级别、数据库级别或客户端级别进行设置。

1 : 等待写入被确认 0:不等待写入被确认 TRUE:同步到日志 FALSE : 不同步到日志

w 的其他值也有一定的意义。使用w=1j=true,我们可以确保这些写入已持久化到磁盘。现在,如果写入已经写入日志,那么如果服务器崩溃,那么即使页面可能还没有写回磁盘,在恢复时,服务器可以查看磁盘上的日志 - mongod 处理并重新创建尚未持久化到页面的所有写入。因为,他们已经被写到日记里了。所以,这就是为什么这给了我们更高的安全性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多