上一节:
Redis技术指南-5-理解内存
上一节聊了Redis内存,这一节我们来理解一下Redis的高可用和分区知识:哨兵和集群
Redis的主从复制模式下,一旦主节点故障,需要人工把从节点提升为主节点(slaveof no one),同时还需要通知应用方更新主节点地址。无法接受,主要是不是自动的,比较麻烦。
那么如何自动,如何高可用。sentinel实际上是一种监控节点程序。
redis-2.8以上,更稳定
从架构上来看,Sentinel节点集合会定期对所有节点进行监控,特别是对主节点的故障自动转移。
1、 当主节点发生故障后,sentinel集合发现问题后
2、超过2个sentinel同意(可以在sentinel启动时配置),才能准备下线主节点。
3、通过选举sentinel的领导者(其中一个sentinel)负责故障转移。
高可用在于负责故障处理的sentinel是高可用的。
raft算法。
虽然已经有客观下线了,但是注意不会立即故障转移,而是先选取出一个领导者Sentinel
选举思路:
1、每个sentinel都可能称为leader,当它确认主节点客观下线,发送sentinel is-master-down-by-addr给其他sentinel,要求把自己设置为leader
2、收到命令的sentinel,如果没有同意过其他sentinel的上述命令,则通过,否则拒绝,其实每个sentinel只能投票一次。
3、如果该Sentinel 节点发现自己的票数已经大于等于 max(quorum, num(sentinels ) / 2 + ), 那么它将成为leader。
4、如果此过程中没有选举出领导者,将进入下一次选举。
高可用读写分离,节点运维(最好有可视化页面和脚本)
Sentinal优点
解决了主从模式中出现故障不能自动切换故障的问题
缺点:
第二三点
1、主节点故障不能自动转移 --高可用
2、主节点的写能力受到单机限制 --分布式
只有一台主机接受并处理写命令,容易受到单机瓶颈。
3、主节点的存储能力受到单机限制 --分布式
所有数据节点都是全量数据,没有真正的分布式存储。数据量过大时,影响主从同步性能。
那么Redis Cluster 如何做到分布式高可用呢? --分区
分布式数据库最核心的数据分散问题,把数据集划分到多个节点上。
其中,重点关注的是数据分区规则。
两种:
哈希分区
数据离散好、数据分布业务无关、无法顺序访问
顺序性
数据离散查、数据分布业务相关、可顺序访问
1、节点取余分区
hash(key) % N N一般为表数
简单、但是扩容时肯有可能造成全量迁移。一般扩容两倍
2、一致性哈希分区
每个节点分配一个tocken 范围 0~2^32 这些token形成一个哈希环。数据查找时,先根据key计算hash值,然后顺时针找到第一个大于等于该hash值的token节点。
缺点:少量节点时,节点变化会大范围影响hash环中数据映射。
加减节点都会造成哈希环中部分数据无法命中,需要手动处理或者忽略这一部分数据,一般用于缓存场景。
3、哈希槽
虚拟槽分区,使用新的hash函数,映射到0~16383的槽范围上。
每个节点分配一批槽位。这样方便数据拆分和集群管理。
新增删除节点时,临近节点会承担和处理多余或者少的槽位的数据迁移。
特点:
1、解耦数据和节点之间的关系,简化了节点扩容和收缩难度。
2、节点自身维护槽映射关系,不需要客户端或者代理服务维护槽分区元数据
3、支持节点、槽、键之间的映射查询,用于数据路由、在线伸缩等场景。
直接看pdf吧,这块挺多的。核心思想就是多个master 分区存储数据,然后每个节点都有各个节点的通信状态。 很多master 也会有自己的slave
常见的元数据维护方式 : 集中式和P2P方式。
Redis-Cluster采用P2P方式(Gossiop留言)协议。其工作原理其实就是不停的节点数据交换。一段时间后所有节点都会知道集群完整的信息。
通信过程:
1、集群中的每个节点都会单独开辟一个TCP通道,用于及其他节点之间彼此通信,通信端口号在基础端口上加10000
2、每个节点在固定周期内通过特定规则选择几个节点发送ping消息。
3、接收到ping消息的节点用pong消息作为响应。
Gossip协议的主要职责就是信息交换。信息交换的载体就是节点彼此发送的Gossip消息,了解这些消息有助于我们理解集群如何完成信息交换。
伸缩原理: 负责相邻节点的部分数据、槽位迁移
集群模式: 一般是用客户端访问,而不是代理方式。
如果是单机到集群,需要更新客户端代码。
分为三个方面介绍:
1、请求重定向 --判定性
集群模式下,Redis接受任何命令首先计算键对应的槽,在根据槽找到对应的节点。如果节点是自身,直接处理。如果不是,恢复MOVED重定向错误,通知客户端请求正确的节点。
2、Smart客户端
大部分开发语言的Redis客户单都支持Smart客户端支持集群协议。
smart客户端内部维护了slot -> node 的映射关系,本地就可以实现键到及节点的查找,节省IO, 而moved重构定向错误负责协助客户端更新slot -> node映射。
3、ASK重定向 --临时性
在线迁移slot和数据来做水平伸缩,此时ASK替代Moved角色,但是注意不会更新客户端slot -> node缓存。
而是给客户端 数据在迁移后的目标ip,此时客户端收到此异常后,找对应ip主机即可。
moved相当于是已经迁移完成了,整个事情过后的异常响应。
发现
主观下线: 集群A节点定期拿到其他所有节点的pong消息,如果超时,则认为B节点有问题。
客观下线: 当A判定B节点主观下线后,相应的节点状态会随着消息在集群内传播。
通过Gossip消息传播,集群内节点不断收集到故障节点的下线报告。当半数以上只有槽的主节点都标记某个节点是主观下线时。触发客观下线流程。
恢复
其实就是被下线节点需要在自己的从节点中选出一个替换自己。
下一节
Redis技术指南-7-缓存设计