MongoDB WriteConcern对复制的影响

时间:2019-01-22 02:02:51

标签: mongodb

通常,MongoDB会根据写入操作的次数,时间和其他因素,通过将 oplog 从主数据库传送到辅助数据库,来从主数据库异步复制到辅助数据库。

在描述WriteConcern选项时,MongoDB documentation声明“ ...主数据库等待,直到所需数量的辅助数据库确认已写入,然后返回写关注确认。这似乎表明,除“ w:1”以外的WriteConcern将以阻塞方式复制到副本集的至少某些成员,从而有可能避免日志传送。

我要回答的基本问题是:如果每个写入都使用“多数”的WriteCocnern,MongoDB是否将不得不使用日志传送?换句话说,使用“多数”的WriteCocnern还可以控制复制时间吗?

我想更好地了解MongoDB如何处理“多数”的WriteConcern。一些明显的选择:

  1. 主节点向每个辅助节点发送写请求,并阻塞线程,直到大多数响应并确认为止 或
  2. 主要预选择次要对象,并仅将请求发送给那些次要对象,从而阻塞线程,直到所有选定的次要对象均以确认响应 或
  3. 比这两个选项都要聪明

如果使用选项1,则在大多数情况下(假设等距放置等距),所有所有次级将在写入完成时就已经接受了写操作,并且可能性很高(尽管不能保证) all 所有辅助语言都将应用它。如果为true,则此行为启用了一些用例,这些用例需要比典型的异步复制过程更快地将其反映在Secondaries上。

显然,“多数”的WriteConcern会导致性能下降,但这对于某些特定的用例来说是可以接受的,在这种特定的用例中,读取操作可能针对次要对象(例如,“最近”的ReadPreference)并且需要更新的数据。

1 个答案:

答案 0 :(得分:0)

  

如果每个写入都使用“多数”的WriteConcern,MongoDB是否将不得不使用日志传送?

MongoDB中的复制使用了oplog。这是主节点(唯一接受写入的节点)上所有操作的记录。

次要节点不是将操作日志推入辅助节点,而是在主节点的操作日志上长拉。如果允许复制链接(默认设置),则辅助节点也可以从另一个辅助节点提取操作日志。因此,从MongoDB 4.0开始,您发布的场景1和2在MongoDB复制中是不现实的。

有关复制过程的详细信息,请参见MongoDB Github Wiki页面:Replication Internals

引用与您的问题有关的部分:

  

如果命令包含写入问题,则该命令将仅阻塞其自己的线程,直到将其生成的操作日志条目复制到所请求的节点数为止。主数据库跟踪次数据库如何知道何时返回。写关注点可以指定要等待的节点数或多数。

换句话说,辅助数据库不断向主数据库报告其将oplog应用于其自己的数据集的距离。由于主服务器知道写入发生的时间戳,因此,一旦辅助服务器应用了该时间戳,它就可以知道写入已传播到该辅助服务器。为了满足写问题,主数据库仅等待直到确定数量的辅助数据库已应用写入时间戳。

请注意,只有指定写关注点的线程正在等待此确认。由于完全没有等待,所有其他线程都不会被阻塞。

关于您的其他问题:

  

显然,“多数”的WriteConcern会导致性能下降,但这对于某些特定的用例来说是可以接受的,在这种特定的用例中,读取操作可能针对次要对象(例如,“最近”的ReadPreference)并且需要更新的数据。

要实现您所描述的内容,您需要将读写问题组合在一起。有关此主题的更多详细信息,请参见 Causal Consistency and Read and Write Concerns

写入多数通常用于:

  • 确保在发生主要故障时不会回滚写入。
  • 确保应用程序的写入速度不会太快,以至于副本集的已配置硬件无法应对流量;即它可以充当背压机制。
  • 结合read concern,为客户提供不同级别的一致性保证。

这些要点假定写入多数被确认,并且客户端已收到确认。可能存在多种不同的故障情况(对于需要处理不可靠网络的分布式系统,这是预期的情况),但这不在本讨论范围之内。