redis在单机模式下,受限于内存容量,无法缓存更多的数据,超过一定量的数据,redis会采取一定策略清理数据。

所以,从reids3.0开始提供集群功能,集群中提供多个master,每个master存储一部分数据,这样就能应对海量数据了。

redis cluster架构下,会自动进行数据分片,每个master上放一部分数据。每个master下可以挂多个slave,当master故障的时候,可以发生主备切换,使其具备高可用性。

redis集群测试 redis集群rehash_数据

图1 redis集群

1、分布式系统数据分布方式

分布式数据分布方式,一般有hash方式,一致性hsah方式,redis集群的hash slot方式。

(1)hash方式

hash方式,就是根据key的哈希值值对节点数据取模计算余数,比如有3个节点,hash=1342,对3取模余数是1,数据就一定分布在节点2上。

redis集群测试 redis集群rehash_redis集群测试_02

图2 哈希取模

这种数据分布方式最最简单,但问题也很明显。
 

一旦某个master节点挂掉了,整个集群缓存的数据基本都会失效掉。

比如原来是有3个节点的,对3取模,数据分布在3个节点上,现在只有2个节点,同样的key对2取模,数据分布很可能就不再原来的机器上了。

假如master1挂掉了,对hash=1341取模,得到的余数是0,数据就会分不到节点2上。

redis集群测试 redis集群rehash_数据_03

图3 哈希取模,一个节点故障

(2)一致性哈希方式

一致性哈希是假设有一个圆环,节点机器分布在圆环的不同地方。对key的hash值映射到具体的节点上,比如key%N,key是数据的key,N是机器节点数,

redis集群测试 redis集群rehash_redis集群测试_04

图4 一致性哈希

如图所示。数据的存储时,先对key计算一个hash值,对应到这个环中的每个位置,如k1对应到了图中所示的位置,然后沿顺时针找到一个机器节点B,将k1存储到B这个节点中。

如果B节点宕机了,则B上的数据就会落到C节点上,如下图所示:

redis集群测试 redis集群rehash_redis集群测试_05

图5 一致性哈希一个节点故障

这样,只会影响C节点,对其他的节点A,D的数据不会造成影响。但如果有热点数据,很可能会引发“雪崩”。即C节点由于承担了B节点的数据,所以C节点的负载会变高,C节点很容易也宕机,这样依次下去,这样造成整个集群都挂了。所以此时引入了虚拟节点的概念。

想象在这个环上有很多“虚拟节点”,数据的存储是沿着环的顺时针方向找一个虚拟节点,每个虚拟节点都会关联到一个真实节点 ,如下图所使用:

redis集群测试 redis集群rehash_取模_06

图6 带虚拟节点的一致性哈希

图中的A1、A2、B1、B2、C1、C2、D1、D2都是虚拟节点,机器A负载存储A1、A2的数据,机器B负载存储B1、B2的数据,机器C负载存储C1、C2的数据。由于这些虚拟节点数量很多,均匀分布,因此不会造成“雪崩”现象。

(3)redis cluster slot方式

redis cluster有固定16384个hash slot(2^14),对每个key计算CRC16值,然后对16384取模,可以获取key对应的hash slot。

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

redis集群使用hash slot方式分布数据,使节点的增加和删除很简单,假如增加一个master,就将其他master的hash slot移动部分过去,如果减少一个master,就将它的hash slot移动到其他master节点上去,另外移动hash slot成本是非常低的。

redis集群测试 redis集群rehash_取模_07

图7 redis cluster hash slot

2、redis cluster原理

redis cluster节点将节点元数据存储在各个节点上,节点间通过gossip协议进行通信,比如故障信息、节点的增加和移除、hash slot信息等等。gossip是一种最终一致性的协议,所以节点之间同步数据的时候可能会有延迟。

每个节点都有一个专门用于通信的端口,就是自己对外提供服务的端口号 + 10000,比如对外提供服务的端口6379,那么节点通信的端口就是16379。

redis集群测试 redis集群rehash_redis_08

图8 redis cluster节点间通信

Gossip协议的主要职责就是信息交换,信息交换的载体就是节点之间彼此发送的Gossip消息,常用的Gossip消息有ping消息、pong消息、meet消息、fail消息 。

redis cluster高可用原理与redis sentinel很类似,如果一个节点认为一个另一个节点宕机了,那么就是pfail(主观宕机),如果多个节点都认为另一个节点宕机了,那么就是fail。

每个从节点,根据自己对master复制数据的offset,来设置一个选举时间,offset越大的节点,选举越靠前。

所有的master节点开始投票,给所有的slave进行投票,如果大部分(master node(N / 2 + 1)都投票给了某个从节点,那么选举通过,从节点执行主备切换,成为master节点。

END