vlambda博客
学习文章列表

看图说话-redis集群模式

介绍


数据量大,一台机器 资源有限,需要数据分片处理


存在的方案有:codis, redis cluster


本文主要讲redis cluster的内容


codis 分布式 Redis 解决方案


基本架构,中心化代理模式



  • 优点 客户端透明,数据自均衡,高性能等,最多支持1024个节点

  • 缺点 自有redis分支,与原版的redis分支不同步,中心化问题(瓶颈),某些命令不支持,社区不活跃


redis cluster


基本架构,去中心化 gossip协议


看图说话-redis集群模式


  • 优点 高性能,高可用,去中心化,自带迁移功能,丰富的集群管理命令

  • 缺点 client端实现复杂,迁移异常不能自动修复,节点太多占用带宽,不同slot指命令不支持


对比

\ redis cluster codis
hash tag y y
中心化 n y
pipeline 客户端设计 支持
slot y y
多db n y
性能 小于cluster
client实现 复杂 简单
范围 广 也不少


常见数据分布算法


取模算法


实现原理:key进行hash后对节点数量取模


看图说话-redis集群模式


如果出现节点挂掉,数据影响范围


看图说话-redis集群模式


结论:实现简单,但出现节点挂掉,重新计算节点并进行取模时,数据丢失接近100%

扩容缩容时,为避免影响的数量量过大,需要二倍扩或直接减少一半缩


一致性hash算法


俗名hash环

将key取hash后,判断落在环的哪个位置,如果当前位置是节点位置,直接使用,如果不是,则顺时针顺延,找到最近的位置


看图说话-redis集群模式


问题,会出现数据倾斜的情况,使用虚拟节点解决


看图说话-redis集群模式


扩容缩容时,只会影响节点逆时针的一小块数据,影响范围小,不需要二倍扩和一半缩,同时可以根据机器性能,增加或减少虚拟节点来平衡负载情况


slot算法


0-16383个slot, slot = CRC16(key)&16383


cluster基本架构


功能流程介绍


  • 节点 节点之间互相通信,节点支持读写

  • meet操作 节点间的互相通信,连接支持redis cluster的节点

  • 槽分配 将16384个slot平均分配给节点

  • 复制 用于高可用,每个节点都有对应的slave


看图说话-redis集群模式


槽分配


看图说话-redis集群模式


客户端路由


  • moved重定向

    1. 请求任意节点

    2. 槽命中直接返回

    3. 槽未命中返回moved异常,带有目标节点信息

    4. 重新请求目标节点


看图说话-redis集群模式


  • ask重定向

    1. 请求正确节点(未命中则moved后重定向),但正好迁移走了

    2. 返回ask异常,带有目标节点

    3. 重新请求目标节点


看图说话-redis集群模式


  • smart智能客户端

    1. jedis初始化时,先随机请求一个节点,缓存slot与node映射关系,如果连接异常,则换一个活跃节点,如果5次都失败,则Too many cluster redirection!

    2. 客户端请求时,jedis cluster计算slot,再通过映射关系,直接请求对应slot

    3. 如果遇到slot迁移,则更新jedis cluster后,重新目标节点


   看图说话-redis集群模式


多节点命令实现


  • 串行mget:利用for循环,多次每个key进行请求

看图说话-redis集群模式

  • 串行IO:先对keys计算得到对应slot,再计算得到对应的节点,对每个节点发送一次请求,大大减少网络IO

看图说话-redis集群模式

  • 并行io:串行IO的并行化

看图说话-redis集群模式

  • 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上