camhan 2020-05-27
客户端分区:在客户端决定key该放在哪个节点上
代理分区:客户端把请求发给代理,代理按规则请求某个节点,将结果返回给客户端
查询路由:随机请求一个节点,该节点告诉客户端key在哪个节点上
集群的缺点:对多个key的操作通常不被支持,例如求两个集合的交集,他们可能在不同的节点上
操作多个key,不支持事务
redis服务器在启动时会根据cluster-enabled是否为yes来决定是否启用集群模式
cluster node 查看集群所含的节点
集群只能使用0号数据库
最初每个节点都是相互独立的,处于一个只包含自己的集群中。
假设当前在127.0.0.1:6379·上
cluster meet 127.0.0.1 7000 会合并6379和7000这两个集群
槽(slot)指派:
整个集群被分为16384个槽,每个键都属于某个槽,
集群中每个节点可处理0~16384个槽,
当每个槽都有节点在处理时,集群处于上线状态(ok),否则为下线状态(fail)
向节点发送 cluster addSlots 命令可以指派槽
记录槽指派信息:
用2048字节的二进制位数组,可以记录2048*8=16384个槽是否被指派到本节点。
另一个长为16384的数组记录了每个槽被指派到了哪个节点上。
执行命令:
接受命令的节点计算key属于哪个槽,CRC(key) & 16383
如果这个槽指派给了自己,就执行命令
否则返回Moved错误,指引客户端向正确的节点再次发送命令
重新分片:
集群不需要下线,并且源节点和目标节点都可以继续处理请求
集群管理软件redis-trib负责重新分片,
对于每个要移动的槽,redis-trib向源节点获取若干个属于该槽的key
对于每个key,redis-trib发送相关的命令,原子地移动到目标节点
然后通知任一节点,该槽指派给了目标节点,这一信息会传遍整个集群
ASK错误:客户端请求某个key,该key属于正在被迁移的槽,
源节点在自己的数据库里没找到该key,会返回ASK错误,指引客户端去目标节点
复制与故障转移
集群中的每个节点都会定期向其他节点发送ping消息,以及返回pong消息,
超时未返回pong的节点,会被标记为疑似下线。超过半数节点把某节点标记为疑似下线,
那么集群认为该节点已经下线,会在它的从节点里选择一个,作为新的主节点
有投票权的节点,对从节点进行投票,若某个从节点的票数超过一半,则该节点就为主节点