文章目录
前言
分布式系统中存在一个关键的问题,单点问题。单点问题是指服务器的程序只有一个节点,只是用一个物理机来进行不是,这就会导致出现一些问题
- 可用性问题: 如果这个物理机挂了,那么服务就中断了;甚至这个服务器坏掉了,那么就会出现数据丢失的问题
- 性能问题: 单台机器所能承载的访问量是有限的。
为了解决上述问题,通常会把数据复制到多个服务器进行保存,以满足数据故障恢复和负载均衡等需求。其中,redis支持以下三种部署模式
- 主从复制
- 哨兵模式
- 集群模式
在本文中我们主要展示主从复制的实现原理
提示:以下是本篇文章正文内容,下面案例可供参考
一、什么是主从复制模式?
主从复制模式,主要是部署多台redis服务器,其中一个服务器为master节点(主节点),其他节点作为slave节点(从节点),主节点和从节点分别有不同的功能
- 从节点要保持和主节点的数据一直,主节点数据变化,从节点要跟着变化
- 主节点负责写入,所有的写入更新操作都在主节点完成,修改后的数据同步到从节点
- 从节点只负责数据的读取,不能修改数据
通过主从复制我们可以有效的解决单节点的问题
- 可用性问题: 如果从节点挂了,也不影响客户端读取数据,当主节点挂了,只需要重启主节点,或者把其中一个从节点变为主节点即可,不影响客户端的读写问题,也不会丢失数据
- 性能问题: 读请求都分发到对应的从节点区执行,降低了主节点的并发压力
二、使用docker配置redis主从复制
首先要确保服务正确安装docker,配置好正确的docker源 这里不过多赘述
2.1 拉取redis镜像
docker pull redis
2.2 启动redis容器
我这里只有一台服务器,所以我启用多个端口来代表多个redis服务,实际开发中这里是多台物理机
- 创建配置文件目录,下载redis配置文件 并编辑
从redis官方下载redis 配置文件 根据自己的redis版本下载
redis 配置文件
#创建文件 并写入数据
vim /home/docker/redis6379/conf/redis.conf
主要修改以下数据
# 关闭保护模式
pretected-mode no
# 指定服务器地址
prot 6379 # 默认就是6379 这里不必修改

2. 启动主服务器 master服务
docker run -d \
-p 6379:6379 \
--name redis-master \
--restart always \
--privileged=true \
-v /home/docker/redis6379/conf/redis.conf:/etc/redis/redis.conf \
-v /home/docker/redis6379/data:/data \
redis \
redis-server /etc/redis/redis.conf
- 配置从服务的配置文件
vim /home/docker/redis6380/conf/redis.conf
修改以下配置
# 关闭保护模式
protected-mode no
# 服务端口 默认为6379 改为6380
port 6380
# 添加主节点的ip和端口号 这里改为自己的主节点的ip和端口号 这里的127.0.0.1 是假的 !!!!
slaveif 127.0.0.1 6379

4. 启动从服务器
docker run -d \
-p 6380:6380 \
--name redis-slave \
--restart always \
--privileged=true \
-v /home/docker/redis6380/conf/redis.conf:/etc/redis/redis.conf \
-v /home/docker/redis6380/data:/data \
redis \
redis-server /etc/redis/redis.conf
2.3 查看主从同步
进入主服务器查看从节点数量
# 进入容器 打开redis-cli
docker exec -it redis-master redis-cli -p 6379
# 查看redis主节点信息
info relication
这里看到主节点这里,connected_slaves :1 从节点个数1

主节点写入数据
set name dearlin2024

进入从节点
docker exec -it redis-slave redis-cli -p 6380
查看数据
get name

从节点写入数据 测试错误操作

这里我们可以看到 从节点只能读取不能写入 印证了开始的观点
三、主从复制其他操作
3.1 断开链接
对于已经建立的主从关系,我么可以使用 slave no one 将其断开,此命令由从节点执行,执行后从节点将变成一个独立的节点,且无法再同步主节点的修改数据,但是从节点中已有的数据不会丢失
需要注意这里slave no one操作时临时,重启从节点仍然会复制主节点,需要永久生效的话,需要修改配置 slaveof
slave no one 命令和 salveof 命令配合使用,可以进行主节点的切换,把当前从节点切换到另外一个主节点进行复制。主要操作如下:
- 断开和旧主节点的复制关系
- 与新主节点建立复制关系
- 删除从节点当前的所有信息(会判断 runid 不一致)
- 从新节点进行复制操作
哨兵模式就是使用的这个命令,哨兵会给选举的新的主节点发送 slave no one 命令,让新的主节点和旧的主节点断开链接,让自己成为新的主节点,给其他从节点发送 slaveof ip port 命令,让其他从节点复制新的主节点的内容
四、Redis主从复制的原理
4.1 复制过程
Redis 复制建立以及运行的流程如下:

- 保存主节点信息:从节点保存主节点的ip + port信息
- 主从建立连接:从节点想主节点发起三次握手,建立TCP连接
- 发送ping命令:从节点向主节点发送ping,主节点返回pong
- 权限验证:如果主节点设置了requirepss参数,需要进行密码校验
- 同步数据集:对于首次建立复制的场景,主节点会把当前持有的所有数据全部发送给从节点,即全量复制;对于断开连接的从节点,会根据情况进行全量同步或部分同步
- 命令持续复制:当从节点复制了主节点的所有数据之后,针对之后的修改命令,主节点会持续的把命令发送给从节点,从节点执行修改命令,保存了数据的一致性
4.2 PSYNC 数据同步
Redis使用psync 命令完成数据同步,同步分为全量复制和增量复制:
- 全量复制:一般用户初次复制场景,redis早期只支持全量复制,他会把主节点的信息一次性发送给从节点, 当数据量较大是,会造成很大的数据开销
- 增量复制:用于处理主从复制因为网络等原因造成的数据丢失,当从节点再次连接上主节点的死后,如果条件允许,主节点会补发数据给从节点,因为补发的数据远小于全量数据,可以有效的避免全量复制的过度开销
从节点和主节点建立连接之后,会自动执行psync进行数据同步,不需要手动执行
psync 命令语法如下
PSYNC replicationid offset
- replocationid / replid (复制ID):这里的replid指的是主节点的复制ID,主节点每次启动都会重新生成一个replid(统一节点每次重启其 replid也会变化),从节点与主节点建立连接时会保存主节点的replid,主节点根据从节点传递的replid的值进行对应操作
- offset(偏移量):参与复制的主节点和从节点都会维护自身的复制偏移量,主节点处理完修改命令后,会把命令的字节长度做累加记录,统计信息在info replication 中的master_repl_offset 指标中;从节点也会每秒钟上报自身的复制偏移量给主节点,并保存在slave行的offset字段中
- replid 和 offset共同描述一个“数据集” ,如果发现两个节点的replid 和 offset值一致,则可以认为这两个节点中存储的数据是一致的
- 初次复制时,replid的值为?offset的值为-1,此时表示全量复制,重连时,如果replid和offset为某个具体的值,则表示进行增量复制
我们可以使用info replication 命令来查看主节点的复制信息

如图所示:主节点修改命令字节数:master_repl_offset 9828 从节点的offset 也是9828 表示数据已经全部同步
4.3 psync 运行流程
psync运行流程如下

- 从节点发送psync 命令给主节点,且 replid 和 offset 的默认值分别为?和 -1
- 主节点根据psync参数和自身数据情况进行响应
- 如果回复+FULLRESYNC,则从节点需要运行全量复制流程。
- 如果回复+CONTINUE 从节点进行增量复制流程。
- 如果回复-ERR,说明Redis版本过低不支持psync命令,从节点可以使用SYNC命令进行全量复制(链各个命令区别在于,sync会阻塞和redis-server psync不会阻塞)
五、主从复制流程
5.1 全量复制
如下所示:

5.2 增量复制流程
增量复制流程如下:

总结
以上文章为redis主从复制的实现和原理,感谢观看

被折叠的 条评论
为什么被折叠?



