Redis-Cluster集群


  • Cluster高可用集群
  • 槽位&选举&脑裂
  • 集群完整性&奇数节点&批量操作
  • 通信

Cluster 高可用集群

  • 配置文件
    • cluster‐enabled yes                                 开启集群模式
    • cluster‐config‐file nodes.conf                集群节点信息文件,会自动生成
    • cluster‐node‐timeout 10000                  超过1s则认为故障(防止网络抖动)
    • requirepass jxch                                      设置Redis密码
    • masterauth jxch                                       设置Redis集群密码,与上面保持一致
  • 启动所有节点
    • 防火墙设置:避免gossip端口号通信问题(16379,默认端口+10000)
  • 创建集群
    • redis‐cli ‐a jxch ‐‐cluster create ‐‐cluster‐replicas 1 IP:PORT …
    • ‐‐cluster‐replicas 1 代表为每个主节点设置一个从节点
  • 连接任意节点
    • redis‐cli ‐a jxch ‐c ‐h 192.168.0.61 ‐p 800*
      • -a 服务器密码;-c 集群模式
    • cluster info
    • cluster nodes
  • 关闭集群需要逐个关闭
    • redis‐cli ‐a jxch ‐c ‐h 192.168.0.60 ‐p 800* shutdown
    • 集群关闭后只需逐个重启Redis服务即可重启集群,无需重复创建集群
      • 各节点存有自动生成的集群元数据文件
  • 扩容:add-node
    • 先改好配置文件,启动主从节点
    • 添加主节点:第一个是新增节点,第二个是集群中任意已存在的节点
      • redis‐cli ‐a jxch ‐‐cluster add‐node 192.168.0.61:8007 192.168.0.61:8001
    • 为新增的主节点分配hash槽:使用集群中任意其他主节点分配
      • redis‐cli ‐a jxch ‐‐cluster reshard 192.168.0.61:8001
    • 添加从节点:第一个是新增节点,第二个是集群中任意已存在的节点
      • redis‐cli ‐a jxch ‐‐cluster add‐node 192.168.0.61:8008 192.168.0.61:8001
      • 各主节点平均分配,数据也同时迁移了
    • 为从节点分配主节点
      • cluster nodes
      • cluster replicate 主节点ID
  • 缩容:del‐node
    • 删除从节点
      • redis‐cli ‐a jxch ‐‐cluster del‐node 192.168.0.61:8008 从节点ID
    • 转移主节点hash槽(同时迁移数据)
      • redis‐cli ‐a jxch ‐‐cluster reshard 192.168.0.61:8007
    • 只能迁移到一个节点上,无法平均分配
    • 删除主节点
      • redis‐cli ‐a jxch ‐‐cluster del‐node 192.168.0.61:8007 主节点ID

槽位&选举&脑裂

  • 槽位
    • Redis Cluster 将所有数据划分为 16384 个 slots(槽位),每个节点负责其中一部分槽位。槽位的信息存储于每个节点中。客户端连接集群时也会得到一份集群的槽位配置信息并将其缓存在客户端本地。16384个槽位(2的14次方),具有更好的质数性质,减少哈希冲突的概率,不选65535是为了防止维持健康状态大量发送ping/pong导致网络拥堵
    • 槽位定位算法
      • HASH_SLOT = CRC16(key) mod 16384
    • 跳转重定位
      • 当客户端向一个错误的节点发出了指令,该节点会发现指令的 key 所在的槽位并不归自己管理,这时它会向客户端发送一个特殊的跳转指令携带目标操作的节点地址,告诉客户端去连这个节点去获取数据
      • 客户端收到指令后除了跳转到正确的节点上去操作,还会同步更新纠正本地的槽位映射表缓存,后续所有 key 将使用新的槽位映射表
  • 选举
    • 当slave发现自己的master变为FAIL状态时,便尝试进行Failover,以期成为新master。由于挂掉的master可能会有多个slave,从而存在多个slave竞争成为master节点的过程
      • slave发现自己的master变为FAIL
      • 将自己记录的集群currentEpoch加1,并广播FAILOVER_AUTH_REQUEST 信息
      • 其他节点收到该信息,只有master响应,判断请求者的合法性,并发送FAILOVER_AUTH_ACK,对每个epoch只发送一次ack(只返回最先接受到的那个)
      • 尝试failover的slave收集master返回的FAILOVER_AUTH_ACK
      • slave收到超过半数master的ack后变成新Master(所以至少需要三个主节点,如果只有两个,当其中一个挂了,只剩一个主节点是不能选举成功的)
      • slave广播Pong消息通知其他集群节点
    • 延时机制
      • DELAY = 500ms + random(0 ~ 500ms) + SLAVE_RANK * 1000ms
        • SLAVE_RANK表示此slave已经从master复制数据的总量的rank。Rank越小代表已复制的数据越新。这种方式下,持有最新数据的slave将会首先发起选举(理论上)
      • 一定的延迟确保我们等待FAIL状态在集群中传播,slave如果立即尝试选举,其它masters或许尚未意识到FAIL状态,可能会拒绝投票
  • 脑裂
    • 网络问题导致集群其他节点无法连接某一主节点,但客户端可以连接此主节点
    • redis集群没有过半机制会有脑裂问题,导致多个主节点对外提供写服务,一旦网络恢复,会将其中一个主节点变为从节点,这时会有大量数据丢失
    • min‐replicas‐to‐write 1
      • 最少同步一台salve,再返回写成功
      • 影响集群的可用性,如果集群内没有salve了,就无法对外提供服务了

集群完整性&奇数节点&批量操作

  • 集群完整性
    • cluster-require-full-coverage no
    • 表示当负责一个插槽的主库下线且没有相应的从库进行故障恢复时,集群仍然可用
  • 奇数节点
    • 因为新master的选举需要大于半数的集群master节点同意才能选举成功,如果只有两个master节点,当其中一个挂了,是达不到选举新master的条件的
    • 奇数个master节点可以在满足选举该条件的基础上节省一个节点,比如三个master节点和四个master节点的集群相比,大家如果都挂了一个master节点都能选举新master节点,如果都挂了两个master节点都没法选举新master节点了,所以奇数的master节点更多的是从节省机器资源角度出发说的
  • 批量操作:集群模式只支持所有key落在同一slot
    • mset {user1}:1:name zhuge {user1}:1:age 18
    • 在集群模式下只会将{}内的值作为key计算slot

通信

  • 网络抖动:cluster‐node‐timeout 10000
    • 避免网络抖动会导致主从频繁切换 (数据的重新复制)
  • 集群节点间的通信机制:gossip协议(ping,pong,meet,fail)
    • meet:某个节点发送meet给新加入的节点,让新节点加入集群中,然后新节点就会开始与其他节点进行通信;
    • ping:每个节点都会频繁给其他节点发送ping,其中包含自己的状态还有自己维护的集群元数据,互相通过ping交换元数据 (类似自己感知到的集群节点增加和移除,hash slot信息等)
    • pong: 对ping和meet消息的返回,包含自己的状态和其他信息,也可以用于信息广播和更新
    • fail: 某个节点判断另一个节点fail之后,就发送fail给其他节点,通知其他节点,指定的节点宕机了
  • 每个节点每隔一段时间都会往另外几个节点发送ping消息,同时其他几点接收到ping消息之后返回pong消息
  • 优点:元数据的更新比较分散,不是集中在一个地方,更新请求会陆陆续续,打到所有节点上去更新,有一定的延时,降低了压力
  • 缺点:元数据更新有延时可能导致集群的一些操作会有一些滞后
  • 端口:自己提供服务的端口号+10000

文章作者: 钱不寒
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 钱不寒 !
  目录