Redis4️⃣高可用策略:主从复制 & 哨兵模式 & 集群
1、主从复制
主从复制:主机数据更新后,根据配置和策略自动同步到从机。
- 说明:
- 主从复制是在多台服务器下的概念,通常是一主多从。
- Master 以写操作为主,Slaver 只能读操作。
- 作用:读写分离,性能扩展、容灾快速恢复。
1.1、case:一主两从
1.1.1、搭建
Hint:添加配置个数,即可实现多个从节点。
-
创建配置文件:为 3 个数据库实例分别创建配置文件,作为启动配置。
# redis6379.conf include /opt/etc/redis.conf pidfile /var/run/redis_6379.pid port 6379 dbfilename dump6379.rdb # redis6380.conf include /opt/etc/redis.conf pidfile /var/run/redis_6380.pid port 6380 dbfilename dump6380.rdb # redis6381.conf include /opt/etc/redis.conf pidfile /var/run/redis_6381.pid port 6381 dbfilename dump6381.rdb Copy
-
启动服务器:
redis-server redis6379.conf redis-server redis6380.conf redis-server redis6381.conf
-
配置从机:指定主服务器的主机端口号。
-
在命令行中运行,从服务器重启不再是从属于原来的主服务器。
-
将从机配置增加到文件中。永久生效。
slaveof <ip><port>
-
1.1.2、说明
- 主服务器可以读写操作(通常只写),从服务器只读。
- 若主服务器异常关闭,从服务器不会变成新的主服务器。
- 复制延时问题:从 Master 到 Slaver 的同步存在延迟。
- 原因:写操作先在 Master 上执行,再同步更新到 Slaver 上。
- 系统繁忙、Slaver 数目增加都会加重延迟问题。
1.1.3、复制原理
初连接
只要重连 Master,就会自动执行全量复制。
- Slaver 启动并成功连接到 Master 后,向 Master 发送
sync
同步命令。 - Master 接到命令,执行全量复制。
同步
- 全量复制:通常是 Slaver 连接时
- Master 启动后台存盘进程(folk),对数据进行持久化操作。
- Master 也会收集写操作命令。
- 后台进程执行完毕后,将 rdb 文件传输给 Slaver。
- Slaver 接收 rbd 文件并存盘,加载到内存中并读取备份。
- 完成一次全量复制(完全同步)。
- Master 启动后台存盘进程(folk),对数据进行持久化操作。
- 增量复制:通常是 Master 执行写操作后。
- Master 将所有收集到的写操作命令依次传给 Slaver,完成同步。
1.2、常用主从策略
原做法:Master 下有多个 Slaver,Master 崩溃将导致集群崩溃。
1.2.1、薪火相传
-
思想:Master 下只有一个直接的 Slaver,Slaver 之间形成链。
-
优点:降低 Master 的同步压力,去中心化。
说明
-
修改链中的主从关系:会清除之前的数据,同步最新数据。
-
当某个 Slaver 宕机,之后的 Slaver 无法备份。
-
Master 异常关闭后,无法进行写操作。
1.2.2、反客为主
思想:在薪火相传的基础上。
-
当链中某一台 Master 宕机,其直接的 Slaver 升为 Master。
-
之后的 Slaver 无需改变。
slaveof no one
2、哨兵模式(❗)
2.1、说明
反客为主的自动版
思想:后台监控主服务器是否故障,若故障则自动根据投票数将从库转换为主库。
步骤
-
创建
sentinel.conf
文件。/opt/etc/sentinel.conf
-
配置哨兵:
-
guardname:哨兵服务器名称。
-
master:哨兵监控的主服务器 IP 地址和端口号。
-
n:至少有 n 个哨兵同意才转换。
sentinel monitor [guardname] [master] [n]
-
-
启动哨兵:
redis-sentinel /opt/etc/sentinel.conf
2.2、选举规则
redis.conf
优先级别:值越小优先级越高(默认100)
- 旧版:slave-priority
- 新版:replica-priority
选取规则如下顺序
- 选择优先级靠前的(
redis.config
) - 选择偏移量大的(与主服务器的数据同步率最高的)
- 选择 runid 最小的服务(Redis 服务器实例启动时随机生成的 40 位二进制数)
3、集群
分析主从、哨兵模式
- 特点:集群节点仅主机、IP 地址不同,存储的数据相同。
- 节点服务器负载大。
- 不利于扩容。
- 无法分摊并发写操作。
- 配置问题:主服务器宕机时,从服务器升级为新的主服务器,此时客户端需要修改配置(主机、IP 地址)以访问新的主服务器。
3.1、集群
-
思想:通过分区(partition)实现对 Redis 的水平扩容,提高程序可用性。
-
每个分区都可以是主从复制或哨兵模式,通常是 3 个分区。
- 启动 N 个 Redis 节点,每个节点存储数据库中的 1/N 数据。
- 即使集群中有部分节点失效或者无法进行通讯,集群也可以继续处理命令请求。
-
配置方案:
代理主机(旧版) 无中心化集群配置(Redis 3) 含义 在客户端和 Redis 服务器设立代理服务器 Redis 服务器根据客户端请求的数据,自动在服务器之间跳转 图示
3.2、集群搭建
-
配置文件:
-
开启集群模式
-
节点配置文件名
-
节点失联时间:超过时间自动进行主从切换。
include /opt/etc/redis.conf pidfile /var/run/redis_6379.pid port 6379 dbfilename dump6379.rdb # 集群模式 cluster-enabled yes # 节点配置文件名 cluster-config-file nodes-6379.conf # 节点失联事件 cluster-node-timeout 15000
-
-
拷贝多个配置文件,启动多个 Redis 服务器实例。
-
合成集群:进入 src 目录,执行指令。
# 进入redis安装目录 cd /opt/redis-6.2.6/src # 合成集群 redis-cli --cluster create --cluster-replicas 1 IP地址
3.3、常见问题
3.3.1、集群节点分配
一个集群至少要有 3 个主节点。
- 选项
--cluster-replicas 1
:为集群中的每个主节点创建一个从节点。 - 分配原则:每个主数据库运行在不同的 IP 地址,从库和主库不在同一个 IP 地址。
3.3.2、hash slot
存储 Redistribution 数据库的 Key
- 一个 Redis 集群包含 16384 个槽位,通过公式计算 Key 所属的槽位。
- 插槽计算公式:
CRC16(key) % 16384
,其中 CRC16(key) 语句用于计算键 key 的 CRC16 校验和 。 - 集群的每个节点负责处理一部分插槽。
- 如:节点 A 负责 0 - 5460,节点 B 负责 5461 - 10922,节点 C 负责 10923 - 16383。
3.3.3、存取 Key
存值:向集群中添加一个 Key
- 计算位置:根据公式,计算 Key 所对应的 slot。
- 判断范围:若 slot 属于当前节点的范围中则添加,否则报错。
- 参数
-c
:当 slot 不属于当前节点范围时,自动重定向到对应节点。
取值:从集群中查询指定 Key
每个节点只能查询节点范围内的 slot。
-
计算位置:计算 Key 所对应的 slot
-
判断范围:若 slot 属于当前节点范围则返回,否则返回 null。
# 查询指定key的slot cluster keyslot <key> # 查询指定slot是否有值 cluster countkeysinslot <slot> # 返回slot中count个Key CLUSTER GETKEYSINSLOT <slot><count>
注意
- 不支持多键操作,如 mset、mget
- 原因:多个 Key 所计算的 slot 可能不是位于同一分区。
3.3.4、故障恢复
若主服务器下线超过指定时间,从服务器自动升为主服务器。
- 指定时间:
cluster-node-timeout 毫秒数
- 原来的主服务器重新上线后,变成新主服务器的从机(交换身份)
若某个分区的主从节点都宕机,Redis 集群是否能继续使用?
- 参数
cluster-require-full-coverage
- yes:整个集群都无法使用。
- no:仅该分区无法使用,不影响其它分区。
3.4、特点
- 优点:易于扩容,分摊压力,无中心化集群配置。
- 缺点:不支持多键操作和多键事务,不支持 lua 脚本。