参考 redis之哨兵集群
参考 Redis 高可用篇:你管这叫 Sentinel 哨兵集群原理
参考 Redis 高可用篇:Cluster 集群能支撑的数据有多大?
参考 Redis 高可用篇:你管这叫主从架构数据同步原理?
Redis高可用实现方式
Redis-Sentinel哨兵
是redis官方推荐的高可用性解决方案
哨兵通过监控、自动切换主库、通知客户端实现故障自动切换
redis 主从复制
-
可将主节点数据同步给从节点
-
从节点此时有两个作用
- 一旦主节点宕机,
从节点作为主节点的备份可以随时顶上来 - 扩展主节点的读能力,分担主节点读压力。
- 一旦主节点宕机,
-
问题
- redis本身或者客户端都没有实现主从切换的功能。
- 需要人为修改所有应用方的主节点地址
- 需要命令所有从节点复制新的主节点
当用redis作master-slave的高可用时
- 如果master本身宕机,
- redis-sentinel就是一个独立运行的进程
- 用于监控多个master-slave集群
- 自动发现master宕机,进行自动切换slave > master。
Redis Cluster 集群
主要解决了大数据量存储导致的各种慢问题,同时也便于横向拓展。
两种扩展方式
-
垂直扩展(scale up)
-
升级单个 Redis 的硬件配置
-
比如增加内存容量、磁盘容量、使用更强大的 CPU。
-
问题
- 当数据量大并且使用 RDB 实现持久化
- 会造成阻塞导致响应慢
- 拓展内存的成本太大
-
-
水平扩展(scale out)
-
一台机器无法保存所有数据,那就多台分担。
-
横向增加 Redis 实例个数
-
每个节点负责一部分数据。
-
优势
- 便于拓展
- 不需要担心单个实例的硬件和成本的限制
-
问题
- 切片集群会涉及多个实例的分布式管理问题,
- 需要解决如何将数据合理分布到不同实例
- 同时还要让客户端能正确访问到实例上的数据
-
-
那这两种方案都有什么优缺点呢?
横向扩展的 Redis 切片集群
Redis 集群是一种分布式数据库方案
-
集群通过分片(sharding)来进行数据管理
-
数据切片后,需要将数据分布在不同实例上,数据和实例之间如何对应上呢?
-
将数据划分为 16384 的 slots,每个节点负责一部分槽位
-
为啥要手动制定呢?
-
能者多劳,让牛逼的机器多支持一点。
-
哈希槽又是如何映射到 Redis 实例上呢?
-
将 key 通过 CRC16 计算出一个值再对 16384 取模得到对应的 Slot
-
槽位的信息存储于每个节点中。
-
举例
-
node1
- 0-5400
-
node2
- 5401-10008
-
node3
- 10009-16383
-
三个节点相互连接组成一个对等的集群
-
它们之间通过 Gossip协议相互交互集群信息
-
最后每个节点都保存着其他节点的 slots 分配情况
-
Redis 集群如何实现高可用呢?
-
复制功能
- Master 用于处理槽
- Slave 节点则通过《Redis 主从架构数据同步》方式同步主节点数据。
- 当 Master 下线,Slave 代替主节点继续处理请求。
- Master 与 Slave 还是读写分离么?
- 主从节点之间并没有读写分离, Slave 只用作 Master 宕机的高可用备份。
- Redis Cluster 可以为每个主节点设置若干个从节点
- 单主节点故障时,集群会自动将其中某个从节点提升为主节点。
- 如果某个主节点没有从节点,那么当它发生故障时,集群将完全处于不可用状态
-
故障检测
- 一个节点认为某个节点失联了并不代表所有的节点都认为它失联了
- 只有当大多数负责处理 slot 节点都认定了某个节点下线了,集群才认为该节点需要进行主从切换
- Redis 集群节点采用 Gossip 协议来广播自己的状态以及自己对整个集群认知的改变
- 如果一个节点收到了某个节点失联的数量 (PFail Count) 已经达到了集群的大多数,就可以标记该节点为确定下线状态 (Fail)
- 然后向整个集群广播,强迫其它节点也接收该节点已经下线的事实,并立即对该失联节点进行主从切换。
-
故障转移
- Cluster 又如何实现故障自动转移呢?
- 当一个 Slave 发现自己的主节点进入已下线状态后
- 从节点将开始对下线的主节点进行故障转移。
-
选主流程
- 新的主节点如何选举产生的?
- 从下线的 Master 及节点的 Slave 节点列表选择一个节点成为新主节点
- 新主节点会撤销所有对已下线主节点的 slot 指派,并将这些 slots 指派给自己
- 新的主节点向集群广播一条 PONG 消息
- 让集群中的其他节点立即知道这个节点已经由从节点变成了主节点
- 新的主节点开始接收处理槽有关的命令请求,故障转移完成。
客户端又怎么确定访问的数据到底分布在哪个实例上呢?
- Redis 实例会将自己的哈希槽信息通过 Gossip 协议发送给集群中其他的实例
- 实现了哈希槽分配信息的扩散。
- 集群中的每个实例都有所有哈希槽与实例之间的映射关系信息
Redis 如何告知客户端重定向访问新实例呢?
-
MOVED 错误
-
ASK 错误
- 如果某个 slot 的数据比较多,部分迁移到新实例,还有一部分没有迁移咋办?
有了 Redis Cluster,再也不怕大数据量了,我可以无限水平拓展么?
- Redis 官方给的 Redis Cluster 的规模上线是 1000 个实例
到底是什么限制了集群规模呢?
- 关键在于实例间的通信开销
- Cluster 集群中的每个实例都保存所有哈希槽与实例对应关系信息(Slot 映射到节点的表)以及自身的状态信息
XMind - Trial Version