redis的主从复制
对主从的理解
主从首先应该只有一个主,一个或多个从。主从的两个主要作用是
- 1、备份
- 2、一个写多个读
使用只是想使用备份,那么一主两个从应该就可以了。对于数据的读操高于写数倍的场景使用多个从的收益会比较高的, 如果从太多master的负载可能会比较高。。
可以在为从服务器设置从服务器, 这样就可以减少master的压力,合理扩展从服务器的个数
主从的实现
同步的两种方式
- 完整同步
像初次作为一个master的从服务器的时候就会进行完整同步,完整同步的步骤如下:
1、从服务器向master发送SYNC命令
2、master将现有的数据写成rdb文件,并在此期间缓存接受到的客户端命令
3、master将rdb发送给从服务器,从服务器载入rdb文件
4、master将缓存区的所有命令发送给从服务器,使从服务器与主服务器保存一致 - 部分同步
部分同步用于处理断线重连的情况。master有一个复制积压缓存区,断线重连之后从服务器最后
的复制偏移如果还在缓存积压区中,就可以将剩余未发送的内容同步过去,所以叫部分同步。
如果断线太久,就只能完整同步,不然就会有数据丢失。
部分同步的实现
部分同步通过复制偏移量,积压缓存区,服务器运行id三个信息来实现。每个服务器都有自己的运行id,
从服务器保存着上一个复制的主服务器的运行id。当从服务器通过psync master_run_id slave_offset
请
求复制的时候,主服务器会根据从服务器发送的master_run_id判断从服务器之前的主服务器是否是自己来决定是否
需要完整同步,如果是自己还需要根据判断slave_offset是否还在积压缓存去来决定是否可以部分同步。
- 从服务器发送命令
如果从服务器没有复制过任何主服务器或执行过slaveof no one
,则通过此命令来请求完整同步
psync ? -1
如果已经复制过某个主服务器,则发送它的id,和当前从服务器的复制偏移
psync <master_run_id> <slave_offset>
- 主服务器响应
若是完整同步,则主服务器回复如下命令,告知从服务器自己的运行id和复制偏移
+fullresync <run_id> <offset>
如果是部分同步,则主服务器回复如下命令
+continue
复制的完整步骤
- 1、从服务器通过
slaveof 127.0.0.1 6379
设置主服务器ip与端口 - 2、从服务器与主服务器建立socket连接,让从服务器成为主服务器的客户端
- 3、从服务器发送ping命令给主服务器。
用于检测主服务器能否正常处理命令请求,可能不能处理的原因:网络不佳、服务器在处理超时lua脚本 - 4、身份验证:从服务器通过
auth xxx
命令发送密码,主服务器验证密码 - 5、发送端口信息:从服务器发送
replconf listening-port <port>
向主服务器发送从服务器的端口 - 6、同步:从服务器发送命令
psync
请求同步,主服务器变成从服务器的客户端开始向从服务器发送命令 - 7、命令传播:主服务器一直将自己执行的写命令发给从服务器,从服务器一直接收并执行,这样就保证了主从一直一致
心跳检测
心跳检测是通过从服务器每秒向主服务器发送命令replconf ack <slave_offset>
完成。心跳检测有以下几个作用:
- 检测主从服务器的网络连接状态
如果主服务器超过1秒钟没有收到从服务器的replconf ack
命令,主服务器就知道和从服务器之间的连接出了问题
通过向主服务器发送info replication可以在lag一栏中看到每个从服务器最后一次向主服务器发送replconf ack命令距离
现在过了多少秒 - 辅助现实min-slaves配置选项
当从服务器的数量少于某个值或者所有从服务器的延迟(lag)大于某个值时,主服务器拒绝执行写命令 - 检测命令丢失
类似于tcp协议的重传机制。