Redis 不同集群方案对比
- 本文基于 Redis 7.0.5 版本测试
主从复制模式
Redis 的主从复制是如何做的?复制过程中也会产生各种问题? | Kaito's Blog (kaito-kidd.com)
简述

- 客户端可对主数据库进行读写操作,对从数据库进行读操作,主数据库写入的数据会实时自动同步给从数据库
- Redis 2.6 开始,Slave 默认只读
优点
- 读写分离:主节点写,从节点读,提高服务器的读写负载能力。
- 数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。
- 故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复 ; 实际上是一种服务的冗余。
- 负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务(即写 Redis 数据时应用连接主节点,读 Redis 数据时应用连接从节点),分担服务器负载 ; 尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高 Redis 服务器的并发量。
- 高可用基础:主从复制机制是 Sentinel 和 Cluster 机制的基础,两者都实现了故障转移,即主节点故障后,Redis 负责选择一个从节点切换为主节点,继续提供服务。
缺点
- Master 故障时不能自动切换,Master 或 Slave 的宕机都可能导致客户端请求失败,需要等待机器重启或手动切换客户端 IP 才能恢复
- Master 掉线前如果没有完成同步则数据可能丢失
部署实践
编辑 Master 节点启动配置文件
复制 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>启动 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
此时,Master 上进行的操作会被同步到 Slave 上
进入 Slave 节点,执行命令
REPLICAOF no one,将关闭对 Master 节点的同步模式
Sentinel(哨兵)模式
简述

- 解决了主从复制模式中 Master 不被监控的问题
- 哨兵监控当前集群状态,当 Master 掉线后将从 Slave 中选出一个优先级最高的当作新的 Master
优点
- 哨兵模式基于主从复制模式,所以主从复制模式有的优点,哨兵模式也有
- 哨兵模式下,Master 挂掉可以自动进行切换,系统可用性更高
缺点
- 同样也继承了主从模式难以在线扩容的缺点,Redis 的容量受限于单机配置
- 需要额外的资源来启动 Sentinel 进程,实现相对复杂一点,同时 Slave 节点作为备份节点不提供服务
部署实战
编辑 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>使用命令
redis-sentinel sentinel.conf或redis-server sentinel.conf --sentinel启动 sentinel 节点,需要注意 sentinel 节点数需要满足 2n+1(n>=1)的奇数个shellredis-server *:26379 [sentinel] ...下线当前 Master 节点
检查原 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原 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
- 简述

- 豌豆荚开源的集群方案,目前已停止维护
- 将 Redis 集群对外抽象成单个服务,业务无需关心集群实现方式,
- 将 Redis 在客户端和服务端中间增加一个代理层,客户端只需要操作这个代理层,代理层实现了具体的请求转发规则,然后转发请求到后面的多个节点上,因此这种方式也叫做中心化方式的集群方案
- 优点
- 在线扩容。在扩容期间不影响客户端的访问,也就是不需要停机。这对业务使用方是极大的便利,当集群性能不够时,就可以动态增加节点来提升集群的性能
- 基于 Redis 3.2.8 二次开发,支持异步迁移数据
- 缺点
- 框架实现时间较早,目前已经不再维护,且内置 Redis 3.2.8 版本,不可升级
- 对部分操作命令进行了禁用,详见: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
- 优点
- 功能简单,只实现请求路由转发
- 缺点
- 无法在线扩容、缩容
Redis Cluster 模式
Redis 集群化方案对比:Codis、Twemproxy、Redis Cluster | Kaito's Blog (kaito-kidd.com)
简述
- Cluster 没有使用代理层进行转发,而是把请求转发逻辑一部分放在客户端,一部分放在了服务端,它们之间互相配合完成请求的处理
- SDK 中内置了请求转发的逻辑,所以业务开发人员同样不需要自己编写转发规则,Redis Cluster 采用 16384 个槽位进行路由规则的转发

- Cluster 模式实现了 Redis 的分布式存储,即每台节点存储不同的内容,来解决在线扩容的问题。
- 在 Redis 的每个节点上,都有一个插槽(slot),取值范围为 0-16383
- 当存取 key 的时候,Redis 会根据 CRC16 的算法得出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,通过这个值,去找到对应的插槽所对应的节点,然后直接自动跳转到这个对应的节点上进行存取操作
- 为了保证高可用,Cluster 模式也引入主从复制模式,一个主节点对应一个或者多个从节点,当主节点宕机的时候,就会启用从节点
- 当其它主节点 ping 一个主节点 A 时,如果半数以上的主节点与 A 通信超时,那么认为主节点 A 宕机了。如果主节点 A 和它的从节点都宕机了,那么该集群就无法再提供服务了
- Cluster 模式集群节点最小配置 6 个节点(3 主 3 从,因为需要半数以上),其中主节点提供读写操作,从节点作为备用节点,不提供请求,只作为故障转移使用。
优点
- 提供了在线数据迁移、节点扩容缩容等功能,内部还内置了哨兵完成故障自动恢复功能
- 所有的 Redis 节点彼此互联(PING-PONG 机制),内部使用二进制协议优化传输速度和带宽
- 节点的
fail是通过集群中超过半数的节点检测失效时才生效 - 客户端与 Redis 节点直连,不需要中间代理层。客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可
缺点
Redis Cluster 在线数据迁移性能不高,迁移过程中遇到大 key 时还有可能长时间阻塞迁移的两个节点。
数据通过异步复制,不保证数据的强一致性
Slave 充当“冷备”,不能缓解读压力
批量操作限制,目前只支持具有相同 Slot 值的 Key 执行批量操作,对
mset、mget、sunion等操作支持不友好shell172.17.0.5:7002> mset a 1 b 2 (error) CROSSSLOT Keys in request don\'t hash to the same slotkey 事务操作支持有线,只支持多 key 在同一节点的事务操作,多 key 分布不同节点时无法使用事务功能
不支持多数据库空间,单机 Redis 可以支持 16 个 db,集群模式下只能使用一个,即 db 0
shell172.17.0.5:7002> select 1 (error) ERR SELECT is not allowed in cluster mode
部署实战
编辑启动配置文件
config# Redis 启动端口 port 6379 # 开启集群模式 cluster-enabled yes # master 密码 masterauth <master-password> # 集群配置文件 需要指定不重名的文件 不需要手动维护 cluster-config-file nodes-6379.conf启动不同端口至少 6 个 Redis 服务 ```
创建集群
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:7005Redis5 通过 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>
执行结果
shellWarning: 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.
进行数据操作
- 集群会自动进行跳转与 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>cluster nodes查看集群节点信息shell26977b84aa3242f089b284e9f69aba1c847e69d8 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-5460Kill 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添加新的 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. ...- 添加完成后可见节点,但没有分配槽位
shellbb0f6b17ed26340ed9afe0fbce5ee783f72bed59 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将新的节点设置为 Slave
shell# 连接到需要设置的从节点 redis-cli -p 7007 -h 172.17.0.11 -a 123456 # 设置绑定到主节点上 (replicate 没有参数就是恢复主节点) cluster replicate b576aa576d161b836e154937c67d9428f25bb2ee- 绑定完成后可见当前结点已成为 Slave 节点
shell26977b84aa3242f089b284e9f69aba1c847e69d8 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为新 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- 重分配后结果
shell172.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主动移除结点
移除 slot(也是重分配)
移除节点(需要先移除从节点)
shellredis-cli -a 123456 --cluster del-node 172.17.0.2:7000 b576aa576d161b836e154937c67d9428f25bb2ee
异常时,修复结点插槽
shellredis-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.- 强制修复掉线节点,主节点插槽会被重新分配,可能会遗失数据
shellredis-cli --cluster fix 172.17.0.2:7000 -a 123456 --cluster-fix-with-unreachable-masters