1、主从复制过程
Redis 主从复制分为全量同步和增量同步
Redis 的主从同步是非阻塞的,即同步过程不会影响主服务器的正常访问.
1.1、全量复制过程
![图片[1]-主从复制优化-李佳程的个人主页](http://www.lijiach.com/wp-content/uploads/2022/11/image-186.png)
- 主从节点建立连接,验证身份后,从节点向主节点发送PSYNC(2.8版本之前是SYNC)命令
- 主节点向从节点发送FULLRESYNC命令,包括runID和offset
- 从节点保存主节点信息
- 主节点执行BGSAVE保存RDB文件,同时记录新的记录到buffer中
- 主节点发送RDB文件给从节点
- 主节点将新收到buffer中的记录发送至从节点
- 从节点删除本机的旧数据
- 从节点加载RDB
- 从节点同步主节点的buffer信息
1.2、增量复制过程
![图片[2]-主从复制优化-李佳程的个人主页](http://www.lijiach.com/wp-content/uploads/2022/11/image-187.png)
在主从复制首次完成全量同步之后再次需要同步时,从服务器只要发送当前的offset位置(类似于MySQL binlog的位置)给主服务器,然后主服务器根据相应的位置将之后的数据(包括写在缓冲区的积压数据)发送给从服务器,再次将其保存到从节点内存即可。
即首次全量复制,之后的复制基本增量复制实现
1.3、主从同步完整过程
![图片[3]-主从复制优化-李佳程的个人主页](http://www.lijiach.com/wp-content/uploads/2022/11/image-188.png)
- slave 发起连接master,验证通过后,发送PSYNC命令
- master 接收到PSYNC命令后,执行BGSAVE命令将全部数据保存至RDB文件中,并将后续发生的写操作记录至buffer中
- master 向所有slave发送RDB文件
- master 向所有slave发送后续记录在buffer中写操作
- slave 收到快照文件后丢弃所有旧数据
- slave 加载收到的RDB到内存
- slave 执行来自master接收到的buffer写操作
- 当 slave 完成全量复制后,后续master只会先发送 slave_repl_offset 信息
- 以后 slave 比较自身和 master 的差异,只会进行增量复制的数据即可
# 复制缓冲区(环形队列)配置参数
# master的写入数据缓冲区,用于记录自上一次同步后到下一次同步过程中间的写入命令,计算公式:repl-backlog-size = 允许从节点最大中断时长 * 主实例offset每秒写入量,比如:master每秒最大写入64mb,最大允许60秒,那么就要设置为64mb*60秒=3840MB(3.8G),建议此值是设置的足够大
repl-backlog-size 1mb
# 如果一段时间后没有slave连接到master,则backlog size的内存将会被释放。如果值为0则表示永远不释放这部份内存。
repl-backlog-ttl 3600
![图片[4]-主从复制优化-李佳程的个人主页](http://www.lijiach.com/wp-content/uploads/2022/11/image-189.png)
1.4、避免全量复制
- 第一次全量复制不可避免,后续的全量复制可以利用小主节点(内存小),业务低峰时进行全量
- 节点运行ID不匹配:主节点重启会导致RUNID变化,可能会触发全量复制,可以利用故障转移,例如哨兵或集群,而从节点重启动,不会导致全量复制
- 复制积压缓冲区不足:当主节点生成的新数据大于缓冲区大小,从节点恢复和主节点连接后,会导致全量复制,解决方法将repl-backlog-size 调大
1.5、避免复制风暴
单主节点复制风暴
当主节点重启,多从节点复制
解决方法:更换复制拓扑
![图片[5]-主从复制优化-李佳程的个人主页](http://www.lijiach.com/wp-content/uploads/2022/11/image-190.png)
单机器多实例复制风暴
机器宕机后,大量全量复制
解决方法:主节点分散多机器
![图片[6]-主从复制优化-李佳程的个人主页](http://www.lijiach.com/wp-content/uploads/2022/11/image-191.png)
2、主从同步优化配置
Redis 在2.8版本之前没有提供增量部分复制的功能,当网络闪断或者slave Redis重启之后会导致主从之间的全量同步,即从2.8版本开始增加了部分复制的功能。
# 性能相关配置
repl-diskless-sync no
# 是否使用无盘方式进行同步RDB文件,默认为no,no表示不使用无盘,需要将
RDB文件保存到磁盘后再发送给slave,yes表示使用无盘,即RDB文件不需要保存至本地磁盘,而且直接通过网络发送给slave
repl-diskless-sync-delay 5
# 无盘时复制的服务器等待的延迟时间
repl-ping-slave-period 10
# slave向master发送ping指令的时间间隔,默认为10s
repl-timeout 60
# 指定ping连接超时时间,超过此值无法连接,master_link_status显示为down状态,并记录错误日志
repl-disable-tcp-nodelay no
# 是否启用TCP_NODELAY
# 设置成yes,则redis会合并多个小的TCP包成一个大包再发送,此方式可以节省带宽,但会造成同步延迟时长的增加,导致master与slave数据短期内不一致
# 设置成no,则master会立即同步数据
repl-backlog-size 1mb
# master的写入数据缓冲区,用于记录自上一次同步后到下一次同步前期间的写入命令,计算公式:repl-backlog-size = 允许slave最大中断时长 * master节点offset每秒写入量,如:master每秒最大写入量为32MB,最长允许中断60秒,就要至少设置为32*60=1920MB,建议此值是设置的足够大,如果此值太小,会造成全量复制
repl-backlog-ttl 3600
# 指定多长时间后如果没有slave连接到master,则backlog的内存数据将会过期。如果值为0表示永远不过期。
slave-priority 100
# slave参与选举新的master的优先级,此整数值越小则优先级越高。当master故障时将会按照优先级来选择slave端进行选举新的master,如果值设置为0,则表示该slave节点永远不会被选为master节点。
min-replicas-to-write 1
# 指定master的可用slave不能少于个数,如果少于此值,master将无法执行写操作,默认为0,生产建议设为1,
min-slaves-max-lag 20
# 指定至少有min-replicas-to-write数量的slave延迟时间都大于此秒数时,master将不能执行写操作
3、常见主从复制故障
3.1、主从硬件和软件配置不一致
主从节点的maxmemory不一致,主节点内存大于从节点内存,主从复制可能丢失数据
rename-command 命令不一致,如在主节点启用flushdb,从节点禁用此命令,结果在master节点执行
flushdb后,导致slave节点不同步
# 在从节点定义rename-command flushall "",但是在主节点没有此配置,则当在主节点执行flushall时,会在从节点提示下面同步错误
10822:S 16 Oct 2020 20:03:45.291 # == CRITICAL == This replica is sending an
error to its master: 'unknown command `flushall`, with args beginning with: '
after processing the command '<unknown>'
# master有一个rename-command flushdb "magedu",而slave没有这个配置,则同步时从节点可以看到以下同步错误
3181:S 21 Oct 2020 17:34:50.581 # == CRITICAL == This replica is sending an
error to its master: 'unknown command `magedu`, with args beginning with: ' after
processing the command '<unknown>'
3.2、master密码错误
如果slave节点配置的master密码错误,导致验证不通过,自然将无法建立主从同步关系。
tail -f /var/log/redis/redis.log
24930:S 20 Feb 2020 13:53:57.029 * Connecting to MASTER 192.168.1.41:6379
24930:S 20 Feb 2020 13:53:57.030 * MASTER <-> REPLICA sync started
24930:S 20 Feb 2020 13:53:57.030 * Non blocking connect for SYNC fired the
event.
24930:S 20 Feb 2020 13:53:57.030 * Master replied to PING, replication can
continue...
24930:S 20 Feb 2020 13:53:57.031 # Unable to AUTH to MASTER: -ERR invalid
password
3.3、Redis版本不一致
不同的redis 版本之间尤其是大版本间可能会存在兼容性问题,如:Redis 3,4,5,6之间
因此主从复制的所有节点应该使用相同的版本
3.4、安全模式下无法远程连接
如果开启了安全模式,并且没有设置bind地址和密码,会导致无法远程连接
vim /etc/redis.conf
#bind 127.0.0.1 #将此行注释
systemctl restart redis
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END