您的位置:首页 > 数据库 > Redis

彻底明白Redis主从同步原理

2020-06-03 05:47 302 查看

1.主从复制

两个Redis实例(可ip相同port不同),可使用slaveof命令设置主从关系。redis采用乐观同步策略,即容忍短时间内主从不一致,但是保证最终一致性,主从复制分为三个阶段:

  1. 连接阶段
  2. 数据同步阶段
  3. 命令传播阶段

2.连接阶段

当slave执行完salveof ${master_ip} ${master_port}命令时,slave向master发起socket连接,master接收到连接请求后建立连接。

当连接建立后,slave向master发送[ping]命令,以确定master状态正常,如果master响应[pong]则代表master正常。

如果master设置了密码,则slave需要配置masterauth参数,此时slave发送[auth + ${passwoed}]命令进行密码验证,

当密码验证成功后,slave通知master自己的监听端口,此时连接完成。

3.数据同步阶段

数据同步阶段是slave的数据初始化阶段,也就是slave同步master当前的数据,该步是slave主动发起。

slave向master发送[psync]命令,master收到请求后,首先判断是增量复制还是全量复制,然后再同步。

增量复制是指master仅将缓冲区中的命令发给slave,slave依次执行命令,完成数据同步。

全量复制是指master先生成内存快照(rdb文件,这里和是否开启rdb备份无关),然后将内存快照发给slave,slave加载快照到内存中完成数据同步。

3.1 offset 偏移量

master和slave都会维护一个偏移量(可使用[info replication]命令查看偏移量),用于标识主从复制的现状;master的offset表示向slave已发送的字节数,slave的offset表示已同步的字节数。可以通过offset观察主从是否同步完成,若相等则说明同步完成。

3.2 replication backlog buffer

[replication backlog buffer]是一个固定长度的FIFO的队列,大小由配置参数[repl-backlog]指定,默认大小是1mb,这个缓冲区只存在master,用于备份最近master同步slave的数据。

在命令传播阶段,master除了将命令同步给slave外还会在这个缓冲区中备份,而且还会存储每个命令(实际是每个字节)对用的offset值,如下图:

由于缓冲区固定大小,因此只能备份最近执行过的命令,这个缓冲区用于增量复制,提高数据同步阶段的效率。

3.3 runid

每个redis服务每次启动时,都会随机生成一个40的id来代表自己,可通过[info server]命令查询run_id。

在初次主从同步时,master会将自己的runid发送给slave,salve记录自己的[master runid]。

3.4 同步流程

  1. slave首先判断是否第一次执行主从复制,即如果有保存的[master run_id],如果有则说明不是第一次。

  2. 如果slave是第一次执行主从复制,则向master发送全量复制请求。

  3. 如果slave不是第一次执行主从复制,则向master发送增量复制请求[ psync ${master run_id} offset ]。

  4. master如果接受到全量复制请求,则进行内存快照,然后响应rdb文件。

  5. master如果接受到增量复制请求,则首先判断请求中的runid是不是自己,如果和自己的runid不一致,则说明slave之前的master并不是自己,此时只能进行全量复制,响应[ FULLRESYNC runid offset ],从节点则更新自己保存的master runid,并将offset作为自己的初始偏移量,然后等待master发来的rdb文件进而执行全量复制。

  6. 如果master判断slave的上一次的master是自己时,则继续判断请求中的offset是否在[replication-backlog-buffer]中,如果在则说明可以进行增量复制,返回[CONTINUE],slave则得知可以进行增量复制,等待slave发来的自己缺少的那部分命令,然后执行即可。

4 命令传播阶段

当数据同步完成后,此后的时间里主从之间维护心跳来检查对方是否在线。

master定时向slave发送[PING]请求,如果收到slave的[PONG]响应则可知slave在线(默认10s,通过参数[repl-ping-slave-period]指定)。

slave每秒向master发送[ REPLCONF ACK ${offset} ]命令,master根据偏移量响应未同步的数据,slave收到master的响应可知master在线,并执行命令,完成主从同步。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: