疯狂的小鸡

Redis集群-Cluster功能简述

字数统计: 1.6k阅读时长: 5 min
2018/10/07 Share

更多Redis入门系列文章,参见Redis入门-大纲

Cluster是什么

博文至此,redis集群仍存在两类问题。

第一类问题为单机性能不足问题

  • 每个redis实例存有全部数据,当数据量特别大,超过了单机内存容量的时候无法处理。
  • 虽然sentinal能将读操作分给从机处理实现部分负载均衡功能,若并发写压力特别高,主服务器也会承受不住。
  • 实现sentinal后,客户端不再直接连接特定redis实例,而是连接sentinel的ip和port,由sentinel来提供具体的可提供服务的Redis实现。存在流量瓶颈问题。

为了解决这三个问题,Redis cluster提供在多个Redis间节点间共享数据的程序集。redis cluster提供了数据分片功能,自动分割数据到不同的节点上。每个redis实例不再储存全部数据。

需要注意的是,Redis cluster并不支持处理多个keys的命令,因为这需要在不同的节点间移动数据,从而达不到像Redis那样的性能,在高负载的情况下可能会导致不可预料的错误.

第二类问题为可用性问题。

虽然sentinel有效的解决了故障转移的问题,也解决了主节点下线客户端无法识别新的可用节点的问题,但是如果是从节点下线了,sentinel是不会对其进行故障转移的,并且连接从节点的客户端也无法获取到新的可用从节点。

与之不同的是,Redis cluster根据客户端请求的不同,直接请求储存了对应数据的redis实例,而不是经由一个统一的负载均衡器实现负载均衡。Sentinal的监控和自动Failover能力由cluster承担。

数据分片

redis cluster任何两个节点之间都是相互连通的。客户端可以与任何一个节点相连接,然后就可以访问集群中的任何一个节点。对其进行存取和其他操作。用户在任意实例上执行请求命令时,其首先会为当前的键通过一致哈希算法计算其所在的槽位,若判断该槽位不在当前redis实例中,则重定向到目标实例上执行该命令。

一致哈希算法

Redis cluster引入了哈希槽的概念。有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽(CRC16(key) % 16384)。集群的每个节点负责一部分hash槽。

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

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

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

请求重定向

由于每个节点只负责部分slot,以及slot可能从一个节点迁移到另一节点,造成客户端有可能会向错误的节点发起请求。因此需要有一种机制来对其进行发现和修正,这就是请求重定向。

1)MOVE
‘我’并不负责‘你’要的key,告诉’你‘正确的吧。

返回CLUSTER_REDIR_MOVED错误,和正确的节点。

客户端向该节点重新发起请求,注意这次依然有发生重定向的可能。

2)ASK
‘我’负责请求的key,但不巧的这个key当前在migraging状态,且‘我’这里已经取不到了。告诉‘你’importing他的‘家伙’吧,去碰碰运气。

返回CLUSTER_REDIR_ASK,和importing该key的节点。

客户端向新节点发送ASKING,之后再次发起请求。

新节点对发送过ASKING,且key已经migrate过来的请求进行响应。

3)区别
MOVE,申明的是slot所有权的转移,收到的客户端需要更新其key-node映射关系。

ASK,申明的是一种临时的状态,所有权还并没有转移,客户端并不更新其映射关系。前面的加的ASKING命令也是申明其理解当前的这种临时状态。

replica迁移

Redis Cluster实现了一个成为“Replica migration”的概念,用来提升集群的可用性。如果masters与slaves之间的映射关系是固定的(fixed),提高集群抗灾能力的唯一方式,就是给每个master增加更多的slaves,不过这种方式开支很大,需要更多的redis实例。解决这个问题的方案,我们可以将集群非对称,且在运行时可以动态调整master-slaves的布局(而不是固定master-slaves的映射)。

比如集群中有三个master A、B、C,它们对应的slave为A1、B1、C1、C2,即C节点有2个slaves。“Replica迁移”可以自动的重新配置slave,将其迁移到某个没有slave的master下。

  • A失效,A1被提升为master。

  • 此时A1没有任何slave,但是C仍然有2个slave,此时C2被迁移到A1下,成为A1的slave。

  • 此后某刻,A1失效,那么C2将被提升为master。集群可以继续提供服务。

迁移算法使用一种算法来避免大规模迁移,这个算法确保最终每个master至少有一个slave。触发时机为,任何一个slave检测到某个master没有一个良好slave时。参与迁移的slave为,持有最多slaves的master的其中一个slave,且不处于FAIL状态,且持有最小的node ID。

当集群的配置不够稳定时,有一种竞争情况的发生,即多个slaves都认为它们自己的ID最小;如果这种情况发生,结果就是可能多个slaves会迁移到同一个master下, 的结果是导致原来的master迁出了所有的slaves,让自己变得单一。但是迁移算法(进程)会在迁移完毕之后重新判断,如果尚未平衡,那么将会重新迁移。

最终,每个master最少持有一个slave;这个算法由用户配置的“cluster-migration-barrier”,此配置参数表示一个master至少保留多少个slaves,其他多余的slaves可以被迁出。此值通常为1,如果设置为2,表示一个master持有的slaves个数大于2时,多余的slaves才可以迁移到持有更少slaves的master下。

CATALOG
  1. 1. Cluster是什么
  2. 2. 数据分片
    1. 2.1. 一致哈希算法
    2. 2.2. 请求重定向
  3. 3. replica迁移