Redis分布式方案:集群
Redis集群通过分片(sharding)进行数据共享,并提供复制和故障转移功能。
节点
一个Redis集群由多个node组成,连接各节点的命令格式如下:
CLUSTER MEET
127.0.0.1:7000> CLUSTER MEET 127.0.0.1 7001
槽指派
Redis集群通过分片的方式来保存键值对:集群的整个数据库被分为16384的槽(slot)。
通过CLUSTER ADDSLOTS命令,可以将一个或多个槽指派给节点负责:
CLUSTER ADDSLOTS
[slot ...] 127.0.0.1:7000> CLUSTER ADDSLOTS 0 1 2 3 4 ... 5000
OK
执行命令将槽0-5000指派给节点7000负责
记录节点的槽指派信息
slots属性是一个二进制位数组,数组长度为16384/8=2048个字节,共包含16384个二进制位。
为什么是16384个?
因为节点之间需要经常互相发送心跳等信息,其中就槽位也是包含在内的,取一个中间值16384能在一定程度
上减少消息的大小,又减少了数据不均衡的问题。
计算键属于哪个槽
节点使用 CRC16(key) & 16383 计算出一个 0-16383之间的整数作为键key的槽号。
但是,如果计算出来的槽值不能由当前节点处理,那么,该节点会向客户端返回MOVED错误,指引客户端转向可
以处理的节点。
MOVED 10086 127.0.0.1:7002
表示槽10086正由127.0.0.1:7002节点负责。
节点数据库实现
单机和节点的区别:节点只能使用0号数据库。
淘汰策略是一样的,从过期key里淘汰最久未使用的key,volatile-LRU。
重新分片
客户端访问key时,key所属的槽如果正在从旧节点转移到新节点,会发送ask错误(隐藏的)。
复制与故障转移
Redis集群节点分为master和slave,如果主节点下线,会选择一个从节点作为新的主节点。
设置从节点
CLUSTER REPLICATE <node_id>
可以让接收命令的节点变成从节点(和复制反命令过来了)
故障转移
当一个从节点发现自己正在复制的主节点下线了,从节点开始对下线主节点进行故障转移,以下步骤:
- 被选中的从节点会执行SLAVEOF no one命令,成为新的主节点。
- 将槽指派给自己。
- 新主节点向集群广播发送PONG消息,昭告天下。
选举新的主节点
和领头哨兵选举类似,都是基于Raft算法实现的。(见Redis哨兵)
Reference
《Redis设计与实现》