redis Cluster集群

Redis Cluster 官网地址:https://redis.io/topics/cluster-tutorial 

Redis Cluster集群保证高可用但是不支持强一致性,具有自动切分数据集到多个节点上的能力,当部分节点宕机或无法通讯的情况下仍可继续处理命令。但是如果大部分节点挂掉,那么该集群就停止工作。

① Redis Cluster需要的TCP端口

每一个redis集群的节点需要开通两个TCP端口。一个是用于客户端的Redis TCP,如6379。另一个由客户端加10000所得,如16379,用于Redis集群总线连接。 这是一个用户 节点对节点的 二进制协议通讯通道。集群总线是用来处理节点的失效检测,配置更新,灾备授权等事情。

集群总线使用了一种不同的二进制协议,供节点和节点之间交换信息用。该协议可以让节点和节点之间以更小的流量和和更短的时间来交换信息。

② 数据是怎么在cluster中存放的

Redis集群用的不是基于哈希值的分片方式,用的是另一种不同的分片方式-hash slot。在该分片方式下所有键在概念上都是我们称之为哈希槽的一部分。

Redis集群有16384个哈希槽。当需要在 Redis 集群中放置一个 key-value 时,redis 先对 key 使用 crc16 算法算出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,redis 会根据节点数量大致均等的将哈希槽映射到不同的节点。

Redis集群中的每个节点都存放了一些哈希槽。所以举例来说,比如你有3个节点:

节点A 保存了从 0 到 5500 的哈希槽
节点B 保存了从 5501 到 11000的哈希槽
节点C 保存了从 11001 到 16384 的哈希槽
  • 1
  • 2
  • 3

这么做让集群增加或者减少节点变得很简单。比如我要增加一个节点D,我只需要从节点ABC移动一部分哈希槽到D。如果我要从节点中去除节点A,我只需要把节点A上的哈希槽移动到节点B或者C。当节点A的哈希槽被全部移走了之后,我就可以将它从节点中完全去除。

因为把哈希槽从一个节点移动到另外一个节点并不需要停止集群, 所以增加、删除节点或者在各节点间调整哈希槽的占有率的时候是不用停止集群的。Redis集群支持在一条命令里面对同一个哈希槽的多个键同时操作(或者在一个事务中,或者在一个lua脚本执行过程中)。

用户可以通过哈希标签强制的把多个键放到一个哈希槽里面。在Redis集群手册中可以查到哈希标签的相关说明, 不过归纳成一句话就是:当有在key里面写上段包含在{...}中的文字的时候,之后大括号{...}中的文字会被计算成哈希键。比如有两个key一个名叫 this{foo}key 另一个名叫 another{foo}key ,这两个key会被归纳到同一个哈希槽里面。这样这两个key就可以在一个命令中同时进行操作了。


③ Redis 集群主从模型

为了在部分节点失败或者无法通信的情况下集群仍然可用,Redis 集群采用了一种 主从模型。在该模型下每一个哈希槽都会被从master端复制N份到slave节点。在上面例子中有三个节点分别是ABC,如果节点B挂掉了,集群就无法继续工作,因为从5501到11000的哈希槽就没了。

不过如果当集群被创建的时候(迟些时候也可以)我们给每一个master节点增加一个slave从节点。模型变成这样:集群中有三个节点A,B,C,以及他们各自的从节点 A1,B1,C1,当节点B挂掉的时候,系统还可以正常运行。节点B1是用来做为节点B的镜像的。当节点B挂掉了,集群会选举B1作为新的master节点,并继续运行下去。不过要注意当节点B和节点B1都挂掉的时候,redis集群还是无法继续运行。


④ Redis 集群一致性保证

Redis 集群并不能保证数据的强一致性。在实际应用中这意味着在特定的情况下,就算Redis 集群告知客户端已经收到了写请求,这个写请求仍然有可能丢失。Redis集群之所以会丢失写请求的首要原因是:它采用了异步的复制机制

在write的时候会经历以下的步骤:

你的客户端发送了一个写请求给master B 节点
master B 节点回复了一个OK给你的客户端。
master B 节点把这个写请求传播到它的 slave B1, B2, B3 节点上去。
  • 1
  • 2
  • 3

正如你所见, B节点并不会等到B1,B2,B3节点都回复它之后才回复OK给客户端。因为这样会造成redis集群过高的延迟度。所以如果你的客户端正在写入,节点B告知你的客户端它收到了写请求,但是在它把这个写请求发送给它的slave节点们之前,节点B挂了,那么其中一个slave节点(假设它还没收到写请求)被选举为master那么你这个写请求就永久的丢失了。

Redis集群也支持同步写入(但是就会导致性能降低,需要在高性能和强一致性做权衡)。它通过实现WAIT命令来实现。这样一来基本不会丢失写操作。但是请注意就算你使用了同步复制,Redis集群也不能达到强一致性,因为总是会遇到某些更复杂的错误场景,比如一个slave节点在被选举为master的时候不能收到写请求命令。

还有一个需要注意的会丢失数据的情况。当进行一次网络网络分裂的时候某个客户端被分配到一个拥有很少节点的区域中的情况。

就拿我们的6节点例子(master是ABC,slave是A1,B1,C1),此时有一个客户端,我们称之为Z1。当网络分裂后,有可能有这种情况:现在有2方,一方是 A,C,A1,B1,C1,另一方是B和Z1。Z1依然可以写入B,而且B也会接受来自Z1的写请求。如果这次网络分裂在很短的时间内被修复, 集群依然会保持正常运行。 然而如果网络分裂持续了较长时间,长到足够B1在多数方被选举为master。那么Z1发送给B的写请求都会丢失。

注意, 在网络分裂出现期间, 客户端 Z1 可以向主节点 B 发送写命令的最大时间是有限制的, 这一时间限制称为节点超时时间(node timeout), 是 Redis 集群的一个重要的配置选项。

  • 对于majority 一方来说, 如果一个主节点未能在节点超时时间所设定的时限内重新加入集群, 那么集群会将这个主节点视为下线, 并使用从节点替换掉。
  • 对于minority 一方, 如果一个主节点未能在节点超时时间所设定的时限内重新联系上集群, 那么它将停止处理写命令, 并向客户端报告错误。

⑤ 集群配置一些参数

集群配置参数主要有:

cluster-enabled <yes/no>
cluster-config-file <filename>
cluster-node-timeout <milliseconds>
cluster-slave-validity-factor <factor>
cluster-migration-barrier <count>
cluster-require-full-coverage <yes/no>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

详细解释如下:

  • cluster-enabled <yes/no>: 该项如果设置成yes,该实例支持redis集群。否则该实例会像往常一样以独立模式启动。
  • cluster-config-file <filename>: 必须注意到尽管该项是可选的,这并不是一个用户可以编辑的配置文件,这是redis集群节点自动生成的配置文件,每次一旦配置有修改它都通过该配置文件来持久化配置(基本上都是状态),这样在下次启动的时候可以重新读取这些配置。该文件中列出了该集群中的其他节点的状态,持久化变量等信息。 当节点收到一些信息的时候该文件就会被冲重写。
  • cluster-node-timeout <milliseconds>: redis集群节点的最大超时时间。响应超过这个时间的话该节点会被认为是挂掉了。如果一个master节点超过一定的时候无法访问,它会被它的slave取代。 该参数在redis集群配置中很重要。很明显,当节点无法访问大部分master节点超过一定时间后,它会停止接受查询请求。
  • cluster-slave-validity-factor <factor>:如果将该项设置为0,不管slave节点和master节点间失联多久都会一直尝试failover(设为正数,失联大于一定时间(factor*节点TimeOut),不再进行FailOver)。比如,如果节点的timeout设置为5秒,该项设置为10,如果master跟slave之间失联超过50秒,slave不会去failover它的master(意思是不会去把master设置为挂起状态,并取代它)。注意:任意非0数值都有可能导致当master挂掉又没有slave去failover它,这样redis集群不可用。在这种情况下只有原来那个master重新回到集群中才能让集群恢复工作。
  • cluster-migration-barrier <count>: 一个master可以拥有的最小slave数量。该项的作用是,当一个master没有任何slave的时候,某些有富余slave的master节点,可以自动的分一个slave给它。具体参见手册中的replica migration章节
  • cluster-require-full-coverage <yes/no>: 如果该项设置为yes(默认就是yes) 当一定比例的键空间没有被覆盖到(就是某一部分的哈希槽没了,有可能是暂时挂了)集群就停止处理任何查询炒作。如果该项设置为no,那么就算请求中只有一部分的键可以被查到,一样可以查询(但是有可能会查不全)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值