集群
复制
- 写命令落到主库,主库完成以后,在同步给从库,会有一定的时延性
- 读命令落到从库,读到的数据可能会有时延性
- 同步流程
- 当主库、从库上线后,首先进行握手并验证端口、IP 等信息。
- 当握手完成后,从库向主库发送
PSYNC命令,开启数据同步过程,并发送主库 ID(防止主库被人为切换)和复制偏移量 offset(用于断线续传) - 主库根据复制 ID、偏移量和复制积压缓冲区判断执行全量同步还是部分重同步
- 同步完成以后,命令传播阶段:主库状态被修改了(如增加了新数据,修改了原始数据)为了使得从库和主库数据状态一致,主库将会把数据变更命令发给从库,从库收到后执行命令
- 全量复制
- 主库执行BGSAVE,生成对应的RDB文件,同时开辟缓冲区,记录在RDB文件实行过程中,收到的新数据命令
- RDB文件产生后,主库发给从库,从库通过RDB恢复数据
- 部分重同步
- 从库与主库断线重连后,会优先尝试只复制断线期间缺失的数据。此过程依赖复制 ID、复制偏移量和复制积压缓冲区
- 复制 ID:标识主库的数据历史
- 复制偏移量:代表主节点传输了的字节数
- 复制积压缓冲区:复制积压缓冲区是一个先进先出队列,存储了最近主节点的数据修改命令
哨兵
- 即新建哨兵组,对主库从库统一进行监控,如果主库坏了,哨兵组进行投票,从从库中重新选出主库
- 本质上,从代码层面上讲,哨兵是一个不提供数据服务的 Redis 服务器
- Sentinel 会周期性地向主库、从库和其他 Sentinel 发送
PING等命令,并依据down-after-milliseconds判断实例是否在规定时间内有效响应。 - 单个 Sentinel 判断主库不可达时,将其标记为主观下线(SDOWN);当达到配置的 quorum 后,主库被判定为客观下线(ODOWN)。quorum 用于判断客观下线,不等同于故障转移授权所需的多数票。
- 多个 Sentinel 会先选出一个 Leader 来执行故障转移。Leader 再根据副本优先级、复制偏移量和运行 ID 等规则选择要晋升的从库;这两个选举过程不能混为一谈。
- Leader 向目标从库发送
REPLICAOF NO ONE使其成为主库,再让其他从库复制新主库,并向客户端提供新的主库地址。
- 如果旧主库重新上线,它会被 Sentinel 重新配置为新主库的从库。
集群模式
Cluster
- Redis提供的分布式数据库解决方案
- 自动将你的数据切分给多个节点存储
- 即使这些节点中一部分宕机,也可以继续执行数据操作
- 分区策略:
- Redis Cluster 使用 16384 个哈希槽,键所在槽位按
CRC16(key) mod 16384计算;使用 Hash Tag 时只对{...}中的内容计算。 - 每个 Redis Cluster 节点负责一部分槽数据的存储
- 并且该节点可以结合之前讲到的主从复制模式,将分配给它的数据进行复制
- Redis Cluster 使用 16384 个哈希槽,键所在槽位按
- 查询与重定向:
- 每个节点都会存储整个集群节点信息,这些信息也被称为元信息(每一个节点都有元数据信息)
- 各节点存储的槽数据
- 各节点的 master 和 slave 状态
- 各节点是否存活
- 集群节点通过 Cluster Bus 上的 Gossip 消息交换节点和槽位状态
- Gossip 协议是周期性的,每隔一定时间执行一次。
- 节点会选择若干其他节点传播信息。
- 每个节点都会存储整个集群节点信息,这些信息也被称为元信息(每一个节点都有元数据信息)
- 客户端可以连接任一节点,但节点不会代理普通请求:
- 如果目标槽由其他节点负责,返回
MOVED,客户端应刷新槽位映射并重试。 - 槽位迁移期间,源节点对已经迁走的 key 返回
ASK;客户端需要先向目标节点发送ASKING,再执行原命令。 MOVED表示槽位归属已经改变,ASK表示迁移期间的一次性重定向。
- 如果目标槽由其他节点负责,返回
- 扩缩容
- 增加或移除主节点时,需要在节点之间重新分配和迁移哈希槽;迁移期间客户端必须正确处理
ASK和MOVED。
- 增加或移除主节点时,需要在节点之间重新分配和迁移哈希槽;迁移期间客户端必须正确处理