Skip to content

Redis 不同集群方案对比

一文搞懂 Redis 的三种集群方案 - 腾讯云开发者社区-腾讯云 (tencent.com)

  • 本文基于 Redis 7.0.5 版本测试

主从复制模式

Redis 的主从复制是如何做的?复制过程中也会产生各种问题? | Kaito's Blog (kaito-kidd.com)

Redis 主从复制基础概念 _TacitusKillgore 的博客-CSDN 博客

Redis——Redis 主从复制(工作流程详解)_stan Z 的博客-CSDN 博客_redis 主从复制

  • 简述

    • 主从复制模式
    • 客户端可对主数据库进行读写操作,对从数据库进行读操作,主数据库写入的数据会实时自动同步给从数据库
    • Redis 2.6 开始,Slave 默认只读
  • 优点

    1. 读写分离:主节点写,从节点读,提高服务器的读写负载能力。
    2. 数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。
    3. 故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复 ; 实际上是一种服务的冗余。
    4. 负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务(即写 Redis 数据时应用连接主节点,读 Redis 数据时应用连接从节点),分担服务器负载 ; 尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高 Redis 服务器的并发量。
    5. 高可用基础:主从复制机制是 Sentinel 和 Cluster 机制的基础,两者都实现了故障转移,即主节点故障后,Redis 负责选择一个从节点切换为主节点,继续提供服务。
  • 缺点

    1. Master 故障时不能自动切换,Master 或 Slave 的宕机都可能导致客户端请求失败,需要等待机器重启或手动切换客户端 IP 才能恢复
    2. Master 掉线前如果没有完成同步则数据可能丢失
  • 部署实践

    1. 获取 redis 配置文件

    2. 编辑 Master 节点启动配置文件

    3. 复制 Master 节点启动配置文件,并修改以下内容作为 Slave 节点启动配置文件

      config
      # Redis 5.0 之前叫做 SLAVEOF
      # https://redis.io/commands/replicaof/
      # https://redis.io/commands/slaveof/
      
      # 设置 Master 的 host 与 port
      replicaof <masterip> <masterport>
      # 对应于 Master 的 requirepass
      masterauth <master-password>
    4. 启动 Master 与 Slave

      • Slave 启动后,可以使用 info replication 查看到信息

        shell
        > info replication
        
        # Replication
        role:master
        connected_slaves:2
        slave0:ip=172.17.0.1,port=6385,state=online,offset=11186,lag=0
        slave1:ip=172.17.0.1,port=6386,state=online,offset=11186,lag=0
        master_failover_state:no-failover
        master_replid:eca4f0e2111d48768e319b6c0143858a7fa9fef0
        master_replid2:0000000000000000000000000000000000000000
        master_repl_offset:11325
        second_repl_offset:-1
        repl_backlog_active:1
        repl_backlog_size:1048576
        repl_backlog_first_byte_offset:1
        repl_backlog_histlen:11325
    5. 此时,Master 上进行的操作会被同步到 Slave 上

    6. 进入 Slave 节点,执行命令 REPLICAOF no one,将关闭对 Master 节点的同步模式

Sentinel(哨兵)模式

Redis 哨兵-实现 Redis 高可用

Redis 如何实现故障自动恢复?浅析哨兵的工作原理 | Kaito's Blog (kaito-kidd.com)

  • 简述

    • 哨兵模式
    • 解决了主从复制模式中 Master 不被监控的问题
    • 哨兵监控当前集群状态,当 Master 掉线后将从 Slave 中选出一个优先级最高的当作新的 Master
  • 优点

    1. 哨兵模式基于主从复制模式,所以主从复制模式有的优点,哨兵模式也有
    2. 哨兵模式下,Master 挂掉可以自动进行切换,系统可用性更高
  • 缺点

    1. 同样也继承了主从模式难以在线扩容的缺点,Redis 的容量受限于单机配置
    2. 需要额外的资源来启动 Sentinel 进程,实现相对复杂一点,同时 Slave 节点作为备份节点不提供服务
  • 部署实战

    1. 获取 sentinel 配置文件

    2. 编辑 Sentinel 哨兵启动配置文件

      config
      # sentinel 启动端口,默认26379
      port <sentinel-port>
      
      # <master-name> 定义一个master数据库的名称
      # <quorum> 表示至少需要n个Sentinel进程同意才能将master判断为失效,如果不满足这个条件,则自动故障转移(failover)不会执行
      sentinel monitor <master-name> <ip> <redis-port> <quorum>
      
      # master的密码
      sentinel auth-pass <master-name> <password>
      
      # <milliseconds> 未回复PING,则认为master主观下线,默认为30s
      sentinel down-after-milliseconds <master-name> <milliseconds>
      
      # 指定在执行故障转移时,最多可以有多少个slave实例在同步新的master实例,在slave实例较多的情况下这个数字越小,同步的时间越长,完成故障转移所需的时间就越长
      sentinel parallel-syncs <master-name> <numreplicas>
      
      # 如果在该时间(ms)内未能完成故障转移操作,则认为故障转移失败,生产环境需要根据数据量设置该值
      sentinel failover-timeout <master-name> <milliseconds>
    3. 使用命令 redis-sentinel sentinel.confredis-server sentinel.conf --sentinel 启动 sentinel 节点,需要注意 sentinel 节点数需要满足 2n+1(n>=1)的奇数个

      shell
      redis-server *:26379 [sentinel]
      ...
    4. 下线当前 Master 节点

    5. 检查原 Slave 节点

      shell
      > info replication
      # Replication
      role:slave
      master_host:192.168.31.234
      master_port:6379
      master_link_status:down
      master_last_io_seconds_ago:-1
      master_sync_in_progress:0
      slave_read_repl_offset:63146
      slave_repl_offset:63146
      master_link_down_since_seconds:5
      slave_priority:100
      slave_read_only:1
      replica_announced:1
      connected_slaves:0
      master_failover_state:no-failover
      master_replid:0d1e4612705847b8acd4ee9fcb6ebd6bb2523add
      master_replid2:0000000000000000000000000000000000000000
      master_repl_offset:63146
      second_repl_offset:-1
      repl_backlog_active:1
      repl_backlog_size:1048576
      repl_backlog_first_byte_offset:1
      repl_backlog_histlen:63146
      
      > info replication
      # Replication
      role:master
      connected_slaves:1
      slave0:ip=172.17.0.5,port=6386,state=online,offset=63578,lag=1
      master_failover_state:no-failover
      master_replid:b06d1d8c734ac005183e82c111c3cc73c5ef27c4
      master_replid2:0d1e4612705847b8acd4ee9fcb6ebd6bb2523add
      master_repl_offset:63848
      second_repl_offset:63147
      repl_backlog_active:1
      repl_backlog_size:1048576
      repl_backlog_first_byte_offset:1
      repl_backlog_histlen:63848
    6. 原 Master 节点 redis.conf 配置文件被自动添加以下内容

      config
      # Generated by CONFIG REWRITE
      save 3600 1
      save 300 100
      save 60 10000
      replicaof 172.17.0.1 6385
      latency-tracking-info-percentiles 50 99 99.9
      user default on #8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92 ~* &* +@all

Codis

CodisLabs/codis: Proxy based Redis cluster solution supporting pipeline and scaling dynamically (github.com)

  • 简述
    • Codis
    • 豌豆荚开源的集群方案,目前已停止维护
    • 将 Redis 集群对外抽象成单个服务,业务无需关心集群实现方式,
    • 将 Redis 在客户端和服务端中间增加一个代理层,客户端只需要操作这个代理层,代理层实现了具体的请求转发规则,然后转发请求到后面的多个节点上,因此这种方式也叫做中心化方式的集群方案
  • 优点
    1. 在线扩容。在扩容期间不影响客户端的访问,也就是不需要停机。这对业务使用方是极大的便利,当集群性能不够时,就可以动态增加节点来提升集群的性能
    2. 基于 Redis 3.2.8 二次开发,支持异步迁移数据
  • 缺点
    1. 框架实现时间较早,目前已经不再维护,且内置 Redis 3.2.8 版本,不可升级
    2. 对部分操作命令进行了禁用,详见:codis/unsupported_cmds.md at release3.2 · CodisLabs/codis (github.com)

Tweproxy

twitter/twemproxy: A fast, light-weight proxy for memcached and redis (github.com)

  • 简述
    • Twitter 开源的集群化方案,它既可以做 Redis Proxy,还可以做 Memcached Proxy
  • 优点
    1. 功能简单,只实现请求路由转发
  • 缺点
    1. 无法在线扩容、缩容

Redis Cluster 模式

Redis 集群化方案对比:Codis、Twemproxy、Redis Cluster | Kaito's Blog (kaito-kidd.com)

Redis 集群教程

Redis cluster specification | Redis

Redis 高可用架构—Redis 集群(Redis Cluster)详细介绍_腾讯新闻 (qq.com)

  • 简述

    • Cluster 没有使用代理层进行转发,而是把请求转发逻辑一部分放在客户端,一部分放在了服务端,它们之间互相配合完成请求的处理
    • SDK 中内置了请求转发的逻辑,所以业务开发人员同样不需要自己编写转发规则,Redis Cluster 采用 16384 个槽位进行路由规则的转发
    • Cluster
    • Cluster 模式实现了 Redis 的分布式存储,即每台节点存储不同的内容,来解决在线扩容的问题。
      1. 在 Redis 的每个节点上,都有一个插槽(slot),取值范围为 0-16383
      2. 当存取 key 的时候,Redis 会根据 CRC16 的算法得出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,通过这个值,去找到对应的插槽所对应的节点,然后直接自动跳转到这个对应的节点上进行存取操作
      3. 为了保证高可用,Cluster 模式也引入主从复制模式,一个主节点对应一个或者多个从节点,当主节点宕机的时候,就会启用从节点
      4. 当其它主节点 ping 一个主节点 A 时,如果半数以上的主节点与 A 通信超时,那么认为主节点 A 宕机了。如果主节点 A 和它的从节点都宕机了,那么该集群就无法再提供服务了
    • Cluster 模式集群节点最小配置 6 个节点(3 主 3 从,因为需要半数以上),其中主节点提供读写操作,从节点作为备用节点,不提供请求,只作为故障转移使用。
  • 优点

    1. 提供了在线数据迁移、节点扩容缩容等功能,内部还内置了哨兵完成故障自动恢复功能
    2. 所有的 Redis 节点彼此互联(PING-PONG 机制),内部使用二进制协议优化传输速度和带宽
    3. 节点的 fail 是通过集群中超过半数的节点检测失效时才生效
    4. 客户端与 Redis 节点直连,不需要中间代理层。客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可
  • 缺点

    1. Redis Cluster 在线数据迁移性能不高,迁移过程中遇到大 key 时还有可能长时间阻塞迁移的两个节点。

    2. 数据通过异步复制,不保证数据的强一致性

    3. Slave 充当“冷备”,不能缓解读压力

    4. 批量操作限制,目前只支持具有相同 Slot 值的 Key 执行批量操作,对 msetmgetsunion 等操作支持不友好

      shell
      172.17.0.5:7002> mset a 1 b 2
      (error) CROSSSLOT Keys in request don\'t hash to the same slot
    5. key 事务操作支持有线,只支持多 key 在同一节点的事务操作,多 key 分布不同节点时无法使用事务功能

    6. 不支持多数据库空间,单机 Redis 可以支持 16 个 db,集群模式下只能使用一个,即 db 0

      shell
      172.17.0.5:7002> select 1
      (error) ERR SELECT is not allowed in cluster mode
  • 部署实战

    1. 编辑启动配置文件

      config
      # Redis 启动端口
      port 6379
      
      # 开启集群模式
      cluster-enabled yes
      
      # master 密码
      masterauth <master-password>
      
      # 集群配置文件 需要指定不重名的文件 不需要手动维护
      cluster-config-file nodes-6379.conf
    2. 启动不同端口至少 6 个 Redis 服务 ```

    3. 创建集群

      1. Redis3/4 通过 Ruby 环境运行 redis-trib.rb 脚本

        shell
        ./redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005
      2. Redis5 通过 redis-cli 创建集群

        shell
        # `--cluster-replicas 1` 表示为每一个主服务器配一个重服务器。其余的参数是要创建的集群中各实例的地址列表。
        redis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 --cluster-replicas 1 -a <password>
      • 执行结果

        shell
        Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
        >>> Performing hash slots allocation on 6 nodes...
        Master[0] -> Slots 0 - 5460
        Master[1] -> Slots 5461 - 10922
        Master[2] -> Slots 10923 - 16383
        Adding replica 172.17.0.7:7004 to 172.17.0.2:7000
        Adding replica 172.17.0.8:7005 to 172.17.0.4:7001
        Adding replica 172.17.0.6:7003 to 172.17.0.5:7002
        M: 7166562ee201eecc7bbf65e76086ecfec515ef82 172.17.0.2:7000
           slots:[0-5460] (5461 slots) master
        M: 8c76b45a60807d75b1d1d7810ee12cffa890c1e1 172.17.0.4:7001
           slots:[5461-10922] (5462 slots) master
        M: 26977b84aa3242f089b284e9f69aba1c847e69d8 172.17.0.5:7002
           slots:[10923-16383] (5461 slots) master
        S: bb0f6b17ed26340ed9afe0fbce5ee783f72bed59 172.17.0.6:7003
           replicates 26977b84aa3242f089b284e9f69aba1c847e69d8
        S: 2a5c587dec73fdf3927b030439f9e35f7aadf833 172.17.0.7:7004
           replicates 7166562ee201eecc7bbf65e76086ecfec515ef82
        S: 0ea1b80c7810b46dabb0fb98f92fbcf58ed7f462 172.17.0.8:7005
           replicates 8c76b45a60807d75b1d1d7810ee12cffa890c1e1
        
        Can I set the above configuration? (type 'yes' to accept): yes
        >>> Nodes configuration updated
        >>> Assign a different config epoch to each node
        >>> Sending CLUSTER MEET messages to join the cluster
        Waiting for the cluster to join
        
        >>> Performing Cluster Check (using node 172.17.0.2:7000)
        M: 7166562ee201eecc7bbf65e76086ecfec515ef82 172.17.0.2:7000
           slots:[0-5460] (5461 slots) master
           1 additional replica(s)
        S: 0ea1b80c7810b46dabb0fb98f92fbcf58ed7f462 172.17.0.8:7005
           slots: (0 slots) slave
           replicates 8c76b45a60807d75b1d1d7810ee12cffa890c1e1
        M: 26977b84aa3242f089b284e9f69aba1c847e69d8 172.17.0.5:7002
           slots:[10923-16383] (5461 slots) master
           1 additional replica(s)
        M: 8c76b45a60807d75b1d1d7810ee12cffa890c1e1 172.17.0.4:7001
           slots:[5461-10922] (5462 slots) master
           1 additional replica(s)
        S: 2a5c587dec73fdf3927b030439f9e35f7aadf833 172.17.0.7:7004
           slots: (0 slots) slave
           replicates 7166562ee201eecc7bbf65e76086ecfec515ef82
        S: bb0f6b17ed26340ed9afe0fbce5ee783f72bed59 172.17.0.6:7003
           slots: (0 slots) slave
           replicates 26977b84aa3242f089b284e9f69aba1c847e69d8
        [OK] All nodes agree about slots configuration.
        >>> Check for open slots...
        >>> Check slots coverage...
        [OK] All 16384 slots covered.
    4. 进行数据操作

      • 集群会自动进行跳转与 key 操作
      shell
      # 登录 -c 代表以集群方式操作
      redis-cli -h 172.17.0.2 -p 7000 -c -a 123456
      
      # set
      172.17.0.2:7000> set abcde 1
      -> Redirected to slot [16097] located at 172.17.0.5:7002
      OK
      172.17.0.5:7002> keys *
      1) "abcde"
      172.17.0.5:7002>
      
      # get
      172.17.0.2:7000> get abcde
      -> Redirected to slot [16097] located at 172.17.0.5:7002
      "1"
      172.17.0.5:7002>
    5. cluster nodes查看集群节点信息

      shell
      26977b84aa3242f089b284e9f69aba1c847e69d8 172.17.0.5:7002@17002 myself,master - 0 1669216512000 3 connected 10923-16383
      bb0f6b17ed26340ed9afe0fbce5ee783f72bed59 172.17.0.6:7003@17003 slave 26977b84aa3242f089b284e9f69aba1c847e69d8 0 1669216513000 3 connected
      8c76b45a60807d75b1d1d7810ee12cffa890c1e1 172.17.0.4:7001@17001 master - 0 1669216514000 2 connected 5461-10922
      2a5c587dec73fdf3927b030439f9e35f7aadf833 172.17.0.7:7004@17004 slave 7166562ee201eecc7bbf65e76086ecfec515ef82 0 1669216514348 1 connected
      0ea1b80c7810b46dabb0fb98f92fbcf58ed7f462 172.17.0.8:7005@17005 slave 8c76b45a60807d75b1d1d7810ee12cffa890c1e1 0 1669216514000 2 connected
      7166562ee201eecc7bbf65e76086ecfec515ef82 172.17.0.2:7000@17000 master - 0 1669216515351 1 connected 0-5460
    6. Kill Master

      • 结束 Master 后,备用节点将代替主节点服务,原 Master 节点降级为 Slave 节点
      shell
      # before kill
      26977b84aa3242f089b284e9f69aba1c847e69d8 172.17.0.5:7002@17002 myself,master - 0 1669216608000 3 connected 10923-16383
      bb0f6b17ed26340ed9afe0fbce5ee783f72bed59 172.17.0.6:7003@17003 slave 26977b84aa3242f089b284e9f69aba1c847e69d8 0 1669216607000 3 connected
      8c76b45a60807d75b1d1d7810ee12cffa890c1e1 172.17.0.4:7001@17001 master - 0 1669216608666 2 connected 5461-10922
      2a5c587dec73fdf3927b030439f9e35f7aadf833 172.17.0.7:7004@17004 slave 7166562ee201eecc7bbf65e76086ecfec515ef82 0 1669216609669 1 connected
      0ea1b80c7810b46dabb0fb98f92fbcf58ed7f462 172.17.0.8:7005@17005 slave 8c76b45a60807d75b1d1d7810ee12cffa890c1e1 0 1669216608000 2 connected
      7166562ee201eecc7bbf65e76086ecfec515ef82 172.17.0.2:7000@17000 master - 1669216595614 1669216591598 1 connected 0-5460
      
      # after kill
      26977b84aa3242f089b284e9f69aba1c847e69d8 172.17.0.5:7002@17002 myself,master - 0 1669216615000 3 connected 10923-16383
      bb0f6b17ed26340ed9afe0fbce5ee783f72bed59 172.17.0.6:7003@17003 slave 26977b84aa3242f089b284e9f69aba1c847e69d8 0 1669216614000 3 connected
      8c76b45a60807d75b1d1d7810ee12cffa890c1e1 172.17.0.4:7001@17001 master - 0 1669216615689 2 connected 5461-10922
      2a5c587dec73fdf3927b030439f9e35f7aadf833 172.17.0.7:7004@17004 master - 0 1669216613000 7 connected 0-5460
      0ea1b80c7810b46dabb0fb98f92fbcf58ed7f462 172.17.0.8:7005@17005 slave 8c76b45a60807d75b1d1d7810ee12cffa890c1e1 0 1669216616691 2 connected
      7166562ee201eecc7bbf65e76086ecfec515ef82 172.17.0.2:7000@17000 master,fail - 1669216595614 1669216591598 1 connected
      
      # after reboot node
      26977b84aa3242f089b284e9f69aba1c847e69d8 172.17.0.5:7002@17002 myself,master - 0 1669216787000 3 connected 10923-16383
      bb0f6b17ed26340ed9afe0fbce5ee783f72bed59 172.17.0.6:7003@17003 slave 26977b84aa3242f089b284e9f69aba1c847e69d8 0 1669216791000 3 connected
      8c76b45a60807d75b1d1d7810ee12cffa890c1e1 172.17.0.4:7001@17001 master - 0 1669216790000 2 connected 5461-10922
      2a5c587dec73fdf3927b030439f9e35f7aadf833 172.17.0.7:7004@17004 master - 0 1669216792256 7 connected 0-5460
      0ea1b80c7810b46dabb0fb98f92fbcf58ed7f462 172.17.0.8:7005@17005 slave 8c76b45a60807d75b1d1d7810ee12cffa890c1e1 0 1669216791253 2 connected
      7166562ee201eecc7bbf65e76086ecfec515ef82 172.17.0.2:7000@17000 slave 2a5c587dec73fdf3927b030439f9e35f7aadf833 0 1669216790248 7 connected
    7. 添加新的 Node,默认是 Master

      shell
      # 第一个参数是新的Redis节点的IP和端口,第二个参数是任意一个已经存在的Redis节点的IP和端口
      redis-cli -a 123456 --cluster add-node 172.17.0.10:7006 172.17.0.2:7000
      redis-cli -a 123456 --cluster add-node 172.17.0.11:7007 172.17.0.2:7000
      
      Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
      >>> Adding node 172.17.0.10:7006 to cluster 172.17.0.2:7000
      >>> Performing Cluster Check (using node 172.17.0.2:7000)
      >>> Adding node 172.17.0.11:7007 to cluster 172.17.0.2:7000
      >>> Performing Cluster Check (using node 172.17.0.2:7000)
      
      S: 7166562ee201eecc7bbf65e76086ecfec515ef82 172.17.0.2:7000
         slots: (0 slots) slave
         replicates 2a5c587dec73fdf3927b030439f9e35f7aadf833
      S: bb0f6b17ed26340ed9afe0fbce5ee783f72bed59 172.17.0.6:7003
         slots: (0 slots) slave
         replicates 26977b84aa3242f089b284e9f69aba1c847e69d8
      M: 8c76b45a60807d75b1d1d7810ee12cffa890c1e1 172.17.0.4:7001
         slots:[5461-10922] (5462 slots) master
         1 additional replica(s)
      M: 26977b84aa3242f089b284e9f69aba1c847e69d8 172.17.0.5:7002
         slots:[10923-16383] (5461 slots) master
         1 additional replica(s)
      S: 0ea1b80c7810b46dabb0fb98f92fbcf58ed7f462 172.17.0.8:7005
         slots: (0 slots) slave
         replicates 8c76b45a60807d75b1d1d7810ee12cffa890c1e1
      M: 2a5c587dec73fdf3927b030439f9e35f7aadf833 172.17.0.7:7004
         slots:[0-5460] (5461 slots) master
         1 additional replica(s)
      M: b576aa576d161b836e154937c67d9428f25bb2ee 172.17.0.10:7006
         slots: (0 slots) master
      
      [OK] All nodes agree about slots configuration.
      >>> Check for open slots...
      >>> Check slots coverage...
      
      [OK] All 16384 slots covered.
      >>> Getting functions from cluster
      >>> Send FUNCTION LIST to 172.17.0.10:7006 to verify there is no functions in it
      >>> Send FUNCTION RESTORE to 172.17.0.10:7006
      >>> Send CLUSTER MEET to node 172.17.0.10:7006 to make it join the cluster.
      [OK] New node added correctly.
      
      ...
      • 添加完成后可见节点,但没有分配槽位
      shell
      bb0f6b17ed26340ed9afe0fbce5ee783f72bed59 172.17.0.6:7003@17003 slave 26977b84aa3242f089b284e9f69aba1c847e69d8 0 1669217828000 3 connected
      8c76b45a60807d75b1d1d7810ee12cffa890c1e1 172.17.0.4:7001@17001 master - 0 1669217828000 2 connected 5461-10922
      26977b84aa3242f089b284e9f69aba1c847e69d8 172.17.0.5:7002@17002 master - 0 1669217826000 3 connected 10923-16383
      a68f533865b0d570f2f894b76e6d5231b35de6cf 172.17.0.11:7007@17007 master - 0 1669217827528 8 connected
      0ea1b80c7810b46dabb0fb98f92fbcf58ed7f462 172.17.0.8:7005@17005 slave 8c76b45a60807d75b1d1d7810ee12cffa890c1e1 0 1669217828532 2 connected
      2a5c587dec73fdf3927b030439f9e35f7aadf833 172.17.0.7:7004@17004 master - 0 1669217829535 7 connected 0-5460
      b576aa576d161b836e154937c67d9428f25bb2ee 172.17.0.10:7006@17006 master - 0 1669217827000 0 connected
      7166562ee201eecc7bbf65e76086ecfec515ef82 172.17.0.2:7000@17000 myself,slave 2a5c587dec73fdf3927b030439f9e35f7aadf833 0 1669217827000 7 connected
    8. 将新的节点设置为 Slave

      shell
      # 连接到需要设置的从节点
      redis-cli -p 7007 -h 172.17.0.11 -a 123456
      # 设置绑定到主节点上 (replicate 没有参数就是恢复主节点)
      cluster replicate b576aa576d161b836e154937c67d9428f25bb2ee
      • 绑定完成后可见当前结点已成为 Slave 节点
      shell
      26977b84aa3242f089b284e9f69aba1c847e69d8 172.17.0.5:7002@17002 master - 0 1669218129000 3 connected 10923-16383
      7166562ee201eecc7bbf65e76086ecfec515ef82 172.17.0.2:7000@17000 slave 2a5c587dec73fdf3927b030439f9e35f7aadf833 0 1669218130590 7 connected
      b576aa576d161b836e154937c67d9428f25bb2ee 172.17.0.10:7006@17006 master - 0 1669218129000 0 connected
      bb0f6b17ed26340ed9afe0fbce5ee783f72bed59 172.17.0.6:7003@17003 slave 26977b84aa3242f089b284e9f69aba1c847e69d8 0 1669218127000 3 connected
      a68f533865b0d570f2f894b76e6d5231b35de6cf 172.17.0.11:7007@17007 myself,slave b576aa576d161b836e154937c67d9428f25bb2ee 0 1669218130000 0 connected
      8c76b45a60807d75b1d1d7810ee12cffa890c1e1 172.17.0.4:7001@17001 master - 0 1669218131592 2 connected 5461-10922
      2a5c587dec73fdf3927b030439f9e35f7aadf833 172.17.0.7:7004@17004 master - 0 1669218129587 7 connected 0-5460
      0ea1b80c7810b46dabb0fb98f92fbcf58ed7f462 172.17.0.8:7005@17005 slave 8c76b45a60807d75b1d1d7810ee12cffa890c1e1 0 1669218129000 2 connected
    9. 为新 Master 分配槽位(reshard slots)

      失去所有槽位的节点会变成从结点

      shell
      # reshard:新节点ip
      # cluster-from:已有节点id,多个id之间使用半角逗号分隔
      # cluster-to:新节点id
      # cluster-slots:新节点的哈希槽数量 (一共16384个,现在4个Master,所以均分4096个)
      
      redis-cli -h 172.17.0.5 -p 7002 -a 123456 --cluster reshard 172.17.0.10 7006
      # 或
      redis-cli -h 172.17.0.5 -p 7002 -a 123456 --cluster reshard 172.17.0.10 7006 --cluster-from 2a5c587dec73fdf3927b030439f9e35f7aadf833,8c76b45a60807d75b1d1d7810ee12cffa890c1e1,26977b84aa3242f089b284e9f69aba1c847e69d8 --cluster-to b576aa576d161b836e154937c67d9428f25bb2ee --cluster-slots 4096
      • 重分配后结果
      shell
      172.17.0.5:7002> cluster nodes
      b576aa576d161b836e154937c67d9428f25bb2ee 172.17.0.10:7006@17006 master - 0 1669219512000 9 connected 0-1364 5461-6826 10923-12287
      26977b84aa3242f089b284e9f69aba1c847e69d8 172.17.0.5:7002@17002 myself,master - 0 1669219509000 3 connected 12288-16383
      bb0f6b17ed26340ed9afe0fbce5ee783f72bed59 172.17.0.6:7003@17003 slave 26977b84aa3242f089b284e9f69aba1c847e69d8 0 1669219510000 3 connected
      8c76b45a60807d75b1d1d7810ee12cffa890c1e1 172.17.0.4:7001@17001 master - 0 1669219512000 2 connected 6827-10922
      2a5c587dec73fdf3927b030439f9e35f7aadf833 172.17.0.7:7004@17004 master - 0 1669219510000 7 connected 1365-5460
      a68f533865b0d570f2f894b76e6d5231b35de6cf 172.17.0.11:7007@17007 slave b576aa576d161b836e154937c67d9428f25bb2ee 0 1669219512000 9 connected
      0ea1b80c7810b46dabb0fb98f92fbcf58ed7f462 172.17.0.8:7005@17005 slave 8c76b45a60807d75b1d1d7810ee12cffa890c1e1 0 1669219513826 2 connected
      7166562ee201eecc7bbf65e76086ecfec515ef82 172.17.0.2:7000@17000 slave 2a5c587dec73fdf3927b030439f9e35f7aadf833 0 1669219512822 7 connected
    10. 主动移除结点

      1. 移除 slot(也是重分配)

      2. 移除节点(需要先移除从节点)

        shell
        redis-cli -a 123456 --cluster del-node 172.17.0.2:7000 b576aa576d161b836e154937c67d9428f25bb2ee
    11. 异常时,修复结点插槽

      shell
      redis-cli --cluster fix 172.17.0.2:7000 -a 123456
      
      Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
      Could not connect to Redis at 172.17.0.11:7007: No route to host
      Could not connect to Redis at 172.17.0.10:7006: No route to host
      172.17.0.4:7001 (8c76b45a...) -> 0 keys | 4096 slots | 1 slaves.
      172.17.0.5:7002 (26977b84...) -> 1 keys | 4096 slots | 1 slaves.
      172.17.0.7:7004 (2a5c587d...) -> 0 keys | 4096 slots | 1 slaves.
      [OK] 1 keys in 3 masters.
      0.00 keys per slot on average.
      >>> Performing Cluster Check (using node 172.17.0.2:7000)
      S: 7166562ee201eecc7bbf65e76086ecfec515ef82 172.17.0.2:7000
      slots: (0 slots) slave
      replicates 2a5c587dec73fdf3927b030439f9e35f7aadf833
      S: bb0f6b17ed26340ed9afe0fbce5ee783f72bed59 172.17.0.6:7003
      slots: (0 slots) slave
      replicates 26977b84aa3242f089b284e9f69aba1c847e69d8
      M: 8c76b45a60807d75b1d1d7810ee12cffa890c1e1 172.17.0.4:7001
      slots:[6827-10922] (4096 slots) master
      1 additional replica(s)
      M: 26977b84aa3242f089b284e9f69aba1c847e69d8 172.17.0.5:7002
      slots:[12288-16383] (4096 slots) master
      1 additional replica(s)
      S: 0ea1b80c7810b46dabb0fb98f92fbcf58ed7f462 172.17.0.8:7005
      slots: (0 slots) slave
      replicates 8c76b45a60807d75b1d1d7810ee12cffa890c1e1
      M: 2a5c587dec73fdf3927b030439f9e35f7aadf833 172.17.0.7:7004
      slots:[1365-5460] (4096 slots) master
      1 additional replica(s)
      [OK] All nodes agree about slots configuration.
      >>> Check for open slots...
      >>> Check slots coverage...
      [ERR] Not all 16384 slots are covered by nodes.
      
      *** Fixing slots coverage with 1 unreachable masters is dangerous: redis-cli will assume that slots about masters that are not reachable are not covered, and will try to reassign them to the reachable nodes. This can cause data loss and is rarely what you want to do. If you really want to proceed use the --cluster-fix-with-unreachable-masters option.
      • 强制修复掉线节点,主节点插槽会被重新分配,可能会遗失数据
      shell
      redis-cli --cluster fix 172.17.0.2:7000 -a 123456 --cluster-fix-with-unreachable-masters