看图说话-redis集群模式
介绍
数据量大,一台机器 资源有限,需要数据分片处理
存在的方案有:codis, redis cluster
本文主要讲redis cluster的内容
codis 分布式 Redis 解决方案
基本架构,中心化代理模式
优点 客户端透明,数据自均衡,高性能等,最多支持1024个节点
缺点 自有redis分支,与原版的redis分支不同步,中心化问题(瓶颈),某些命令不支持,社区不活跃
redis cluster
基本架构,去中心化 gossip协议
优点 高性能,高可用,去中心化,自带迁移功能,丰富的集群管理命令
缺点 client端实现复杂,迁移异常不能自动修复,节点太多占用带宽,不同slot指命令不支持
对比
\ | redis cluster | codis |
hash tag | y | y |
中心化 | n | y |
pipeline | 客户端设计 | 支持 |
slot | y | y |
多db | n | y |
性能 | 高 | 小于cluster |
client实现 | 复杂 | 简单 |
范围 | 广 | 也不少 |
常见数据分布算法
取模算法
实现原理:key进行hash后对节点数量取模
如果出现节点挂掉,数据影响范围
结论:实现简单,但出现节点挂掉,重新计算节点并进行取模时,数据丢失接近100%
扩容缩容时,为避免影响的数量量过大,需要二倍扩或直接减少一半缩
一致性hash算法
俗名hash环
将key取hash后,判断落在环的哪个位置,如果当前位置是节点位置,直接使用,如果不是,则顺时针顺延,找到最近的位置
问题,会出现数据倾斜的情况,使用虚拟节点解决
扩容缩容时,只会影响节点逆时针的一小块数据,影响范围小,不需要二倍扩和一半缩,同时可以根据机器性能,增加或减少虚拟节点来平衡负载情况
slot算法
0-16383个slot, slot = CRC16(key)&16383
cluster基本架构
功能流程介绍
节点 节点之间互相通信,节点支持读写
meet操作 节点间的互相通信,连接支持redis cluster的节点
槽分配 将16384个slot平均分配给节点
复制 用于高可用,每个节点都有对应的slave
槽分配
客户端路由
moved重定向
请求任意节点
槽命中直接返回
槽未命中返回moved异常,带有目标节点信息
重新请求目标节点
ask重定向
请求正确节点(未命中则moved后重定向),但正好迁移走了
返回ask异常,带有目标节点
重新请求目标节点
smart智能客户端
jedis初始化时,先随机请求一个节点,缓存slot与node映射关系,如果连接异常,则换一个活跃节点,如果5次都失败,则
Too many cluster redirection!
客户端请求时,jedis cluster计算slot,再通过映射关系,直接请求对应slot
如果遇到slot迁移,则更新jedis cluster后,重新目标节点
多节点命令实现
串行mget:利用for循环,多次每个key进行请求
串行IO:先对keys计算得到对应slot,再计算得到对应的节点,对每个节点发送一次请求,大大减少网络IO
并行io:串行IO的并行化
hash tag:利用hash tag,将同一tag数据分配到同一slot内,也就是同一节点,在请求时,只需要操作一个节点即可
四种方式对比
方案 | 优点 | 缺点 | 网络IO |
串行mget | 实现简单 | keys多延迟严重 | O(keys数量) |
串行IO | 实现简单 | 节点数量多延迟大 | O(节点数量) |
并行IO | 利用并行减少延迟 | 编程复杂,超时问题排查难 | O(最长延迟节点时间) |
hash tag | 性能高 | 操作复杂,数据倾斜 | O(1) |
高可用
redis cluster故障的原因:
至少一个slot不可用
集群中大多数mster处理pfail状态(类似sentinel中的odown)
故障发现
redis cluster 利用集群问的ping/pong心跳检测,不需要利用哨兵来管理
主观故障(pfail):节点间探测发现心跳超过timeout时,标记为pfail,并通过gossip传播
客观故障(fail):大多数节点认为pfail后,将状态变更为faiil,并广播fail消息同步fail状态
故障恢复
资格检查
准备选举时间
选举投票
扩展说明:
通过冗余slave,可以实现在某个master故障后,只一有个slave的情况下,该slave晋升master后,将冗余slave自动挂载到新master上