1.主从复制的作用
- 数据冗余:解决了持久化的单点故障问题,将数据备份到了其他机器。
- 故障恢复: 当主节点出问题时,从节点能及时提供服务。
- 负载均衡: 主节点复制写,从节点负责读。
2.主从复制的开启
主从复制的开启都是从从节点开始的,主节点无需修改。有下面三种方式来开启从节点的主从复制:
- 在从节点配置文件中加入:
slaveof [masterip] [masterport] - redis-server 启动命令后面加入:
slaveof [masterip] [masterport] - redis客户端手动执行:
slaveof [masterip] [masterport]
3.主从复制的过程
- 从节点执行 slaveof 命令,从节点只是保存了 slaveof 命令中主节点的信息,并没有立即发起复制。
- 从节点内部的定时任务发现有主节点的信息,开始使用 socket 连接主节点。
- 连接建立成功后,发送 ping 命令,希望得到 pong 命令响应,否则会进行重连。
- 如果主节点设置了权限,那么就需要进行权限验证;如果验证失败,复制终止。
- 权限验证通过后,进行数据同步,这是耗时最长的操作,主节点将把所有的数据全部发送给从节点。
- 当主节点把当前的数据同步给从节点后,便完成了复制的建立流程。接下来,主节点就会持续的把写命令发送给从节点,保证主从数据一致性。
4.主节点怎么同步数据到从节点的
Redis2.8以前都是全量复制,但是Redis2.8以后是根据主节点的状态来判断是全量复制还是部分复制。
(1) 全量复制
- 主节点接受到从节点发来的全量复制命令后,执行bgsave,在后台生成RDB文件,并用一个复制缓存区记录从现在开始起执行的所有命令(一面RDB过程中又有新的redis命令导致丢失)。
- 主节点bgsave完成后,将RDB文件发送给从节点,从节点首先清除自己的旧数据,然后载入接收的RDB文件。
- 主节点将前述复制缓冲区中的所有写命令发送给从节点,从节点执行这些写命令,将数据库状态更新至主节点的最新状态。
- 如果从节点开启了AOF,则会触发bgrewriteaof的执行,从而保证AOF文件更新至主节点的最新状态。
全量复制的缺点:
- 主节点要执行bgsave,在fork时会阻塞主进程。
- 主节点通过网络将RDB文件发送给从节点,带宽消耗很大。
- 从节点清空老数据,重新载入过程是阻塞的,无法响应客户端命令。
(2) 部分复制
复制偏移量
主节点和从节点都维护了一个偏移量(offset),主节点向从节点传播N个字节数时,主节点的offset增加N,从节点也增加N。
偏移量在 info replication 中的 master_repl_offset 指标中。可以用来判断主从延迟多少个字节。
复制积压缓冲区
主节点里的缓冲区,这个队列在 slave 连接时创建。这时主节点响应写命令时,不但会把命令发送给从节点,也会写入复制缓冲区。他的作用就是用于部分复制和复制命令丢失的数据补救。
服务器运行ID(runid)
每个Redis节点(无论主从),在启动时都会自动生成一个随机ID(每次启动都不一样)。
主从节点初次复制时,主节点将自己的runid发送给从节点,从节点将这个runid保存起来;当断线重连时,从节点会将这个runid发送给主节点;主节点根据runid判断能否进行部分复制:
- 如果从节点保存的runid与主节点现在的runid相同,说明主从节点之前同步过,主节点会继续尝试使用部分复制。
- 如果从节点保存的runid与主节点现在的runid不同,说明从节点在断线前同步的Redis节点并不是当前的主节点,只能进行全量复制。
部分复制过程
也就是从节点执行psync命令过程。
psync命令的格式:
命令格式为 `psync {runId} {offset}`
runId : 从节点所复制主节点的运行 id
offset:当前从节点已复制的数据偏移量
如果从节点没有主节点的runid,则代表是第一次同步,则从节点会发送 psync ? -1 进行全量复制。
如果从节点有runid,则代表已经同步过,发送 psync runid offset 进行部分复制。
5.数据同步后,主节点的心跳机制
主节点同步数据给从节点,以后都是直接发送写命令给从节点,并且还维持和从节点的心跳,用来判断主从连接是否正常。
- 主节点默认每隔 10 秒对从节点发送 ping 命令,可修改配置 repl-ping-slave-period 控制发送频率。
- 从节点在主线程每隔一秒发送 replconf ack{offset} 命令,给主节点上报自身当前的复制偏移量。
- 主节点收到 replconf 信息后,判断从节点超时时间,如果超过 repl-timeout 60 秒,则判断节点下线。
- 上面可以看到主从是否正常,lag:代表的是主节点上次收到该replconf ack命令的时间间隔,在正常情况下,该值应该是0或1。
- 主节点收到 replconf 信息后,由于从节点发送了自身的offset,主节点会与自己的offset对比,如果从节点数据缺失(如网络丢包),主节点会推送缺失的数据(这里会利用复制积压缓冲区)
6.主从复制带来的延迟
数据复制的延迟
读写分离时,master会异步的将数据复制到slave,如果这是slave发生阻塞,则会延迟master数据的写命令,造成数据不一致的情况。
最后引用大佬的话
读写都应该在master节点上,slave只做故障恢复。