一、主从复制简介
Redis支持主从复制功能,可以通过执行slaveof(Redis5以后改成replicaof)或者在配置文件中设置 slaveof(Redis5以后改成replicaof)来开启复制功能。
1.1、特点
- 主对外从对内,主可写从不可写
- 主挂了,从不可为主
2、作用
2.1 读写分离
- 一主多从,主从同步
- 主负责写,从负责读
- 提升Redis的性能和吞吐量
需要注意点:主从的数据一致性问题
2.2 数据容灾
- 从机是主机的备份
需要注意点:默认情况下主机宕机后,从机不可为主机 利用哨兵可以实现主从切换,做到高可用
二、主从配置详解
2.1 主Redis配置
无需特殊配置
2.2 从Redis配置
修改从服务器上的 redis.conf 文件:
# slaveof <masterip> <masterport> # 表示当前【从服务器】对应的【主服务器】的IP是192.168.10.135,端口是6379。 replicaof 192.168.10.135 6379
2.3 主从复制流程
- 启动redis,从服务器根据配置文件,执行slaveof去链接主服务器
- 建立socket连接,Socket连接后,相当于从服务器是主服务器的Client 端
- Slaver向Master发送ping命令
- 检测socket的读写状态
- 检测Master能否正常处理
- Master的响应
- 发送“pong” , 说明正常
- 返回错误,说明Master不正常
- timeout,说明网络超时
- 主从正常连接后,进行权限(密码)验证
- 发送端口信息
- 在身份验证步骤之后,从服务器将执行命令REPLCONF listening-port ,向主服务器发送从服务器的监 听端口号
- 同步数据集
- Redis 2.8以前使用SYNC命令同步复制
- 为同步(sync)
- 命令传播(command propagate)
- Redis 2.8之后采用PSYNC命令替代SYNC
- 全量同步
- 增量同步
2.4 同步数据详解
(1)Redis2.8之前的版本,
首先redis复制功能分为同步操作和命令传播两个操作
同步操作作于将从服务器的数据库状态更新至主服务器当前所处的数据库状态
命令传播操作则用于在主服务器的数据库状态被修改,导致主从服务器的状态不一致时,让主从服务器的数据重回一致状态。
旧版复制实现:
同步:
1,从服务器想主服务器发送SYNC命令
2,收到SYNC命令的主服务器执行BGSAVE命令,然后生成一个RDB文件,并使用一个缓存区记录从现在开始执行命令的所有写命令
3,当主服务器的BGSAVE命令执行完毕,将RDB文件在发送给从服务器,从服务器载入这个RDB文件,在将数据库状态更新至主服务器状态一致
4,主服务器将记录在缓冲区内里的所有写命令发送给从服务器,然从服务器执行这些写命令,将自己的状态更新跟主服务器当前的状态。
命令传播:
当同步操作执行完后,主从服务器状态达到一致,但每当主服务器的数据发生变化时,导致主从服务器的状态不一致。这时 为了主从服务器再次回到一致状态,主服务器需要将自己执行的命令,发送给从服务器执行,这样主从服务器回到一致状态。
旧版复制的缺陷:
断线后重复制:再主从服务器状态一致时,从服务器发生宕机,这时主服务器继续接收客户端发来的写命令,然主服务器这时状态已被修改。从服务器重新连接,从服务器向主服务器发送同步命令,然主服务器执行BGSAVE命令,创建RDB文件,并使用使用缓冲区记录接下来所有的写命令,在发送RDB文件给从服务器,从服务器接收载入这个RDB文件,上诉操作其实从服务器断开连接以前的数据库状态是一致的,不一致的只是从服务器断开后一段时间内的数据,然旧版复制还是将主服务器包含所有数据的RDB文件发送给从服务器,效率极其低下。
(2)Redis2.8之后,新版复制功能实现
为了解决旧版复制功能在从服务器断线重连后的低效复制问题,从2.8之后,使用PSYNC命令代替SYNC命令来执行复制的同步操作
PSYNC命令具有完整重同步和部分重同步两种模式
其中完整重同步主要用于初次重复制的情况,完整同步实现与SYNC命令步奏一样。
部分重同步则用于处理断线后重复制的情况,它主要实现是在从服务器断线后重连主服务器时,将断线后主服务器接收到的写命令发送给从服务器,从服务器在执行这些命令,从而达到主从服务器状态一致。
部分重同步实现:
1. 复制偏移量
主从服务器各自维护自己的偏移量,主服务器每次向从服务器传播N个字节的数据时,会将自己的复制偏移量加N,然从服务器的复制偏移量的值也加N。如主从服务器的状态一致时,两者的偏移量是相同的。相反如果偏移量不同,说明主从服务器的状态处于不一致状态。
2. 复制积压缓冲区
复制积压缓冲区是由主服务器维护的一个固定长度先进先出队列,默认大小为1M,
(可以配置redis.conf文件,write_size_per_second,配置可以根据,从服务器断线时间(S)*平均每秒产生的数据(M))
当主服务器进行命令传播的时候,会将所有写命令发送给从服务器,还会将写命令入队到复制积压缓冲区内,如图:
主服务器的复制积压缓冲区里面会保存着一部分的最近传播的写命令,并且复制积压缓冲区会为队列中的每一个字节记录相应的复制偏移量。
当从服务器重新连上主服务器时,从服务器会通过PSYNC命令将自己的复制偏移量offset发送给主服务器,主服务器会根据这个复制偏移量决定从服务器执行那种同步操作,
1,如果offset偏移量之后的数据存在于复制积压缓冲区内,那么主服务器将对从服务器执行部分重同步。
2,如果offset偏移量之后的数据不存在于复制积压缓冲区内,那么将执行完整重同步。
问题:如果在从服务器a断线重连后,从服务器a向主服务器发送PSYNC命令,得知从服务器a当前的复制偏移量在999,如果这个时使用部分重复制,则断线期间的数据丢失。
部分重同步实现具体细节:
当从服务器A断线后,立即重新连接主服务器,并向主服务器发送PSYNC命令,并报告自己的复制偏移量为999,
主服务器收到从服务器发送来的PSYNC命令以及偏移量为999之后,主服务器将检查偏移量999以后的数据是否存在于复制积压缓冲区内,
如果发现数据亦然存在,则主服务器向从服务器发送+CONTINUE回复,表示数据同步价将以部分重同步模式进行。
接着主服务器会将复制积压缓冲区999偏移量之后的所有数据都发送给从服务器,
从服务器只要接收偏移量999以后的确实数据,就可以回到与主服务器一直状态。
2.5、心跳检测
在命令传播阶段,从服务器默认会以每秒一次的频率向主服务器发送命令:
replconf ack <replication_offset>
#ack :应答
#replication_offset:从服务器当前的复制偏移量
作用有三个
1. 检测主从的连接状态
检测主从服务器的网络连接状态 通过向主服务器发送INFO replication命令,可以列出从服务器列表,可以看出从最后一次向主发 送命令距离现在过了多少秒。lag的值应该在0或1之间跳动,如果超过1则说明主从之间的连接有 故障。
2. 辅助实现min-slaves
Redis可以通过配置防止主服务器在不安全的情况下执行写命令 min-slaves-to-write 3 (min-replicas-to-write 3 ) min-slaves-max-lag 10 (min-replicas-max-lag 10) 上面的配置表示:从服务器的数量少于3个,或者三个从服务器的延迟(lag)值都大于或等于10 秒时,主服务器将拒绝执行写命令。这里的延迟值就是上面INFOreplication命令的lag值。
3. 检测命令丢失
如果因为网络故障,主服务器传播给从服务器的写命令在半路丢失,那么当从服务器向主服务器发 送REPLCONF ACK命令时,主服务器将发觉从服务器当前的复制偏移量少于自己的复制偏移量, 然后主服务器就会根据从服务器提交的复制偏移量,在复制积压缓冲区里面找到从服务器缺少的数 据,并将这些数据重新发送给从服务器。(补发) 网络不断 增量同步:网断了,再次连接时
注:以上为本人小小总结,如果对您起到了一点点帮助,请给予我一点鼓励,在下方点个小小的赞,谢谢,如有错误之处,望不吝指出,非常感谢!