文章目录
- 昨日内容复习
-
- [Redis 集群模式有哪些?](#Redis 集群模式有哪些?)
- [Redis 分布式锁的 RedLock 算法需要客户端向若干个 Redis 主节点发送加锁请求,此处的 Redis 主节点为什么可以有多个?方才不是说一个 Redis 集群只能有一个 Redis 主节点吗?](#Redis 分布式锁的 RedLock 算法需要客户端向若干个 Redis 主节点发送加锁请求,此处的 Redis 主节点为什么可以有多个?方才不是说一个 Redis 集群只能有一个 Redis 主节点吗?)
- [Redis 切片集群的原理?](#Redis 切片集群的原理?)
- 主从模式的同步过程?
- [复习 Redis Day6:集群(下)](#复习 Redis Day6:集群(下))
-
- 主服务器如何知道要将哪些数据发送给从服务器?
- 如何避免主从复制的不一致?
- [主从结构中过期的 key 如何处理?](#主从结构中过期的 key 如何处理?)
- 主从复制是同步复制还是异步复制?
- 什么是哨兵机制?
-
- [Sentinel 节点的作用是什么?](#Sentinel 节点的作用是什么?)
- [为什么需要至少 3 个 Sentinel 节点?](#为什么需要至少 3 个 Sentinel 节点?)
- [Redis Sentinel 选取新的主节点的流程](#Redis Sentinel 选取新的主节点的流程)
- 什么是集群的脑裂?
- [如何避免 Sentinel 集群模式下主从切换带来的数据丢失?](#如何避免 Sentinel 集群模式下主从切换带来的数据丢失?)
昨日内容复习
Redis 集群模式有哪些?
Redis 的集群模式包括主从模式、哨兵模式以及切片模式。
- 主从:通常选择一台服务器作为主服务器,若干台服务器作为从服务器,主从之间读写分离,主服务器可读可写,从服务器一般只读。主从服务器之间的命令复制异步,无法确保强一致性。
- 哨兵:是 Redis 官方提供的高可用方案,是普通主从模式的升级,引入 Sentinel 哨兵节点来管理 Redis 主从集群,实现自动故障检测及故障转移。具体来说,哨兵节点会监控主从集群中节点是否存在问题,如果从节点出现问题则告知集群管理员,如果主节点出现问题会自动在从节点当中选取新的主节点,确保 Redis 主从集群的可用性。通常需要 3 个及以上的哨兵节点,1 个主节点和 1 个及以上的从节点来构建 Sentinel 集群,Sentinel 节点之间通过 Raft 协议达成共识。
- 切片:Redis 切片集群将大规模的数据分布到不同的 Redis 节点上,以此来降低系统对单一主节点的依赖,提高 Redis 服务的读写性。具体来说,每个数据分片都有自己的主节点和从节点,且切片集群自带故障转移功能,即当数据切片的主节点宕机时,可以自动选举该切片的从节点为主节点继续提供读写服务。
需要着重强调的是 ,在 Redis 主从模式集群和哨兵模式集群当中,都只存在一个主节点,和若干个从节点。只有在 Redis Cluster 集群模式下才有可能出现多个 Redis 主节点,因为它们保存着不同分片的数据。
Redis 分布式锁的 RedLock 算法需要客户端向若干个 Redis 主节点发送加锁请求,此处的 Redis 主节点为什么可以有多个?方才不是说一个 Redis 集群只能有一个 Redis 主节点吗?
这个问题是我自己提出来的,也是在复习 Redis 的过程中困扰我比较久的。
实际上回答这个问题很简单,Redis 分布式锁的 RedLock 算法是客户端向若干个不同的 Redis 集群或 Redis 单例发送加锁请求。
此外需要注意的是,尽管 Redis Cluster 集群确实包含多个 Redis 主节点,但是 Redis Cluster 集群也不能用于实现 RedLock 算法,因为 RedLock 算法要求加锁的 Redis 实例是完全独立和隔离的,Redis Cluster 集群中的 Redis 主节点保存的是大型缓存的分片数据,不具备独立和隔离性。
综上所述,RedLock 算法中,客户端请求加锁的多个 Redis 主节点一定是不同的 Redis 实例,比如若干个 Redis 集群,或一部分 Redis 集群加上一部分 Redis 单例。
Redis 切片集群的原理?
通过哈希槽以及 CRC 算法来实现 key 到数据切片的映射。具体来说,通过 CRC 算法可以将 key 映射到 0~65536 之间的整形数据,再对 16384 取模,将 key 映射为 0~16384 之间的一个整形数据,16384 为切片集群的哈希槽槽数。
Redis 切片集群在创建时可以自动或手动地将哈希槽分配到具体的 Redis 节点。
主从模式的同步过程?
首先,从节点会建立与主节点之间的 socket 连接。
连接就绪之后,主节点开启 RDB 快照生成,并将生成期间的写命令写入同步缓冲区。
RDB 快照生成完成后,通过 socket 连接传输给从节点,从节点加载快照完成初次同步,再读取主节点同步缓冲区当中的写命令并加载,完成主从同步。
在主从模式下,主节点和从节点会各自维护一个 offset 字段,用于相互告知当前 Redis 数据的同步进度。
复习 Redis Day6:集群(下)

主服务器如何知道要将哪些数据发送给从服务器?
主从模式下,主从同步完成之后,主节点和从节点会自动维护一个 offset 字段,在增量同步时,主从节点比对 offset 来确定需要同步哪些增量数据。如果从节点下线后再次上线,要读取的数据在 repl_backlog_buffer 当中,则采用增量同步,否则重新进行全量同步。
如何避免主从复制的不一致?
无法完全避免,只能尽可能地降低主从复制的不一致程度。具体来说,可以让主从节点位于同一个机房,降低同步的延迟。或者由外部程序监控主从复制的进度,如果主从复制之间的进度差距大于阈值,让客户端不再访问从节点读取数据,而是直接访问主节点。
主从结构中过期的 key 如何处理?
从节点只读,因此不能给删除过期的 key,此时如果客户端访问从节点中过期的 key,仍然能够得到 value。从节点当中过期的 key 依赖于主节点同步 DEL 命令来删除。
主从复制是同步复制还是异步复制?
异步复制。主节点接收到写命令后,先写入缓冲区,再等待时机异步发送给从节点。异步复制确保了主从集群的高可用性。
什么是哨兵机制?
哨兵机制是对普通主从集群的升级,哨兵机制进一步为主从集群引入了故障监测与故障自动转移。具体来说,一个哨兵集群中会引入至少 3 个 Sentinel 哨兵节点,对 Redis 主从节点进行监视,并通过 Raft 协议确保彼此之间消息的一致性。当 Redis 从节点宕机时,会通知集群管理员,当主节点宕机时,为了确保服务可用,会自动选举一个从节点成为新的主节点,实现故障自动转移。一个哨兵集群需要至少 3 个 Sentinel 节点,1 个主节点以及 1 个及以上的从节点。
Sentinel 节点的作用是什么?
- 监控:持续监控 Redis 主从节点的健康状态;
- 自动故障转移:主节点不可用时,自动选举新的主节点,并重新配置其他从节点并复制新的主节点,更新客户端的连接信息;
- 客户端可以通过 Sentinel 节点自动发现当前可用的 Redis 主节点,故障发生时,自动更新配置信息并通知客户端。在这一点上,哨兵的作用类似于注册中心;
- 通过 API 或脚本发送 Redis 集群系统告警,以及时通知管理员当前集群的状态变化;
- 多个 Sentinel 节点形成共识集群,通过投票机制避免误判,确保故障检测和主节点转移决策的可靠性。
为什么需要至少 3 个 Sentinel 节点?
- 避免脑裂问题:如果只有 2 个哨兵节点,如果网络分区发生,那么 2 个节点会认为彼此都下线了,此时会选举出 2 个主节点。「一个可能出现脑裂的极端场景是:Redis Sentinel 集群中,Redis 主节点和少数 Sentinel 节点处于一个网络分区,而若干个从节点与多数 Sentinel 处于另外一个网络分区,此时有可能出现脑裂,即网络分区之间通信存在故障时可能同时出现两个 Redis 主节点。3 个节点可以避免脑裂问题的发生。」
- 3 节点配置可以容忍 1 个节点发生故障;
- 多个 Sentinel 节点的共识比一个单体判断更加可靠。
生产环境中通常部署 3 个或 5 个 Sentinel 节点(奇数个),这些节点应该分布在不同的物理机器或可用区上。
Redis Sentinel 选取新的主节点的流程
一. 故障检测阶段
- 主观下线:单个 Sentinel 节点检测到 Redis 主节点宕机;
- 客观下线:当多数 Sentinel 节点确认 Redis 主节点不可达时,客观上认为 Redis 主节点不可达。
二. 领导者选举阶段
- Sentinel 节点之间通过 Raft 算法推选一个领导者 Sentinel来执行故障转移;
- 每个 Sentinel 有平等的机会成为领导者。
三. 选举新的主节点
领导者 Sentinel 根据以下方式选取 Redis 从节点成为主节点:
- 网络连接状况:优先选择与原主节点断开时间最短的从节点;
- 复制偏移量:选择数据最完整的从节点;
- 运行 ID:如果多个从节点的状态相同,选取运行 ID 最小的从节点;
- 优先级配置:如果配置了
replica-priority
,优先级高的从节点会被选取。
四. 执行故障转移
- 被选中的从节点成为主节点;
- 其他从节点复制新的主节点;
- 旧的主节点故障恢复后成为从节点;
- 更新客户端的配置:通知所有客户端连接新的主节点。
五. 配置传播
- 更新所有 Redis 节点的配置;
- 持久化新的配置。
选举算法细节
- 使用 Raft 算法实现分布式共识;
- 每个 Sentinel 有 1 票,需要多数票才能成为 Sentinel 领导者;
- 选举有超时机制,避免长时间无法达成共识。
什么是集群的脑裂?
一个 Redis Sentinel 集群当中,如果 Redis 主节点突然与集群失联,而此时客户端向主节点写入数据,此时写入的数据会赞存在缓冲区当中。Sentinel 集群发现主节点丢失,会推举领导者 Sentinel 在从节点中推举新的主节点。旧的主节点重新上线之后,由于此时已经有了新的主节点,会短暂地出现两个主节点同时存在的情况,此之谓集群的脑裂。
旧的主节点发现已经有新的主节点之后,会自动降级为从节点,然后从新的主节点通过全量同步的方式同步数据,方才客户端的写命令由于没有写入到新的主节点当中,会丢失。因此集群的脑裂会造成短暂的数据不一致。
如何避免 Sentinel 集群模式下主从切换带来的数据丢失?
异步复制同步丢失
主节点仅在足够多的从节点同步了数据时才会允许写入操作,避免数据未同步就宕机。如果从节点延迟超过阈值或从节点数量不足,主节点会拒绝写入。
合理配置 Sentinel 参数
适当延长 Sentinel 判断主节点客观下线的延迟时间,避免由于网络抖动而产生脑裂,导致数据不一致。