Redis Cluster 测试

Redis Cluster 测试

Sep 13, 2021
Cluster

以下内容基于 Redis Cli Cluster | Redis

资源重试

Standalone 单点

  • 断线过程中错报以下两类错误
    • Unexpected end of stream.
    • Could not get a resource from the pool
  • 服务好了之后恢复正常

Cluster 集群

  • 节点挂之后会报以下异常
    • Too many Cluster redirections?; nested exception is redis.clients.jedis.exceptions.JedisClusterMaxRedirectionsException: Too many Cluster redirections?
    • CLUSTERDOWN The cluster is down; nested exception is redis.clients.jedis.exceptions.JedisClusterException: CLUSTERDOWN The cluster is down
  • 服务好了之后恢复正常

宕机主备切换

操作步骤

  • 重启任意 分片 的 从节点

    • 应用无任何感知
  • 重启任意 分片 的 主节点

    • 阶段1,持续大约 5s(与 cluster-node-timeout 5000 配置有关)

    • 所在 分片报错:Too many Cluster redirections?; nested exception is redis.clients.jedis.exceptions.JedisClusterMaxRedirectionsException: Too many Cluster redirections?

      • 其他集群节点无影响
    • 阶段2,持续大约 1s(集群发现其中一个分片 主节点 Down,开始选主)

      • 所有节点报错:CLUSTERDOWN The cluster is down; nested exception is redis.clients.jedis.exceptions.JedisClusterException: CLUSTERDOWN The cluster is down
    • 阶段3: 所有节点恢复正常

    • 结果:原来主节点变为 从节点

结论

  • 当主节点 Down 之后,会有约 5s 的部分不可用时间
  • 之后开始主备切换,切换过程中存在约 1s 的整体不可用(关闭 cluster-require-full-coverage 不会存在该问题)
  • 主备切换过程并不是完全无感知的,如果要切换不可避免,需选择避开业务峰值

部分 Slot 主备全部 宕机

操作步骤

  • 同时关闭 slot 8000 所在的 master 和 slave

    • 阶段 1 ,持续大约 5s(与 cluster-node-timeout 5000 配置有关)

      • 所在 分片报错:Too many Cluster redirections?; nested exception is redis.clients.jedis.exceptions.JedisClusterMaxRedirectionsException: Too many Cluster redirections?
    • 其他集群节点无影响

  • 阶段2,

    • 所有节点报错:CLUSTERDOWN The cluster is down; nested exception is redis.clients.jedis.exceptions.JedisClusterException: CLUSTERDOWN The cluster is down
  • 重启 slot 8000 所在的 master 和 slave

    • 集群恢复正常

结论

  • slot 缺失,会导致集群整体不可用(关闭 cluster-require-full-coverage 不会存在该问题)
  • 需要关注集群的状态,在集群只有 master 节点时,及时处理,避免单节点挂掉之后,导致整个群不可用

Slot 节点下线,集群部分可用

关闭 cluster-require-full-coverage

# 全部 slot 可用,集群才可用,默认是 yes,这里设置为 no,即允许部分 slot 缺失,集群仍然可以用
cluster-require-full-coverage no

Replica migration

  • 该方案是尽量避免 孤儿 master 的存在,会自动分配其它多余的 slave 节点给 孤儿 master 节点
  • 孤儿 master 的定义是那些本来有 slave,但是全部离线的 master,对于那些原来就没有 slave 的 master 不能认为是孤儿 master
  • 该功能通过 cluster-migration-barrier 参数配置,默认为1

命令主备切换

  • CLUSTER FAILOVER [FORCE|TAKEOVER]
  • 该命令只能在从节点执行
  • 命令 主备切换过程对客户端是无感知的
  • 场景
    • 如果 master 宕机后恢复,会变为 slave,可以执行该命令强制切换为 master
    • 无感知滚动升级

主备切换对 Pub/Sub 的影响

  • 使用 Pub/Sub 通过 CLUSTER FAILOVER 进行主备切

    • 任意节点切换,Pub 时都会报异常:java.net.SocketTimeoutException: Read timed out
  • 切换时 Sub 不受影响

    • 集群恢复后,程序自动恢复
  • 通过 宕掉 master 节点

    • 切换过程中无任何影响
  • 使用 Pub/Sub 通过 CLUSTER FAILOVER FORCE 进行主备切

    • 切换过程中无影响

主备切换对 Block 操作的影响

Redis 模块中的阻塞命令

  • 通过 CLUSTER FAILOVER 进行主备切,执行时报以下异常:

    • UNBLOCKED force unblock from blocking operation, instance state changed (master -> replica?)
  • 在下次发起 Block 操作时,会自动恢复 Block

集群扩容

  • Step 1 : 增加新的 master 和 slave 节点
    • redis-cli –cluster add-node 10.10.17.203:6006 10.10.17.203:6000
    • redis-cli –cluster add-node 10.10.17.203:6007 10.10.17.203:6000 –cluster-slave –cluster-master-id 63d2b26085cbe1dc0ff9591649e6141f71f97a51
  • Step 2 : 重平衡
    • redis-cli –cluster rebalance 10.10.17.203:6000 –cluster-use-empty-masters
  • 结果:扩容过程对节点无影响,Client 无感知

集群缩容

  • Step 1: 删除 Slave 节点
    • redis-cli –cluster del-node 10.10.17.203:6000 9af827b66529e2c69616e5b1b1857a63a3b13a33
  • Step 2:迁移 需要删除的 Node 负责的 Slot 到其他节点
    • redis-cli –cluster reshard 10.10.17.203:6000 –cluster-from 63d2b26085cbe1dc0ff9591649e6141f71f97a51 –cluster-to b7af451787be60449df781670748e1414b3def2e –cluster-slots 1000000
  • Step 3: 删除空 Slot 节点
    • redis-cli –cluster del-node 10.10.17.203:6000 63d2b26085cbe1dc0ff9591649e6141f71f97a51
  • Step 4: rebalance 现有集群的 Slot
    • redis-cli –cluster rebalance 10.10.17.203:6000
  • 结果
    • 缩容 和 Slot 迁移过程对节点无影响,Client 无感知