How Redis-Cluster works?
集群
多个Redis节点协同工作,Redis节点之间两两通信
客户端可连接至任意Redis节点
键分布模型
Redis集群共持有16384(2^14)个槽位,每个槽位仅可存在于一个Redis主节点上
单个Redis主节点可含有任意数量的槽位(0-16384)个
所有的槽位(0-16383)必须被分配
每个Redis从节点持有其主节点一样的槽位
集群通过哈希一致性算法计算键所属槽位 CRC16("key") mod 16384
客户端请求示例
客户端不存储槽位信息
1 | Client => A: GET foo |
客户端存储槽位信息
1 | Client => A: CLUSTER HINTS |
高可用
Redis节点间通过Ping-Pong的方式检测状态
当半数以上节点认定某从节点失效时,仅标记失效状态,不做后续处理,当从节点重新上线,移除失效标记
当半数以上节点认定某主节点失效时,在其所拥有的从节点中发起选举,当选者成为新的主节点
当集群中超过半数的Redis主节点可用,且失效的主节点有可用的从节点,整个Redis集群就是可用的
主从复制
异步复制
- 客户端向主节点发送一条写命令
- 主节点执行写命令,并向客户端返回命令回复
- 主节点将刚刚执行的写命令复制给它的从节点
最终一致性
Redis 集群不保证数据的强一致性
- 主节点写,从节点读 ——读到的数据是旧数据
- 网络分区时间足够长——从节点替换主节点,原主节点写操作丢失
局限性
Redis集群在多个Redis节点之间进行数据共享
Redis集群不支持“multi-key”操作,即执行的命令需要在多个Redis节点之间移动数据
比如Set类型的并集、事务操作、M命令等,除非这些key属于同一个slot,即Cluster不能对多个slots操作
Key hash tags
Redis提供了hash tags操作,允许为key自定义一个tag,在存储时,Redis会依据key的tag计算出slot
1 | SET {hello}world value |
1 | // Radix.v2 |
扩容
启动一个新的Redis节点D并与集群节点建立连接
迁移槽位7至新的Redis节点D
在7号槽位迁移过程中,当C收到操作7的命令时,会产生-ASK 转向
在7号槽位迁移完成后,当C收到操作7的命令时,会产生-MOVED 转向