zl程序教程

您现在的位置是:首页 >  数据库

当前栏目

Redis 主从复制需要注意的问题(2)

Redis 需要 注意 主从复制 问题
2023-09-14 09:01:47 时间

规避全量复制


全量复制是一个非常消耗资源的操作,因此如何规避全量复制是需要重点关注的运维点。 下面我们对需要进行全量复制的场景
逐个分析。

· 第一次建立复制: 由于是第一次建立复制, 从节点不包含任何主节点数据, 因此必须进行全量复制才能完成数据同步。 对于这种情况全量复制无法避免。 当对数据量较大且流量较高的主节点添加从节点时, 建议在低峰时进行操作, 或者尽量规避使用大数据量的Redis节点。

· 节点运行ID不匹配: 当主从复制关系建立后, 从节点会保存主节点的运行ID, 如果此时主节点因故障重启, 那么它的运行ID会改变, 从节点发现主节点运行ID不匹配时, 会认为自己复制的是一个新的主节点从而进行全量复制。 对于这种情况应该从架构上规避, 比如提供故障转移功能。 当主节点发生故障后, 手动提升从节点为主节点或者采用支持自动故障转移的哨兵或集群方案。

· 复制积压缓冲区不足: 当主从节点网络中断后, 从节点再次连上主节点时会发送psync{offset}{runId}命令请求部分复制, 如果请求的偏移量不在主节点的积压缓冲区内, 则无法提供给从节点数据, 因此部分复制会退化为全量复制。 针对这种情况需要根据网络中断时长, 写命令数据量分析出合理的积压缓冲区大小。 网络中断一般有闪断、 机房割接、 网络分区等情况。 这时网络中断的时长一般在分钟级(net_break_time) 。 写命令数据量可以统计高峰期主节点每秒info replication的master_repl_offset差值获取( write_size_per_minute) 。 积压缓冲区默认为1MB, 对于大流量场景显然不够, 这时需要增大积压缓冲区, 保证
repl_backlog_size>net_break_time*write_size_per_minute, 从而避免因复制积压缓冲区不足造成的全量复制

Redis为复制积压缓冲区设置的默认大小为1MB,如果主服务器需要执行大量写命令,又或者主从服务器断线后重连接所需的时间比较长,那么这个大小也许并不合适。如果复制积压缓冲区的大小设置得不恰当,那么PSYNC命令的复制重同步模式就不能正常发挥作用,因此,正确估算和设置复制积压缓冲区的大小非常重要。复制积压缓冲区的最小大小可以根据公式second*write_size_per_second来估算:

  • 其中second为从服务器断线后重新连接上主服务器所需的平均时间(以秒计算)
  • 而write_size_per_second则是主服务器平均每秒产生的写命令数据量(协议格式的写命令的长度总和)

例如,如果主服务器平均每秒产生1 MB的写数据,而从服务器断线之后平均要5秒才能重新连接上主服务器,那么复制积压缓冲区的大小就不能低于5MB。为了安全起见,可以将复制积压缓冲区的大小设为2*second*write_size_per_second,这样可以保证绝大部分断线情况都能用部分重同步来处理。至于复制积压缓冲区大小的修改方法,可以参考配置文件中关于repl-backlog-size选项的说明。

 

注意,repl_backlog只针对部分复制(Partial Replication),而非全量复制。

本文内容基于redis-5.0.5(截至2019/6/6的最新版本),本文深入介绍REdis主从复制的部分复制核心要素repl_backlog,与其相关的配置直接影响主从间的稳定性,对提升集群的稳定性十分重要。

注意REdis的主节点把所有从节点也当作一个Client看待,正常的数据同步并不涉及repl_backlog。当从节点断开重连,这个时候repl_backlog的作用就体现出来了。截至到5.0.5版本,从节点重启用不上repl_backlog,原因是从节点没有保存repl_backlog的信息,无法实现部分同步,但可少量改动REdis源代码,实现从节点重启后的部分复制。

正常情况下,主节点会往从节点连接缓冲区写一份数据,同时往repl_backlog也写一份数据,所有从节点共享同一份repl_backlog,因此可以考虑repl_backlog配置大一点,以容忍从节点更长时间失联。

 

 

规避复制风暴


复制风暴是指大量从节点对同一主节点或者对同一台机器的多个主节点短时间内发起全量复制的过程。 复制风暴对发起复制的主节点或者机器造成大量开销, 导致CPU、 内存、 带宽消耗。 因此我们应该分析出复制风暴发生的场景, 提前采用合理的方式规避。 规避方式有如下几个
 

单主节点复制风暴
单主节点复制风暴一般发生在主节点挂载多个从节点的场景。 当主节点重启恢复后, 从节点会发起全量复制流程, 这时主节点就会为从节点创建RDB快照, 如果在快照创建完毕之前, 有多个从节点都尝试与主节点进行全量同步, 那么其他从节点将共享这份RDB快照。 这点Redis做了优化, 有效避免了创建多个快照。 但是, 同时向多个从节点发送RDB快照, 可能使主节点的网络带宽消耗严重, 造成主节点的延迟变大, 极端情况会发生主从节点连接断开, 导致复制失败。
解决方案首先可以减少主节点(master) 挂载从节点(slave) 的数量,或者采用树状复制结构, 加入中间层从节点用来保护主节点, 如图所示。(采用树状结构降低多个从节点对主节点的消耗)

单机器复制风暴
由于Redis的单线程架构, 通常单台机器会部署多个Redis实例。 当一台机器(machine) 上同时部署多个主节点(master) 时, 如图所示。
                    

如果这台机器出现故障或网络长时间中断, 当它重启恢复后, 会有大量从节点(slave) 针对这台机器的主节点进行全量复制, 会造成当前机器网络带宽耗尽。如何避免? 方法如下:

·应该把主节点尽量分散在多台机器上, 避免在单台机器上部署过多的主节点。
·当主节点所在机器故障后提供故障转移机制, 避免机器恢复后进行密集的全量复制。