周氏一族,整理技术文档,给下一代留点教程......


目前,项目用的redis主备,感觉超不爽,很多局限性,特别是在 redis master 宕机之后,维护非常麻烦,寻思着弄一个redis集群,可不,总算到了今年10.1,redis发布了cluster版本。开启摸索之路...


很多人,一看到官网有最新的cluster版本,满怀热血,第一件事,就是搭建cluster环境,其实,鄙人却不,还是要从基层走起,先来了解一下官方信息,整理成下面的,大部分都是根据网络上整理出来的,又存在相同,纯属借鉴,往见谅!!!


redis主备面临的问题需求

1、主备模式,过于单一,特别是主服务器宕机的情况下,数据没法写入。

2、业务发展,数据庞大,主备必须同步相同数据,对存储需求较大,有点多余

3、虽然说有sentinel,但是效率还是非常低


Redis集群是一个可以在多个 Redis 节点之间进行数据共享的设施。 这一点毫无疑问的!

Redis集群通过分区来提供一定程度的可用性:即使集群中有一部分节点失效或者无法进行通讯, 集群也可以继续处理命令请求。

Redis 集群提供了以下两个好处:

(1)将数据自动切分(split)到多个节点的能力。

           面临大数据时代,集群,就是得要能实现一台宕机,不影响整个集群运作,换句话说,数据得每台机器都必须拥有对方的data,但是这样由于业务的慢慢扩展,数据会原来越大,很明显对存储比较吃力。redis在这一点上面,做得比较完美,那就是"切片"。通过内部 “私有算法技术”,把data分布式存储到集群机器,当要读取数据时,再通过 “私有内部算法” 映射到对应机器读取。


(2)当集群中的一部分节点失效或者无法进行通讯时, 仍然可以继续处理命令请求的能力。

          因为在3.0版本当中,redis采用master n-1 salver的模式,也就是说,一台master主,就若干台备,甚至没有备也行,但是本人强烈建议要1:1的模式,条件允许的情况下,建议1:n的模式



2、集群的数据分片功能:

集群要实现的目的是要将不同的 key 分散放置到不同的 redis 节点,这里我们需要一个规则或者算法,通常的做法是获取 key 的哈希值,然后根据节点数来求模,但这种做法有其明显的弊端,当我们需要增加或减少一个节点时,会造成大量的 key 无法命中,这种比例是相当高的,所以就有人提出了一致性哈希的概念。

一致性哈希有四个重要特征:

均衡性:也有人把它定义为平衡性,是指哈希的结果能够尽可能分布到所有的节点中去,这样可以有效的利用每个节点上的资源。

单调性:对于单调性有很多翻译让我非常的不解,而我想要的是当节点数量变化时哈希的结果应尽可能的保护已分配的内容不会被重新分派到新的节点。

分散性和负载:这两个其实是差不多的意思,就是要求一致性哈希算法对 key 哈希应尽可能的避免重复。


但是:

Redis 集群没有使用一致性hash, 而是引入了哈希槽的概念。

Redis 集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽.集群的每个节点负责一部分hash槽。这种结构很容易添加或者删除节点,并且无论是添加删除或者修改某一个节点,都不会造成集群不可用的状态。

使用哈希槽的好处就在于可以方便的添加或移除节点。

当需要增加节点时,只需要把其他节点的某些哈希槽挪到新节点就可以了;

当需要移除节点时,只需要把移除节点上的哈希槽挪到其他节点就行了;

在这一点上,我们以后新增或移除节点的时候不用先停掉所有的 redis 服务,very good的


3、Redis集群的主从架构:

为了使在部分节点失败或者大部分节点无法通信的情况下集群仍然可用,所以集群使用了主从复制模型,每个节点都会有N-1个复制品。

例如有A,B,C三个节点的集群,在没有复制模型的情况下,如果节点B失败了,那么整个集群就会以为缺少B节点所承担的哈希槽这个范围的槽而不可用。

然而如果在集群创建的时候(或者过一段时间)我们为每个节点添加一个从节点A1,B1,C1,那么整个集群便有三个master节点和三个slave节点组成,这样在节点B失败后,集群便会选举B1为新的主节点继续服务,整个集群便不会因为槽找不到而不可用了。当然如果B和B1都down了,那集群还是不可用的,不过这种情况微乎其妙,基本不用考虑,出发你交换机挂了吧,或者机房断电。


4、redis架构图

redis 3.0 cluster 集群 学习之路篇 [1]_redis 3.0


架构细节:

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

(2)节点的fail是通过集群中超过半数的节点检测失效时才生效.

(3)客户端与redis节点直连,不需要中间proxy层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可

(4)redis-cluster把所有的物理节点映射到[0-16383]slot上,cluster 负责维护node<->slot<->value



5、redis-cluster选举:容错

redis 3.0 cluster 集群 学习之路篇 [1]_集群_02

(1)领着选举过程是集群中所有master参与,如果半数以上master节点与master节点通信超过(cluster-node-timeout),认为当前master节点挂掉.

(2):什么时候整个集群不可用(cluster_state:fail),当集群不可用时,所有对集群的操作做都不可用,收到((error) CLUSTERDOWN The cluster is down)错误

    a:如果集群任意master挂掉,且当前master没有slave.集群进入fail状态,也可以理解成进群的slot映射[0-16383]不完成时进入fail状态.

    b:如果进群超过半数以上master挂掉,无论是否有slave集群进入fail状态