mongodb副本集数据同步的踩坑

一、故事

最近随着搞活动比较频繁导致数据库出现了波动,后端日志总是报数据库连接和读取的问题。由于我设置的是读写分离(伪的,通过设置副本集的读取策略实现的,设置的db.getMongo().setReadPref(),共有如下几个参数:

One of the following read preference modes: primaryprimaryPreferredsecondarysecondaryPreferred, or nearest.详细的介绍可以进链接了解。我们采用的是secondaryPreferred,优先读取second节点,只有从节点不可读是才会去master节点读取)。当然最好的读写分离需要使用shared分片集实现,我们也已经切换称分片集了,这里主要是为了本篇博客将要介绍的知识点,所以会以副本集进行讲解。继续故事啊,看监控数据库状态没有什么问题啊,查看副本集状态的时候发现了点猫腻:rs.status(),发现有一个节点的syncingTo竟然不是master,而是另外的一个secondary节点,这就很奇怪了,其他的都是master的地址。都知道mongodb之间同步数据是通过oplog的回访实现的,和mysql的binlog很像,于是带着这个疑问就到官网查看一番。

二、官网游历

直达车:https://docs.mongodb.com/manual/reference/method/js-replication/、https://docs.mongodb.com/manual/tutorial/manage-chained-replication/

先来看一下官网的描述:

Starting in version 2.0, MongoDB supports chained replication. A chained replication occurs when a secondarymember replicates from another secondary member instead of from the primary. This might be the case, for example, if a secondary selects its replication target based on ping time and if the closest member is another secondary.

Chained replication can reduce load on the primary. But chained replication can also result in increased replication lag, depending on the topology of the network.

You can use the settings.chainingAllowed setting in Replica Set Configuration to disable chained replication for situations where chained replication is causing lag.

从mongodb2.0开始支持链式复制,并且默认是开启的,是根据second节点之间的ping time和网络距离进行选择那个second作为数据的同步节点,链式复制的优点:可以减少master的资源消耗,减少负载。缺点:节点之间同步数据本来就不可避免会有数据的延迟,执行链式复制的过程会使这个时间增大,该second节点的数据就会比其他的更落后于master,所以在读取数据的时候就会有一些问题,比如读取数据读不到,后端服务就会抛错,导致用户能感知到,非常不好,当然可以通过降低数据延迟来缓解,保证节点见的网络带宽流畅、io等。

三、方案

了解了副本集之间的复制方式,接下来就开始着手解决这个数据延迟的问题,从官网来看有两种方式:使用rs.syncFrom()设置同步源、禁用掉链式复制

1、rs.syncFrom

官网对于这个命令的介绍:

Provides a wrapper around the replSetSyncFrom, which allows administrators to temporarily override the default sync target for the current member. Specify the name of the member you want to replicate from in the form of [hostname]:[port].

Changed in version 3.2: MongoDB 3.2 replica set members with vote cannot sync from members with 0votes

>rs.syncFrom("myHost:27017");

2、禁用掉链式复制

Disable Chained Replication

To disable chained replication, set the settings.chainingAllowed field in Replica Set Configuration to false.

If chained replication is disabled, you still can use replSetSyncFrom to specify that a secondary replicates from another secondary. But that configuration will last only until the secondary recalculates which member to sync from.(禁用了链式复制以后,还是可以通过replSetSyncFrom指定复制源为second,但是必须要有投票权

You can use the following sequence of commands to set settings.chainingAllowed to false:

cfg = rs.config()

cfg.settings.chainingAllowed = false
rs.reconfig(cfg)

Re-enable Chained Replication

To re-enable chained replication, set settings.chainingAllowed to true. You can use the following sequence of commands:

cfg = rs.config()
cfg.settings.chainingAllowed = true
rs.reconfig(cfg)

四、一些思考

排查问题时使用的几个命令:

mongostat

mongotop

rs.status()

rs.printSlaveReplicationInfo()  打印数据同步延迟信息

rs.printReplicationInfo()  打印oplog信息

具体遇到数据同步延迟的,需要具体分析当时的情况,不能盲目的修改。首先考虑节点服务器的负载情况和当时的网络环境是否正常,有的时候可能是网络环境导致的,排除这些原因后,再去考虑修改同步源。这样要做好读写分离,否则master的压力会非常大。如果master的压力太大就要做一些处理,比如切换一下msater升级资源或使用replSetSyncFrom切换同步源到second上。

参考:

https://www.cnblogs.com/cuishuai/p/8034851.html

https://docs.mongodb.com/manual/tutorial/manage-chained-replication/

https://docs.mongodb.com/manual/reference/method/rs.syncFrom/

原文地址:https://www.cnblogs.com/cuishuai/p/9773232.html