📕 Redis 主从复制搭建
我打算创建一个专栏,主要用于结合八股文和各种场景题来进行代码实践,包括但不限制于集成各种中间件去实现对应的场景和工具封装,该文章为SpringBoot专栏的一个系列,希望大家观看以后帮我多多点赞评论。
大家的点赞和关注是我创作的动力,实属不易,谢谢大家~
-
主修改
redis.conf
文件#启用主从复制 replicaof no one #绑定主节点的ip地址 bind <master_ip>
-
启动主节点
cd redis安装目录
`./redis-server ./redis.conf
-
从节点修改
redis.conf
文件#启用主从复制 replicaof <master_ip> <master_port> masterauth root@1234
-
启动主节点
cd redis安装目录
./redis-server ./redis.conf
-
验证主从复制
redis-cli -h <主节点IP地址 > -p <主节点端口号>
例如:
./redis-cli -h 192.168.150.15 -p 6379 -a root@1234
-
插入一点数据:set mykey “yjren”
-
根据4、5步骤启动从节点
查询 mykey数据是否存在:get mykey
如果返回了与主节点相同的值,则代表主从复制已经成功搭建。
Redis 主从复制
📕 复制过程
- 从节点执行slaveof命令
- 从节点只是保存了slaveof命令中主节点的信息,并没有立刻发起复制
- 从节点内部的定时任务发现有主节点的信息,开始用socket连接主节点。
- 连接成功后,发送ping命令,希望得到pong命令响应,否则会进行重连。
- 如果主节点设置了权限,那么就需要进行权限验证,如果验证失败,复制中止。
- 权限验证通过后,进行数据同步,这是耗时最长的操作,主节点把所有的数据都全部发送给从节点。
- 当主节点把当前的数据同步给从节点后,变完成了复制的建立流程。接下来,主节点会持续把写的命令发送给从节点,保证主从数据一致性。
📕 数据间的同步
上面说的复制过程,其中有一个步骤是"同步数据集",这个现在就是讲的数据同步。
redis同步有两个命令:
sync 和 psync ,前者是redis2.8之间的同步命令,后者是redis 2.8 之后为了优化sync新设计的命令。
psync 需要有三个组件支持:
- 主从节点各自复制偏移量
- 主节点复制积压缓冲区
- 主节点运行ID
🌮 主节点复制各自偏移量:
- 参与复制的主节点都会维护自身的复制偏移量
- 主节点在处理完写入命令后,会把命令的长度做累加处理,统计信息在info replication 中的masterrepoloffset指标中。
- 从节点每秒上报自身的偏移量给主节点,因此主节点也会保存从节点的偏移量。
- 从节点在接收到主节点发送的命令之后,也会累加自身的偏移量,统计信息在info replication中。
- 通过对比主节点的复制偏移量,可以判断主从节点数据是否一致。
🌮 主节点复制积压缓冲区:
- 复制积压缓冲区是一个保存在主节点的固定长度的先进先出的队列,默认大小1MB。
- 这个队列在slave连接时创建,这时主节点响应写命令时,不但会把命令发送给从节点,也会写入复制缓冲区。
- 他的作用就是用于部分复制和复制命令丢失的数据补救。通过info replication可以看到相关信息。
🌮 主节点运行ID
- 每个redis启动的时候,都会生成一个40位的运行ID。
- 运行ID的主要作用就是用来识别Redis节点,如果使用ip + port 的方式,那么如果主节点重启修改了RDB/AOF数据,从节点再基于偏移量进行复制将是不安全的。所以,当运行ID发生了变化,从节点将会进行全量复制。也就是说,redis重启后,默认从节点都会进行全量复制。
如果在重启时不改变运行 ID 呢?
1、可以通过 debug reload 命令重新加载 RDB 并保持运行 ID 不变。从而有效的避免不必要的全量复制。
2、他的缺点则是:debug reload 命令会阻塞当前 Redis 节点主线程,因此对于大数据量的主节点或者无法容忍阻塞的节点,需要谨慎使用。一般通过故障转移机制可以解决这个问题。
psync 命令的使用方式:
命令格式为 psync{runId}{offset}
runId:从节点所复制主节点的运行 id
offset:当前从节点已复制的数据偏移量
![](https://i-blog.csdnimg.cn/blog_migrate/a9aec49b541f725e7854957c9abf6333.png)
流程说明:从节点发送psync命令给主节点,runid也就是目标主节点的ID,如果没有默认为-1,offset 是从节点保存的偏移量,如果是第一次复制则为-1,主节点会根据runid和offset决定返回结果。
- 如果回复 +FULLRESYNC {runId} {offset},那么从节点将触发全量复制流程。
- 如果回复 +CONTINUE 从节点将触发部分复制。
- 如果回复 +ERR,说明主节点不支持2.8的psync命令,将使用sync执行全量复制。
📕 全量复制
全量复制是Redis最早的支持复制方式,也就是主从第一次建立复制时必须要经历的阶段。触发全量复制的命令是sync和psync。
![](https://i-blog.csdnimg.cn/blog_migrate/50fa5251a919d8f29697c5ca81bd1701.png)
- 发送psync命令(psync ? -1)
- 主节点根据命令返回FULLRESYNC
- 从节点记录主节点ID和offset
- 主节点bgsave并保存RDB到本地
- 主节点发送RDB文件到从节点
- 从节点收到RDB文件并加载到内存中
- 主节点在从节点接收数据的期间,将新数据保存到"复制客户端缓冲区",当从节点加载完RDB完毕,在发送过去。(如果从节点花费时间过长,将导致缓冲区溢出,最后全量同步失败。)
- 从节点清空数据后加载RDB数据,如果RDB文件过大,这一步操作仍然耗时,那么此时客户端访问,将导致数据不一致。可以使用配置slave-server-stale-data关闭
- 从节点成功加载完成RDB之后,如果开启了AOF,会立刻做bgrewriteaof,加粗的地方都是整个全量同步耗时的地方。
📕 部分复制
当从节点正在复制主节点时,如果出现网络闪退和其他异常,从节点会让主节点补发丢失的命令数据,相较于全量复制成本很小。
- 当从节点出现网络中断,超过了repl-timeout时间,主节点就会中断复制连接。
- 主节点会将请求的数据写入到"复制积压缓冲区",默认1mb。
- 当从节点恢复,重新连接上主节点,从节点会将offset和主节点id发送到主节点。
- 主节点校验后,如果偏移量的数后的数据在缓冲区,就发送continue响应 ----表示可以进行部分复制。
- 主节点将缓冲区的数据发送到从节点,保证主从复制可以进行正常状态。
📕 心跳
主从节点在建立连接之后,他们之间维护着长连接并彼此发送心跳命令。
心跳命令关键机制如下:
- 主从都有心跳检测机制,各自模拟成各自的客户端进行通信,通过client list命令查看复制相关客户端信息,主节点的连接状态flags = M,从节点的连接状态是flags = S。
- 主节点默认每个十秒对从节点发送ping命令,可修改配置repl - ping -slave - period 控制发送频率。
- 从节点在主线程每隔一秒发送 replconf ack {offset} 命令,给主节点上报自身当前的复制偏移量。
- 主节点收到replconf 信息 ,判断节点超时信息,如果超过如果 repl-timeout 60秒,则判断节点下线。
📕 异步复制
主节点不但负责数据读写,还负责把写命令同步给从节点,写命令的发送过程是异步完成,也就是说主节点处理完写命令后立刻返回客户端,并不等待从节点复制完成。
- 主节点接收处理命令
- 主节点处理完后返回响应结果
-
![](https://i-blog.csdnimg.cn/blog_migrate/8efa00a4c7812323e5c7a069e2deda7f.png)