【问题标题】:Will MongoDb lock read operations on secondary when inserting with write-concern: majority?MongoDb 在使用 write-concern 插入时是否会在辅助上锁定读取操作:多数?
【发布时间】:2014-03-13 17:34:30
【问题描述】:
MongoDb的当前配置是:
- 一个主节点(A),两个辅助节点(B 和 C),一个副本集的所有部分
- 向主节点插入是通过 write-concern:majority 完成的
- 从副本集读取时,读取首选项设置为“最近”
场景:
- 一个插入被触发,这意味着它只有在它传播到大多数副本集成员之后才会成功
- 在写入操作返回之前,应用程序无法从主数据库读取 (reference)
- 由于写入关注点设置为“多数”,写入操作只有在传播到至少一个辅助 (B) 实例后才会返回,在我们的示例中设置了 3 个成员
- 这意味着辅助 (B) 也被锁定以供读取,因为它正在复制(根据 this)
问题是,由于应用程序设置为从最近的实例读取,假设最近的实例是另一个辅助实例 (C),如果在写入操作时通过了读取请求其他 2 个实例仍在进行中,是否允许或阻止读取。如果允许,我该如何防止?
【问题讨论】:
标签:
mongodb
concurrency
replication
replicaset
【解决方案1】:
写关注并不是这样的。 B 和 C 都将处理写入,并在执行此操作时采用相同的 db 级写入锁,无论您是否发送带有任何写入问题的 getLastError。当锁在 C 上时,C 上的读取将阻塞。
写关注实际上只针对客户端,它使客户端等待直到满足条件(在您的情况下,大多数副本已应用写)。它不会改变辅助节点复制优先级的方式。
【解决方案2】:
如果读取请求在其他 2 个实例上仍在进行写入操作时通过,读取是被允许还是被阻止
嗯,你自己想通了。如果它在最近的组中,您可以从“C”读取(陈旧数据)
如何预防?
读取偏好可以由您的驱动程序、数据库级别、集合级别或操作级别全局应用(对于写入关注点或多或少地应用相同)。如果对于该特定操作,您不会遇到陈旧数据,则可以在发出插入后将该特定查询的读取首选项覆盖为primary(请注意,在这种情况下,插入操作可以设置为写入关注{w:1}