Redis--集群

文章目录

目录

文章目录

前言

一、节点

二、槽指派

三、重新分片

四、集群节点服务器的数据库实现

五、集群中执行命令

六、复制

七、故障转移

八、消息


前言

主要介绍了Redis集群的实现,集群通过分片进行数据共享,不同主机部署相同服务,提供复制和故障转移功能。


一、节点

  • 每个集群节点是一个有点特殊的redis服务器,通过clusterNode&clusterLink&clusterState数据结构来存集群相关信息,每个节点的集群中本来只有自己,通过向其他节点发送CLUSTER MEET握手命令,将该节点加入到自己的集群中
  • 保存集群结点信息的数据结构
    redisServer结构存服务器基础信息
    • clusterNode存节点的当前状态:创建时间、节点名字、ip、port
      • clusterLink:记录节点连接相关信息
      • slots数组:数据项是二进制数据,记录该节点负责处理的槽(numslot记录该节点管理槽的数量)
      • slaveof指针:记录自己复制哪个主节点,当节点是从节点是,该指针指向节点复制的主节点的clusterNode结构
    • clusterLink存连接结点相关信息:fd套接字描述符、输入缓冲区、输出缓冲区、clusterNode与连接相关联的结点相关信息
    • clusterState存该节点视角下集群状态
      • nodes字典:指向集群中所有节点的clusterNode结构,myself指向自己的clusterNode结构
        • clusterState.nodes.clusterNode.slaves字典:记录哪些节点是复制自己的从节点,指向将该节点记录为主节点(即复制该节点)的从节点的clusterNode结构(numslaves记录该节点的从节点数量)
      • slots数组:数据项是指向clusterNode的指针,记录每个槽靠那个节点处理
      • slots-to-key跳跃表:记录数据库键对应的槽
      • 重新分片相关属性
        • importing-slot-from[16384]数据项指向一个clusterNode节点,表示从clusterNode节点将槽i数据转移到自己的数据库:CLUSTER SETSLOT i IMPORTING clusterNode
        • migrating-slot-to[16384]数据项指向一个clusterNode节点,表示将自己数据库里槽i对应的数据发送到clusterNode节点对应的数据库中:CLUSTER SETSLOT i MIGRATING clusterNode
  • CLUSTER MEET命令
    • A向B发送CLUSTER MEET命令后,A为B创建一个clusterNode结构存在自己的clusterState的nodes字典里
    • B收到A发送的信息,B为A创建一个clusterNode结构存在自己的clusterState的nodes字典里
    • B向A发送PONG命令,A向B发送PING命令,握手完成
    • A节点通过Gossip协议将B节点信息传播给集群中的其他节点

二、槽指派

  • 集群通过分片共享数据,数据库会被分成16384个槽,通过CLUSTER ADDSLOTS命令指派某个结点处理某些槽数据,16384个槽都被集群中结点处理时,该集群上线,只要有一个槽没有被处理,该集群就是下线状态
  • 槽指派信息的保存和传播
    • 保存单个节点的槽指派信息:存在clusterNode数据结构的slots数组和numslot中
      • clusterNode.slots存的是某个节点管理哪些槽
      • clusterNode的slots是一个16384b=2048B的存二进制位数据的数组,该节点管理的槽对应的二进制数值为1,不是该节点管理的为0
      • numslot记录标识为1的二进制位个数,即该节点管理的槽的个数
    • 传播:集群中的节点互相发送自己的slots数组
      • 节点收到别的节点发来的slots数组,会将该信息存到自己的clusterState中的nodes字典中该节点对应的clusterNode的slots数组中,同时更新自己clusterState.slots数据
      • 集群中的每个节点会知道数据库的每个槽分配给了那个节点负责
    • 保存集群中所有槽的指派信息:存在clusterState数据结构的slots数组中
      • clusterState.slots存的是每一个槽指派给哪个节点管理
      • clusterState的slots是一个有16384个项的数组,每个元素是一个指向clusterNode结构的指针
      • 记录每个槽指派给了那个集群节点管理
  • CLUSTER ADDSLOTS命令
    • 某个节点执行该命令后,会更新该节点的clusterNode.slots信息和clusterState.slots信息
    • 同时将自己的clusterNode.slots信息发送给集群中其他节点,告知他们自己处理哪些槽,接收到消息的节点会更新自己clusterState中的slots和nodes中对应节点的clusterNode.slots

三、重新分片

  • 将某个槽的管理权从源节点移动到目标节点的过程叫做重新分片,重新分片不仅需要更新两节点的clusterNode和clusterState的slots,还需要移动节点数据库中的键值对,将这个槽对应的所有数据库键值对从源节点数据库迁移到目标节点数据库
  • clusterState中的重新分片数据结构
    • importing-slot-from 、migrating-slot-to

四、集群节点服务器的数据库实现

  • 集群节点服务器的数据库和普通服务器一样用dict字典来存键值对,expires字典存过期键,只不过集群节点服务器只能用0号数据库,普通服务器16个数据库都可以用
  • 在每个节点的clusterState中有一个跳跃表slots-to-key,其中跳跃表值是数据库键,跳跃表分数是数据库键对应的槽,记录所有数据库键对应的槽

五、集群中执行命令

  • 16384个数据库槽都分派给了集群节点,集群上线,可以接受客户端命令,客户端连接到某个集群节点服务器并且发送命令
  • 集群节点服务器会计算出该命令需要操作的数据库键所属的槽,检查该槽是否是自己管理(找到自己的clusterState中的slots数组里该槽指向的clusterNode是不是myself),是则检查该键值是否在自己的数据库里,在则执行该命令
    • 不在则通过migrating-slot-to属性判断该槽数据是否迁移到别的节点,是返回ASK错误并向迁移的目标节点发送ASKING命令,然后引导客户端连接到目标节点,并且重新发送命令
  • 不是则通过importing-slot-from属性检查是否正在从某节点导入该槽,在则检查自己是否有REDIS-ASKING标识,有则破例执行一次关于不在自己管控范围的槽的数据的命令,并且清除自己的REDIS-ASKING标识
    • 没有则报MOVED错误,该数据还没有从旧节点导入自己的数据库,引导客户端连接到importing-slot-from指向的节点,并且重新发送命令
  • 不在则报MOVED错误(通过节点的clusterState中该槽指向的clusterNode结构找到管理该槽的节点的ip和port)并指引客户端重新连接到管理该槽的节点,客户端重新发送命令
  • 两种错误区别
    • ASK错误:针对槽迁移过程的临时措施,关于该槽的命令,只能向ASK错误指向的节点发送一次
    • MOVED错误:表示该槽的负责权永久转移,以后每次对该槽的命令,都可以直接向MOVED错误指向的新节点发送

六、复制

  • 某个节点执行命令REPLICATE node-id表示该节点变成一个从节点,node-id节点是其主节点,开始复制它的数据
  • clusterNode的flag标识变成slave,slaveof指针指向node-id节点的clusterNode结构
  • 该消息会被集群中其他节点感知到,其他节点会修改自己的clusterState中的nodes字典里node-id节点的clusterNode结构
  • clusterState.clusterNode.numslaves+1,slaves字典添加一个发起该命令的节点的clusterNode结构,记录复制node-id节点的从节点

七、故障转移

  • 集群中各个节点会互相发送PING-PONG命令,检测对方是否在线,若没有在规定时间内收到有效回复会将节点标识为疑似下线,主节点可以通过其他节点发送的消息感知到某个节点是否被标识为疑似下线,然后可以为其创建下线报告,如果集群里超过半数的主节点都将某个主节点报告为疑似下线,会广播该节点的下线消息通知集群中所有节点
  • 下线主节点的从节点得知该节点已下线,会开始进行故障转移
  • 从节点会向集群广播一个消息要求具有选举权的主节点(管理槽的)给自己投票,每个主节点会投票给第一次向自己发送该命令的从节点,当某个从节点收到超过半数主节点的投票则顺利成为新的主节点,执行SLAVEOF no one命令
  • 新主节点撤销下线主节点的所有槽指派,将这些槽全部指派给自己
  • 新主节点向集群广播一条PONG消息告知集群其他节点自己接替下线主节点负责处理的槽
  • 故障转移完成,新主节点开始处理自己负责的槽的有关命令

八、消息

  • 集群节点之间通过发送和接受消息进行沟通,消息=消息头+消息正文,消息有5类:MEET、PING、PONG、FAIL、PUBLISH
  • 消息头记录了消息发送者自己的信息,消息接受者根据这些信息在自己的clusterState的nodes字典里找到对应的clusterNode结构进行更新
  • MEET、PING、PONG共用Gossip协议消息正文
    • 通过消息头判断具体是MEET、PING、PONG哪一种消息
    • 消息正文由两个记录被选中节点信息的clusterMsgDateGossip结构构成
    • 消息接受者根据这两个clusterMsgDataGossip结构中的被选中节点信息判断自己对这两个节点怎么处理,如果认识则更新其信息,如果不认识则与该节点握手创建该节点信息
  • FAIL消息正文
    • clusterMsgDateFail结构保存下线节点的名字,当一个节点判断某个节点已经下线,会向集群里其他节点发送存了下线节点名字的FAIL消息,FAIL信息比Gossip协议消息传播的更快,其他节点收到后可以立即将下线节点标识为下线然后根据情况执行故障转移操作
  • PUBLISH消息正文
    • clusterMsgDatePublish结构,存PUBLISH命令中发来的channel和message
    • 客户端向集群节点服务器发送PUBLISH channel message命令,收到该命令的集群节点会向集群中其他节点广播该PUBLISH消息,让集群中所有节点都向channel频道发送message消息
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值