Redis集群Cluster
redisRedis提供的分布式解决方案:Redis Cluster集群,使用分片sharding来进行数据共享,还提供了复制和故障转移功能。
Redis集群通常由多个节点node组成,节点通过CLUSTER MEET命令连接起来组成集群。
Redis集群通过分片方式保存数据库中的键值对,集群的整个数据库分为16384个槽slot,数据库中的每个键都属于这16384个槽的其中一个,集群中每个节点可以处理0到最多16384个槽。
一个节点出了会记录自己负责的槽外,还会把自己负责的slots数组通过消息发送给集群其他的节点,告知其他节点自己负责的槽有哪些。
在集群中执行命令
客户端向节点发送命令时,接收命令的节点会计算出键对应属于哪个槽:
- 如果键对应的槽属于自己,直接执行命令。
- 如果键对应的槽属于其他节点,会向客户端返回MOVED错误,指引客户端转向redirect到正确的节点,并再次发送要执行的命令。
重新分片
Redis集群可以通过重新分片将某节点的槽指派给另外一个节点,所有的对应的键值对也会被迁移到新的目标节点。
- redis-trib向目标节点发送:
CLUSTER SETSLOT <slot> IMPORTING <source_id>
,让目标节点准备好从源节点导入键值对 - redis-trib向源节点发送:
CLUSTER SETSLOT <slot> MIGRATING <target_id>
,让源标节点准备好从源节点迁移键值对到目标节点 - redis-trib向源节点发送:
CLUSTER GETKEYSINSLOT <slot> <count>
,获得最多count个键值对的键 - 针对每个键,redis-trib向源节点发送:
MIGRATE <target_ip> <target_port> <key_name> 0 <timeout
,将被选中的键原子的从源节点迁移到目标节点 - 重复迁移步骤直到完成
- redis-trib向集群中任一节点发送
CLUSTER SETSLOT <slot> NODE <target_id>
,将槽指派配目标节点,这会通知整个集群。
复制和故障转移
Redis集群中的节点分为主节点和从节点,从节点会复制主节点,主节点下线时从节点代替主节点处理命令请求。
集群中每个节点定期向集群中其他节点发送PING消息,用来检测对方是否在线,如果不在线就会将其标记疑似下线,并且各个节点会通过相互发消息交换集群中各个节点状态信息,如果一个集群中半数以上的节点都将某一个节点报告为疑似下线,那么这个节点会被标记为已下线,并广播给集群其他的节点,该节点已下线。
当从节点发现主节点已下线,就开始故障转移:
- 有一个从节点会被选中,执行
SLAVEOF no one
,变成新的主节点 - 新的主节点会撤销所有对已下线主节点的槽指派,并把这些槽指派给自己
- 新的主节点向集群发送PONG消息,让其他的节点知道自己变成了主节点
- 新的主节点开始对外服务
参考
- 《redis设计与实现》(第二版)