Redis主从复制的全量复制和增量复制过程
Redis主从复制分为全量同步和增量同步
Redis 的主从同步是非阻塞的,即同步过程不会影响主服务器的正常访问
全量复制过程(第一次为全量复制)
主从节点建立连接,验证身份后,从节点向主节点发送PSYNC(2.8版本之前是SYNC)命令
主节点向从节点发送FULLRESYNC命令,包括runID和offset
从节点保存主节点信息 主节点执行BGSAVE保存RDB文件,同时记录新的记录到buffer中
主节点发送RDB文件给从节点
主节点将新收到buffer中的记录发送至从节点
从节点删除本机的旧数据
从节点加载RDB
从节点同步主节点的buffer信息
增量复制过程
在主从复制首次完成全量同步之后再次需要同步时,从服务器只要发送当前的offset位置(类似于MySQL的 binlog的位置)给主服务器,然后主服务器根据相应的位置将之后的数据(包括写在缓冲区的积压数据)发 送给从服务器,再次将其保存到从节点内存即可.
即首次全量复制,之后的复制基本增量复制实现
主从同步完整过程
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,缓冲区内数据会被释放,当连上后,是全局复制
默认时间是 repl-backlog-ttl 3600s
二:避免全量复制
1、第一次全量复制不可避免,后续的全量复制可以利用小主节点(主节点内存不要太大),业务低峰时进行全量
2、节点运行ID不匹配:主节点重启会导致RUNID变化,可能会触发全量复制,可以利用故障转移,例如哨兵或集群,而从节点重启动,不会导致全量复制(info replication可查看RUNID)
3、复制积压缓冲区不足: 当主节点生成的新数据大于缓冲区大小,从节点恢复和主节点连接后,会导致全量复制.解决方法将repl-backlog-size 调大
三:避免复制风暴
单主节点复制风暴
当主节点重启,多从节点复制
解决方法:更换复制拓扑(比如级联复制)
单机器多实例复制风暴
机器宕机后,大量全量复制
解决方法:主节点分散多机器
四:主从同步优化配置
vim /apps/redis/etc/redis.conf
和replication相关的
repl-diskless-sync no #yes发送快一些,no发送稳定一些
是否使用无盘方式进行同步RDB文件,默认为no,no表示不使用无盘,需要将RDB文件保存到磁盘后再发送给slave,yes表示使用无盘,即RDB文件不需要保存至本地磁盘,而且直接通过网络发送给slave
repl-diskless-sync-delay 5 #无盘时复制的服务器等待的延迟时间,默认5s
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 环形队列缓冲区,超过此值,就会全量复制,建议设置大一点
repl-backlog-ttl 3600 超过一定时间没有slave连接到master,缓冲区内数据会被释放,当连上后,是全局复制
slave-priority 100 #slave参与选举新的master的优先级,此整数值越小则优先级越高.当master故障时将会按照优先级来选择slave端进行选举新的master,如果值设置为0,则表示该slave节点永远不会被选为master节点.
min-replicas-to-write 1 #指定master的可用slave不能少于个数,如果少于此值,master将无法执行写操作,默认为0,生产建议设为1 (至少有一个从节点把数据同步完成返回成功结果,类似于MySQL的半同步)
min-slaves-max-lag 20 #指定至少有min-replicas-to-write数量的slave延迟时间都大于此秒数时,master将不能执行写操作,默认为10s
常见主从复制故障
1、主从硬件和软件配置不一致
主从节点的maxmemory不一致,主节点内存大于从节点内存,主从复制可能丢失数据
rename-command 命令不一致,如在主节点启用flushdb,从节点禁用此命令,结果在master节点执行 flushdb后,导致slave节点不同步
2、master密码错误
3、Redis版本不一致
4、安全模式下无法远程连接
如果开启了安全模式,并且没有设置bind地址和密码,会导致无法远程连接