主从同步有哪些坑?
这里的主从同步涉及到主机和从机都提供服务的情况。
- 主从数据不一致
- (1)主从库间的命令复制是异步进行的
- (2)从库会滞后执行同步命令
- 从库正在执行其他复杂度高的命令,如 O(n)的集合操作
- 主从库间的网络可能会有传输延迟
- 解决办法
- 尽可能网络环境延迟低
- 上面的 offset 差值来判断主从延迟问题
- 读取过期数据
- EXPIRE 和 PEXPIRE:它们给数据设置的是从命令执行时开始计算的存活时间;
- EXPIREAT 和 PEXPIREAT:它们会直接把数据的过期时间设置为具体的一个时间点。
不合理配置项导致的服务挂掉
这里涉及到的配置项有两个,分别是 protected-mode 和 cluster-node-timeout。
- protected-mode 配置项
这个配置项的作用是限定哨兵实例能否被其他服务器访问。当这个配置项设置为 yes 时,哨兵实例只能在部署的服务器本地进行访问。当设置为 no 时,其他服务器也可以访问这个哨兵实例。
正因为这样,如果 protected-mode 被设置为 yes,而其余哨兵实例部署在其它服务器,那么,这些哨兵实例间就无法通信。当主库故障时,哨兵无法判断主库下线,也无法进行主从切换,最终 Redis 服务不可用。
所以,我们在应用主从集群时,要注意将 protected-mode 配置项设置为 no,并且将 bind 配置项设置为其它哨兵实例的 IP 地址。这样一来,只有在 bind 中设置了 IP 地址的哨兵,才可以访问当前实例,既保证了实例间能够通信进行主从切换,也保证了哨兵的安全性。
我们来看一个简单的小例子。如果设置了下面的配置项,那么,部署在 192.168.10.3/4/5 这三台服务器上的哨兵实例就可以相互通信,执行主从切换。
protected-mode no
bind 192.168.10.3 192.168.10.4 192.168.10.5- cluster-node-timeout 配置项
这个配置项设置了 Redis Cluster 中实例响应心跳消息的超时时间。
当我们在 Redis Cluster 集群中为每个实例配置了“一主一从”模式时,如果主实例发生故障,从实例会切换为主实例,受网络延迟和切换操作执行的影响,切换时间可能较长,就会导致实例的心跳超时(超出 cluster-node-timeout)。实例超时后,就会被 Redis Cluster 判断为异常。而 Redis Cluster 正常运行的条件就是,有半数以上的实例都能正常运行。
所以,如果执行主从切换的实例超过半数,而主从切换时间又过长的话,就可能有半数以上的实例心跳超时,从而可能导致整个集群挂掉。所以,我建议你将 cluster-node-timeout 调大些(例如 10 到 20 秒)。