通常,MongoDB会根据写入操作的次数,时间和其他因素,通过将 oplog 从主数据库传送到辅助数据库,来从主数据库异步复制到辅助数据库。
在描述WriteConcern选项时,MongoDB documentation声明“ ...主数据库等待,直到所需数量的辅助数据库确认已写入,然后返回写关注确认。这似乎表明,除“ w:1”以外的WriteConcern将以阻塞方式复制到副本集的至少某些成员,从而有可能避免日志传送。
我要回答的基本问题是:如果每个写入都使用“多数”的WriteCocnern,MongoDB是否将不得不使用日志传送?换句话说,使用“多数”的WriteCocnern还可以控制复制时间吗?
我想更好地了解MongoDB如何处理“多数”的WriteConcern。一些明显的选择:
如果使用选项1,则在大多数情况下(假设等距放置等距),所有所有次级将在写入完成时就已经接受了写操作,并且可能性很高(尽管不能保证) all 所有辅助语言都将应用它。如果为true,则此行为启用了一些用例,这些用例需要比典型的异步复制过程更快地将其反映在Secondaries上。
显然,“多数”的WriteConcern会导致性能下降,但这对于某些特定的用例来说是可以接受的,在这种特定的用例中,读取操作可能针对次要对象(例如,“最近”的ReadPreference)并且需要更新的数据。
答案 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。
写入多数通常用于:
这些要点假定写入多数被确认,并且客户端已收到确认。可能存在多种不同的故障情况(对于需要处理不可靠网络的分布式系统,这是预期的情况),但这不在本讨论范围之内。