前言
  • Redis集群可以分为三种模式:主从模式、哨兵模式、集群模式。

  • 主从模式,基于BGSAVE命令实现主从数据的同步,但是如果主节点挂掉,需要手动去切换。

  • 哨兵模式,基于哨兵集群实现主从切换,可以看作是对简单主从模式到扩展

  • 集群模式,需要注意的是,哨兵模式下,多个服务器redis存储的是相同的数据,比较浪费,集群模式可以看作是redis的分布式存储

  • Redis 哨兵模式主要是为Redis主从同步架构服务的,有时候主节点宕机,需要哨兵进行监控、通知,选举。

哨兵是干什么用的?

sentinel,中文名是哨兵。哨兵是 redis 集群机构中非常重要的一个组件,主要有以下功能:
在这里插入图片描述

  • 集群监控:负责监控 redis master 和 slave 进程是否正常工作。
  • 消息通知:如果某个 redis 实例有故障,那么哨兵负责发送消息作为报警通知给管理员。
  • 故障转移:如果 master node 挂掉了,会自动转移到 slave node 上。
  • 配置中心:如果故障转移发生了,通知 client 客户端新的 master 地址。

哨兵用于实现 redis 集群的高可用,本身也是分布式的,作为一个哨兵集群去运行,互相协同工作。

故障转移时,判断一个 master node 是否宕机了,需要大部分的哨兵都同意才行,涉及到了分布式选举的问题。
即使部分哨兵节点挂掉了,哨兵集群还是能正常工作的,因为如果一个作为高可用机制重要组成部分的故障转移系统本身是单点的,那就很坑爹了。

哨兵选举流程
  1. 每个在线的哨兵节点都可以成为领导者,当它确认主节点下线时,会向其他哨兵发is-master-down-by-addr命令,征求判断并要求将自己设置为领导者,由领导者处理故障转移

  2. 当其他哨兵收到此命令时,可以同意或者拒绝它成为领导者;

  3. 如果哨兵3发现自己在选举的票数大于等于哨兵的个数/2+1时,将会成为领导者,如果没有超过,继续选举。

在这一点上,与Raft协议有些相像的。

Redis Cluster 集群模式相关介绍

Redis-Cluster采用去中心化结构,它的特点如下:

  • 所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽。

  • 节点的fail是通过集群中超过半数的节点检测失效时才生效。

  • 客户端与redis节点直连,不需要中间代理层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。

  • 集群模式下,也引入了主从架构,每个主节点至少需要有一个从节点做备份,从节点与主节点保存相同的数据,一般情况下,从节点也会用来读。
    在这里插入图片描述

上图的slot我们后面再说是什么。

Redis Cluster模式下的通信

  • 采用gossip协议,又称传染病协议,非常的易懂。Gossip 过程是由种子节点发起,当一个种子节点有状态需要更新到网络中的其他节点时,它会随机的选择周围几个节点散播消息,收到消息的节点也会重复该过程,直至最终网络中所有的节点都收到了消息。

  • 这个”传染“过程可能需要一定的时间,由于不能保证某个时刻所有节点都收到消息,但是理论上最终所有节点都会收到消息,因此它是一个最终一致性协议

  • 相关过程可参考gossip过程

redis cluster的hash slot算法

  • redis cluster有固定的16384hash slot,对每个key计算CRC16值,然后对16384取模,可以获取key对应的hash slot

  • redis cluster中每个master都会持有部分slot,比如有3个master,那么可能每个master持有5000多个hash slot

  • hash slot让node的增加和移除很简单,增加一个master,就将其他master的hash slot移动部分过去,减少一个master,就将它的hash slot移动到其他master上去,而移动hash slot的成本是非常低的。

  • 客户端api,通过hash tag127.0.0.1:7000>CLUSTER ADDSLOTS 0 1 2 3 4 ... 5000 可以将槽0-5000指派给节点7000负责。每个节点都会记录哪些槽指派给了自己,哪些槽指派给了其他节点。

  • 客户端向节点发送键命令,节点要计算这个键属于哪个槽,如果是自己负责这个槽,那么直接执行命令,如果不是,向客户端返回一个MOVED错误,指引客户端转向正确的节点。

为什么是16384个槽?

  • 使用16k的插槽,心跳包是2k,使用65k的插槽,心跳包是8k
  • redis设计原因,节点超不过1000,16k够用

为什么Redis集群模式不用一致性哈希?

  • 删除节点就会把当前节点所有数据加到它的下一个节点上。这样会导致下一个节点使用率暴增,可能会导致挂掉,如果下一个节点挂掉,下下个节点将会承受更大的压力,最终导致集群雪崩
  • 一致性哈希的节点分布基于圆环,无法很好的手动设置数据分布,比如有些节点的硬件差,希望少存一点数据,这种很难操作。而哈希槽可以很灵活的配置每个节点占用哈希槽的数量,这是因为Redis Cluster的槽位空间是可以用户手动自定义分配的,类似于 windows 盘分区的概念。
  • 一致性哈希的某个节点宕机或者掉线后,当该机器上原本缓存的数据被请求时,会从数据源重新获取数据,并将数据添加到失效机器后面的机器,这个过程被称为 “缓存抖动” ,而使用哈希槽的节点宕机,会导致一定范围内的槽不可用,只能通过主从复制加哨兵模式保证高可用。
  • 相对于哈希槽,一致性哈希算法更复杂

参考

Redis 集群的三种实现方式

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐