Redis主从复制


Redis 的复制(replication)功能允许用户根据一个 Redis 服务器来创建任意多个该服务器的复制品,其中被复制的服务器为主服务器(master) ,而通过复制创建出来的服务器复制品则为从服务器(slave) 。 只要主从服务器之间的网络连接正常,主从服务器两者会具有相同的数据,主服务器就会一直将发生在自己身上的数据更新同步给从服务器 ,从而一直保证主从服务器的数据相同。
一句话:就是主从复制,master以写为主,slave以读为主。当master数据变化的时候,自动将新的数据异步同步 到其他slavve数据库。
主从复制的作用
- 读写分离
- 容灾恢复
- 数据备份
- 水平扩容支持高并发
利用docker搭建一主两从的redis集群
docker-compose.yml的配置信息
bash
version: '3.8'
services:
master:
image: docker.1ms.run/library/redis:7.0.0
container_name: redis-master
ports:
- "6379:6379"
command: redis-server --protected-mode no --requirepass root # 主节点密码
slave1:
image: docker.1ms.run/library/redis:7.0.0
container_name: redis-slave1
ports:
- "6380:6379"
command:
- redis-server
- --protected-mode no
- --replicaof redis-master 6379
- --masterauth root # 从节点连接主节点的密码
- --requirepass root # 从节点自身的密码(可选,但建议与主节点一致)
slave2:
image: docker.1ms.run/library/redis:7.0.0
container_name: redis-slave2
ports:
- "6381:6379"
command:
- redis-server
- --protected-mode no
- --replicaof redis-master 6379
- --masterauth root
- --requirepass root
其中在每个从节点上需要配置master主节点的密码,--masterauth 的参数指定。以及--replicaof指定主节点的地址
docker-compose up -d启动后
在master主节点上执行以下命令进入主节点的redis环境
bash
docker exec -it redis-master redis-cli -a root
在redis从节点上执行以下命令进入从节点的redis环境
bash
docker exec -it redis-slave1 redis-cli -a root
进入redis集群后,可以执行info replication的命令查看节点的状态信息
bash
info replication
主节点的信息
从节点的信息
主从同步的演示,在主节点上写入值,从节点可以读取到相关的值
主节点写入值:
从节点读取值
从节点可以执行写命令么?
从节点不可以写
bash
(error) READONLY You can't write against a read only replica.

第三个节点挂了,前两个节点还是正常的,再往主机写入多个值,第三个节点然后再启动,数据会同步过来么?
第三个节点挂了
往第一个节点写入多个值
查看第二个节点的数据,数据正常同步
启动第三个节点
查看第三个节点的数据信息,数据正常同步过来
主节点shutdown后,从节点是否会上位?

读取从机的值,数据并没有丢,身份也没有变
主机shutdown后,重启后主从关系还在吗?从机还能否顺利复制?
主节点再设置值
从节点再去读取值
某台从机down后,master继续,从机重启后他能跟上大部队么?答:能
除了从配置文件的角度设置持久有效的主从关系外,还可以通过命令salveof 主机ip以及端口号指定主机的挂载,但是临时有效 ,当redis重启中,主从关系将不复存在。
薪火相传的架构演示
类似于爷爷->爸爸-> 儿子的主从关系
slaveof 新主库IP 新主库端口
第三个节点选取第二个节点作为master节点
第一个爷爷级别的主节点信息变化
第二个中间爸爸级别的节点信息变化
中间的爸爸节点,仅仅是数据的同步方向的指定,仍然不可以执行写入操作的
上一个slave可以是下一个slave的master,slave同样可以接收其他slaves的连接和同步请求,那么该slave作为了链条中下一个的master,可以有效减轻主master的写压力。
中途变更转向:会清除之前的数据,重新建立拷贝最新的。
反客为主
使用命令: slaveof no one
写入数据
主从复制原理和工作流程
- salve启动,同步初请(slave启动成功连接到master会发送一个sync命令,slave首次全新连接master ,一次完全同步(全量复制)将被自动执行,slave自身原有数据会被master数据覆盖清除)
- 首次连接,全量复制(master节点收到sync命令后会开始在后台保存快照(即RDB持久化,主从复制时会触发RDB),同时收集所有接收到的用于修改数据集命令缓存起来,master节点执行RDB持久化完成后,master将RDB快照文件和所有缓存的命令发送到所有slave,以完成一次完全同步。而slave服务在接收到数据库文件后,将其存盘并加载到内存中,从而完成复制初始化)
- 心跳持续,保持通信(master发出PING包的周期,默认10s。repl-ping-replica-period 10)
- 进入平稳,增量复制(master继续将新的所有收集到的修改命令自动依次传递给slave,完成同步)
- 从机下线,重连续传(master会检查backlog里面的offset,master和slave都会保存一个复制的offset还有一个masterId,offset是保存在backlog中的 ,Master只会把已复制的offset后面的数据复制给slave,类似断点续传)
主从复制的缺点
-
复制延时,信号衰减
-
master挂了,如何办?(默认情况下,不会在slave节点中自动重选一个master ,那每次人工选举?? 无人值守安装成为刚需 哨兵模式 )
参考视频
Redis 集群架构