上一章学习了 (002)Redis 持久化方式 RDB 和 AOF ,本章将学习 Redis 的主从复制。
关于持久化特性使数据在 redis 服务重启后不会丢失,但当 redis 服务器的硬盘损坏后就无法重启,存在硬盘中的数据即无法使用,此时 redis 的主从复制机制(master-slave replication)就可以避免这种单点故障。按照以上介绍,我们可以理解成 Redis 持久化是将数据持久化至本机上,主从复制则是将数据复制到其它服务器上
当然,这并非主从复制的存在的意义,下面将是主从复制的简单介绍。
主从复制
主(master)和 从(slave)分别部署在不同的服务器上,当主节点服务器写入数据时会同步到从节点的服务器上,这样即使 redis 服务器的硬盘损坏,也可以在从节点的服务器中获取数据。
作用
- 为数据提供多个副本,实现高可用
- 实现读写分离(主节点负责写数据,从节点负责读数据,主节点定期把数据同步到从节点保证数据的一致性)
特点
- 数据流向是单向的,只能是从master到slave
- 一个slave只能有一个master,一个master可以有多个slave,一个slave还可以有自己的slave
相关操作
有两种方式实现主从复制功能:slaveof 命令方式和配置方式。
slaveof 命令方式
查看当前redis服务器的角色role,默认 master。
127.0.0.1:6379> info replication
role:master # 角色,主(master)
connected_slaves:0 # 从节点数 0
# 其它信息..
设置成 指定服务器上的子节点:
127.0.0.1:6379> SLAVEOF 127.0.0.1 6380
OK
此时再次查看角色信息:
127.0.0.1:6379> info replication
role:slave # 角色变成了 从节点(salve)
master_host:127.0.0.1 # 主节点的地址(一般不设成同一个服务器)
master_port:6380 # 主节点端口
master_link_status:up # 连接状态,up 表示正常运行
查看主节点服务器角色:
127.0.0.1:6380> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=6379,state=online,offset=308,lag=1
在主节点中设置数据:
127.0.0.1:6380> set hello world
OK
在从节点中获取数据:
127.0.0.1:6379> get hello
"world"
在子节点中设置数据(报错,因为从节点只读)
127.0.0.1:6379> set a b
(error) READONLY You can't write against a read only replica.
取消成为子节点:
127.0.0.1:6379> slaveof no one
OK
注意,在取消成为子节点时,数据不会被清空,而设置成其它主节点时,之前的数据会被清空,并且加载新主节点的数据;
配置方式
打开配置文件redis-6379.conf,添加以下配置:
slaveof 127.0.0.1 6380
然后重启 redis 即可生效。
子节点配置失败可能原因(master_link_status:down):
1. 检查 redis 版本是否一致
2. 检查主节点服务器端口是否打开
3. 检查主节点配置 bind 127.0.0.1 是否已注释
4. 检查主节点连接是否需要设置密码
全量复制
- 新建一个 slave 节点时,slave 会发送(Psync ? -1)命令给 master 请求同步数据;
- master 接收到同步请求后向 slave 发送 run_id 和 offset;
- slave 会接收并保存 mater 传递过来信息(slave 中无对应offset,所以执行全量复制)。
- master 执行 bgsave 命令生成RDB文件,期间会创建复制缓冲区记录从现在开始执行的所有写命令;
- master 先向 slave 发送RDB数据;
- 然后发送复制缓冲区记录的数据,slave 会将RDB和缓冲区数据存放到磁盘中;
- slave 在清空原有数据;
- 最后再将磁盘中接收到的数据导入内存中。
以上过程涉及到的开销:
-
master 节点需要 bgsave
-
RDB文件需要从 master 传递到 slave
-
slave 需要 flushdb 清空数据
-
salve 需要加载RDB
-
全量复制会触发从节点AOF重写
部分复制
- 如果网络抖动(连接断开 connection lost)
- 主机master 还是会写 repl_back_buffer(复制缓冲区)
- 从机slave 会继续尝试连接主机
- 从机slave 会把自己当前 run_id 和偏移量传输给主机 master,并且执行 pysnc 命令同步
- 如果master发现你的偏移量是在缓冲区的范围内,就会返回 continue命令
- 同步了offset的部分数据,所以部分复制的基础就是偏移量 offset。
常见运维
读写分离:master 读写,slave 只读;
主从配置不一致:例如maxmemory不一致,可能会造成丢失数据
规避全量复制:第一次全量复制不可避免,所以分片的maxmemory减小,同时选择在低峰(夜间)时,做全量复制。
复制积压缓冲区不足:增大复制缓冲区配置rel_backlog_size
例如:如果网络中断的平均时间是60s,而主节点平均每秒产生的写命令(特定协议格式)所占的字节数为100KB,则复制积压缓冲区的平均需求为6MB,保险起见,可以设置为12MB,来保证绝大多数断线情况都可以使用部分复制。
复制风暴: master节点重启,master节点生成一份rdb文件,但是要给所有从节点发送rdb文件。对cpu,内存,带宽都造成很大的压力