一. Redis 主从集群
1.1 基本概念
- 主从架构:Redis主从集群采用“一主多从”的架构模式,其中主节点(Master)负责处理客户端的读写请求,而从节点(Slave)则负责处理读请求。这种读写分离的设计使得Redis能够充分利用多核CPU的优势,提高整体的读写性能。
- 数据同步:主节点会将写操作的数据同步到从节点,保证数据的一致性。当主节点出现故障时,可以从从节点中选取一个作为新的主节点,继续提供服务,实现故障转移。
1.2 搭建主从集群
单节点 Redis 的并发能力是有上限的,要进一步提高 Redis 的并发能力,就需要搭建主从集群,实现读写分离。
我们可以采用Docker-Compose 的方式启动多台Redis 容器 (注意:下面只是启动服务并没有绑定主从关系)
Docker配置文件的基础内容
建立集群
虽然我们启动了3个 Redis 实例,但是他们并没有形成主从关系。我们需要通过命令配置主从关系:
salveof <masterip> <masterport>
replicaof <masterip> <masterport>
有临时和永久两种模式:
- 永久生效:在 redis.conf 文件中利用 slaveof 命令指定 master 节点
- 临时生效:直接利用 redis-cli 控制台输入 slaveof 命令,指定 master 节点
1.3 主从同步原理
当主从第一次同步连接或断开重连时,从节点都会发送 psync 请求,尝试数据同步:
- replicatonID: 每一个 master 节点都有自己的的唯一 id, 简称 replid
- offset: repl_backlog 中写入过的数据长度,写操作越多,offset 值越大,主从对 offset 一致代表数据一致。
可以从以下几个方面来优化 Redis 主从集群群:
- 在 master 中配置 repl-diskless-sync yes 启用无磁盘复制,避免全量同步时的磁盘 IO
- Redis 单节点上的内存占用不要太大,减少 RDB 导致的过多磁盘 IO
- 适当提高 repl_baklog 的大小,发现 slave 宕机时尽快实现故障恢复,尽可能避免全量同步
- 限制一个 master 上的 slave 节点数量,如果实在是太多 slave, 则可以采用 主-从-从链式结构,减少 master 压力
1.4 总结
简述全量同步和增量同步区别?
- 全量同步:master 将完整内存数据生成 RDB, 发送 RDB 到 slave
- 增量同步:slave 提交自己的 offset 到 master, master 获取 repl_baklog 中 slave 的 offset 之后的命令给 slave
什么时候执行全量同步?
- slave 节点第一次连接 master 节点时
- slave 节点断开时间太久,repl_baklog 中的 offset 已经被覆盖时
什么时候执行增量同步?
- slave 节点断开又恢复,并且在 repl_baklog 中能找到 offset 时
二. 哨兵原理
2.1 基本作用
Redis 提供了哨兵 (Senntiel)机制来是实现主从集群的自动故障恢复。哨兵的具体作用如下:
- 监控:Sentinel 会不断检查您的 master 和 slave 是否按预期工作
- 自动故障切换: 如果 master 故障,Sentinel 会将一个slave 提升为 master。当故障实例恢复后也以新的 master 为主
- 通知:当集群发生故障转移时,Sentinel 将最新节点角色信息推送给 Redis 客户端。
2.2 服务状态监控
Sentinel 基于心跳机制监测服务状态,每隔1秒向集群的每个实例发送 ping 命令:
- 主观下线:如果某 sentinel 节点发现某实例未在规定时间响应,则认为该实例主观下线
- 客观下线:如果超过指定数量 (quorum) 的 sentinel 都认为该实例主观下线,则该实例客观下线。 quorum 值最好超过Sentinel 实例数量的一半。
选举新的 master
一旦发现 master 故障,sentinel 需要在 slave 中选择一个 作为 新的 master, 选择的依据是这样:
- 首先会判断 slave 节点与 master 节点断开时间长短,如果超过指定值 (down-after-millseconds * 10) 则会排除该 slave 节点
- 然后判断 slave 节点的 slave-priority 值,越小优先级越高,如果是0则永不参与 选举
- 如果 slave-priority 一样,则判断 slave 节点的 offset 值,越大说明数据越新,优先级越高
- 最后是判断 slave 节点运行 id 大小,越小优先级越高。
如何实现故障转移
当选中其中一个 slave 为新的 master 后 (例如 slave1), 故障的转移的步骤如下:
- sentinel 给备选的 slave1 节点发送 slaveof no one 命令,让该节点成为 master
- sentinel 给所有其他 slave 发送 slaveof 192.168.150.101 7002 命令,让这些 slave 成为新 master 的从节点,开始从新的 master 上同步数据
- 最后, sentinel 将故障节点标记为 slave,当故障节点恢复后会自动成为新的 master 的 slave 节点
2.3 总结
Sentinel 的三个作用是什么?
- 监控
- 故障转移
- 通知
Sentinel 如何判断一个 redis 是否健康?
- 每隔1秒发送一次ping 命令,如果超过一定时间没有回应则认为是主观下线
- 如果大多数 sentnel 都认为是主观下线,则判断服务下线 (客观下线)
故障转移步骤有哪些?
- 首先选定一个 slave 作为 新的 master, 执行 slaveof no one
- 然后让所有节点都执行 slaveof 新 master
- 修改故障节点,执行slaveof 新 master