-
可用性,节点数至少为 6 个(三主三从),保证可用性
-
每一个 Redis Cluster node 需要两个 TCP 连接
- Redis TCP port used to serve clients 6379
- cluster bus port, 默认情况下是数据端口加上 10000 ( 16379),但可以通过配置文件中的
cluster-port来指定
-
Cluster bus 是一个节点到节点的通信 Channel,使用 binary protocol
-
节点通过 Cluster bus 来 failure detection, configuration updates, failover authorization
Redis Cluster and Docker
Redis Cluster 不支持 NAT 环境。
所以在 Docker 下需要使用 host 网络模式。docker network ,请添加 --net=host 参数。
Data Sharding
Redis Cluster 不使用 consistent hashing(一致性哈希),而是使用另一种 sharding 方式,叫做 hash slot。
Redis Cluster 中有 16384 个 hash slots,计算一个给定 key 的 hash slot,计算 key 的 CRC16 然后取模(modulo) 16384。
集群中的每一个节点负责hash slot 的一个子集,比如,三个节点:
- Node A 包含 hash slots 从 0 到 5500
- Node B 包括 5501 到 11000
- Node C 包括 11001 到 16383
为了让添加或移除节点更加简单,比如要添加新的节点 D,需要将一些 hash slot 从 A,B,C中移动。同样的如果要移除 A 节点,也需要移动 hash slots。一旦节点 A 空了,就可以从集群中移除。
从一个节点移动到另一个节点不需要停止任何操作,因此,添加或移除节点,或者改变节点 hash slots 的百分比不会造成 downtime。
master-replica model
为了保证可用性,Redis Cluster 使用 master-replica 模型,每一个 hash slot 有 1 (master) 到 N 个副本(replicas,N-1 个额外的副本节点)
比如上面的三个节点的例子,A,B,C 三个节点,如果 B 节点宕机了,这样没有办法提供在 5501-11000 的 hash slots。
但是当集群创建之后,会将副本节点也添加到每一个 master,所以会有副本节点 A1,B1,C1,这种情况下即使 B 节点宕机了,集群也能提供服务。 B1 复制了 B,如果 B 节点宕机, 那么集群会提拔 B1 作为新的 master 节点。
但是要注意的是,如果 B 和 B1 节点同时发生错误,那么 Redis Cluster 会无法提供服务。
consistency guarantees
Redis Cluster 不保证强一致性。在特定的情况下,Redis Cluster 会丢失写的数据。
原因:
- Redis Cluster 使用异步的复制
- Client 写到 master B
- master B 返回成功
- master B 向副本节点 B1,B2,B3 传播写数据
这里可以看到 B 节点不会等待所有副本节点 B1,B2,B3 节点都确认没有问题才返回客户端成功,因为这可能影响 Redis 的性能。正因为这样的机制存在,所以如果客户端写了数据,B 成功写入,但是在发送写操作给副本节点之前 crash 了,然后其中一个副本节点被提拔为 master (但没有收到 write ),那么就永久丢失了写入的数据。
Redis 集群工作原理
自动将数据进行分片,每个 master 上放一部分数据 提供内置的高可用支持,部分 master 不可用时,还是可以继续工作的
分布式寻址算法
Hash slot
Redis cluster 有固定的 16384 个 hash 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 slot,通过 hash tag 来实现。
任何一台机器宕机,另外两个节点,不影响的。因为 key 找的是 hash slot,不是机器。