上一篇文章《Redis(九):多机部署之Cluster(集群)模式》中,已经介绍过Redis集群的搭建以及在redis-cli中使用命令操作redis集群。实际上可以不用进入redis-cli,而是直接通过redis-cli程序使用--cluster功能项直接操作集群,其底层实际上也是使用了redis命令。那为什么还要使用redis-cli --cluster功能项呢?因为其更简单,功能更强大。在上一篇文章介绍cluster setslot
命令时,使用redis cluster命令需要经过四步才能将槽成功迁移;使用--cluster功能项,则使用一条语句就能实现类似的槽迁移功能。
./redis-cli --cluster reshard 127.0.0.1:30002 --cluster-from 9d148120512f85f29dd246e515243fd6019c7dcc --cluster-to d85dc362370f81fe627305e9b246365bd51a02c2 --cluster-slots 1
很明显,使用redis-cli的--cluster子命令可以大幅度提高集群的操作效率。
一、redis-cli简介
一般我们使用redis-cli的目的是进入某个服务器节点交互式执行一些命令,比如我们可以使用./redis-cli -h 127.0.0.1 -p 6379
命令进入6379服务的交互控制台。除了进入控制台,redis-cli还可以不进入交互控制台,直接执行一些命令,其支持的命令可以使用./redis-cli --help
查看。
分类 | 选项 | 描述 | 默认值/示例 |
---|---|---|---|
连接相关 | -h <hostname> |
指定 Redis 服务器主机名 | 127.0.0.1 |
-p <port> |
指定 Redis 服务器端口 | 6379 |
|
-s <socket> |
使用 Unix 套接字连接(覆盖主机名和端口) | ||
-a <password> |
连接服务器的密码(也可用 REDISCLI_AUTH 环境变量) |
||
--user <username> |
使用 ACL 风格认证(需配合 -a ) |
||
--askpass |
强制从 STDIN 输入密码(忽略 -a 和环境变量) |
||
-u <uri> |
使用 URI 格式连接(如 redis://user:pass@host:port ) |
||
-n <db> |
选择数据库编号 | ||
命令执行 | -r <repeat> |
重复执行命令 N 次 | redis-cli -r 100 INCR counter |
-i <interval> |
配合 -r 设置命令间隔时间(支持小数秒) |
-i 0.1 (0.1秒间隔) |
|
-x |
从 STDIN 读取最后一个参数 | `cat file.txt | |
-e |
命令失败时返回错误退出码 | ||
--eval <file> |
执行 Lua 脚本文件 | --eval script.lua key1 key2 , arg1 |
|
--ldb |
启用 Lua 调试器(异步模式) | ||
输出格式 | --raw |
原始格式输出(非终端时默认) | |
--no-raw |
强制格式化输出(即使是非终端) | ||
--csv |
CSV 格式输出 | ||
-d <delimiter> |
设置原始格式的批量响应分隔符 | 默认 \n |
|
--show-pushes <yn> |
控制是否显示 RESP3 PUSH 消息 | 默认根据终端类型决定 | |
监控与诊断 | --stat |
显示服务器滚动统计(内存、客户端等) | |
--latency |
实时延迟监控模式 | ||
--latency-history |
延迟历史记录(默认15秒间隔) | -i 5 修改间隔 |
|
--bigkeys |
查找包含大量元素的键 | ||
--hotkeys |
查找热点键(需 LFU 策略) | ||
--scan --pattern <pat> |
扫描匹配模式的键 | 默认 * |
|
特殊模式 | -c |
集群模式(跟随重定向) | |
--pipe |
将原始协议从 STDIN 传输到服务器 | `cat data.txt | |
--replica |
模拟副本显示主服务器命令 | ||
数据操作 | --rdb <filename> |
将远程服务器的 RDB 转储保存到本地文件 | --rdb dump.rdb |
集群管理 | --cluster <command> |
执行集群管理命令(如 --cluster help ) |
|
其他 | --help |
显示帮助信息 | |
--version |
显示版本信息 |
比如我们使用命令./redis-cli -p 6379
进入控制台之后使用get命令获取键值,如果键值中有中文,则可能会出现中文乱码,解决方法就是使用使用--raw
选项,使用./redis-cli -p 6379 --raw
重新进入控制台就可以解决问题了。
接下来讲解redis-cli集群管理相关的功能。
二、redis-cli集群管理工具
redis-cli客户端附带的集群管理程序使用--cluster
选项开启。先使用help命令查看其有多少子命令可用。
[root@localhost demo_redis_6.2.1]# ./redis-cli --cluster help
Cluster Manager Commands:
create host1:port1 ... hostN:portN
--cluster-replicas <arg>
check host:port
--cluster-search-multiple-owners
info host:port
fix host:port
--cluster-search-multiple-owners
--cluster-fix-with-unreachable-masters
reshard host:port
--cluster-from <arg>
--cluster-to <arg>
--cluster-slots <arg>
--cluster-yes
--cluster-timeout <arg>
--cluster-pipeline <arg>
--cluster-replace
rebalance host:port
--cluster-weight <node1=w1...nodeN=wN>
--cluster-use-empty-masters
--cluster-timeout <arg>
--cluster-simulate
--cluster-pipeline <arg>
--cluster-threshold <arg>
--cluster-replace
add-node new_host:new_port existing_host:existing_port
--cluster-slave
--cluster-master-id <arg>
del-node host:port node_id
call host:port command arg arg .. arg
--cluster-only-masters
--cluster-only-replicas
set-timeout host:port milliseconds
import host:port
--cluster-from <arg>
--cluster-from-user <arg>
--cluster-from-pass <arg>
--cluster-from-askpass
--cluster-copy
--cluster-replace
backup host:port backup_directory
help
For check, fix, reshard, del-node, set-timeout you can specify the host and port of any working node in the cluster.
Cluster Manager Options:
--cluster-yes Automatic yes to cluster commands prompts
可以看到有很多子命令,接下来看看每个子命令的用法。
create:创建集群
create子命令允许用户根据已有的节点创建出一个集群。用户只需要在命令中依次给出各个节点的IP地址和端口号,命令就会将它们聚合到同一个集群中,并根据节点的数量将槽平均地指派给它们负责,完整命令如下所示:
./redis-cli --cluster create host1:port1 ... hostN:portN --cluster-replicas <arg>
--cluster-replicas
选项可选,用于指定每个master节点有多少个副本。
比如我们之前创建了包含5个主节点,5个父节点的集群:
./redis-cli --cluster create \ #创建集群命令
127.0.0.1:30001 127.0.0.1:30002 127.0.0.1:30003 127.0.0.1:30004 127.0.0.1:30005 127.0.0.1:30006 127.0.0.1:30007 127.0.0.1:30008 127.0.0.1:30009 127.0.0.1:30010 \ #指定10个节点的ip和端口号
--cluster-replicas 1 #每个主节点1个副本
check:检查集群
通过cluster选项的check子命令,用户可以检查集群的配置是否正确,以及全部16384个槽是否已经全部指派给了主节点。该命令接受集群中任意一个节点的ip和端口号作为参数,完整命令如下所示:
./redis-cli --cluster check host:port --cluster-search-multiple-owners
--cluster-search-multiple-owners
选项可选,用于着重验证每个哈希槽是否只被一个节点拥有。运行示例如下所示:
./redis-cli --cluster check 127.0.0.1:30001 --cluster-search-multiple-owners
输出如下:

info:查看集群信息
用户可以通过cluster选项的info子命令查看集群的相关信息。完整命令格式如下所示:
./redis-cli --cluster info host:port
host:port是集群中任意节点的ip和端口号。
其输出包括:有多少个主节点,每个主节点有几个副本节点,分配了多少槽以及节点中有多少key。
./redis-cli --cluster info 127.0.0.1:30001
输出如下所示:

fix:修复集群状态错误
当集群在重分片、负载均衡或者槽迁移的过程中出现错误时或者集群状态错误时,执行cluster选项的fix子命令,可以让操作涉及的槽重新回到正常状态:
./redis-cli --cluster fix host:port #集群中任意节点的地址和端口号
--cluster-search-multiple-owners #检查并修复哈希槽(hash slot)被多个节点同时声明的冲突问题
--cluster-fix-with-unreachable-masters #即使某些主节点不可达,仍然尝试修复集群状态。
使用该命令前应当先试用check
子命令检查集群问题,确认问题后再运行该命令修复。如果集群没问题,运行该命令不会做任何操作:
./redis-cli --cluster fix 127.0.0.1:30001 --cluster-search-multiple-owners --cluster-fix-with-unreachable-masters
可以看到运行fix命令后,内部应该先调用了check命令检查了集群状态,如果没发现错误则不会进行修复操作。
reshard:重分片
通过cluster选项的reshard子命令,用户可以将指定数量的槽从原节点迁移至目标节点,被迁移的槽将交由后者负责,并且槽中已有的数据也会陆续从原节点转移至目标节点,该命令常用于集群扩容/缩容:
./redis-cli --cluster reshard host:port #集群中任意一个节点的地址和端口
--cluster-from <node-id> #源节点
--cluster-to <node-id> #目标节点
--cluster-slots <num-slots> #要迁移的槽数量
--cluster-yes #跳过确认提示
--cluster-timeout <milliseconds> #超时时间(默认 60000ms)
--cluster-pipeline <num> #批量迁移 key 的数量(默认 10)
--cluster-replace #强制替换目标节点上的现有数据
该命令的作用:
- 重新分配哈希槽(reshard),调整数据分布。
- 支持手动指定源节点和目标节点,或让 Redis 自动选择。
- 批量迁移 key,提高迁移效率。
- 适用于集群扩容或缩容(如新增节点后需要均衡数据)。
该命令有两种模式:手动交互模式以及全自动模式。
手动交互模式
手动交互模式只需要执行./redis-cli --cluster reshard host:port
就会进入交互模式,根据提示输入信息,比如待迁移的节点id、槽数量等最后提交即可完成迁移。比如现在30001节点下有0到3276槽,我们现在将30001节点下的一个槽迁移到30011:
[root@localhost demo_redis_6.2.1]# ./redis-cli --cluster reshard 127.0.0.1:30001
>>> Performing Cluster Check (using node 127.0.0.1:30001)
M: d85dc362370f81fe627305e9b246365bd51a02c2 127.0.0.1:30001
slots:[0-3276] (3277 slots) master
1 additional replica(s)
S: d5f1adb8939529abcfe24e657bd01787b7d7928c 127.0.0.1:30003
slots: (0 slots) slave
replicates 32661eb91b3be79b9a9d9ba873e1066bd64916a7
M: 32661eb91b3be79b9a9d9ba873e1066bd64916a7 127.0.0.1:30010
slots:[6554-9829] (3276 slots) master
1 additional replica(s)
M: adbbff5339b083b1e4fb641951e6fb9085ffb25c 127.0.0.1:30005
slots:[13107-16383] (3277 slots) master
1 additional replica(s)
S: 1728a0fb708c776303f25e33c0add3297332cd64 127.0.0.1:30007
slots: (0 slots) slave
replicates 6d2c221d2ff15ae7fb9d5a5b7551ae5b493e791f
S: 0db0c21f6f9b075b887c0ef1548cf35cb0505b0b 127.0.0.1:30009
slots: (0 slots) slave
replicates adbbff5339b083b1e4fb641951e6fb9085ffb25c
S: c33e236a553d9e658a0bb549d933567de5a756f8 127.0.0.1:30006
slots: (0 slots) slave
replicates 9d148120512f85f29dd246e515243fd6019c7dcc
M: 9d148120512f85f29dd246e515243fd6019c7dcc 127.0.0.1:30002
slots:[3277-6553] (3277 slots) master
1 additional replica(s)
S: dd7079d8486119fecc4e71f10fb705889ea8668b 127.0.0.1:30008
slots: (0 slots) slave
replicates d85dc362370f81fe627305e9b246365bd51a02c2
M: 6d2c221d2ff15ae7fb9d5a5b7551ae5b493e791f 127.0.0.1:30004
slots:[9830-13106] (3277 slots) master
1 additional replica(s)
M: 79a28e2df5e13dd726c892c42ee35a15423b00fb 127.0.0.1:30011
slots: (0 slots) master
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
How many slots do you want to move (from 1 to 16384)? 1
What is the receiving node ID? 79a28e2df5e13dd726c892c42ee35a15423b00fb
Please enter all the source node IDs.
Type 'all' to use all the nodes as source nodes for the hash slots.
Type 'done' once you entered all the source nodes IDs.
Source node #1: d85dc362370f81fe627305e9b246365bd51a02c2
Source node #2: done
Ready to move 1 slots.
Source nodes:
M: d85dc362370f81fe627305e9b246365bd51a02c2 127.0.0.1:30001
slots:[0-3276] (3277 slots) master
1 additional replica(s)
Destination node:
M: 79a28e2df5e13dd726c892c42ee35a15423b00fb 127.0.0.1:30011
slots: (0 slots) master
Resharding plan:
Moving slot 0 from d85dc362370f81fe627305e9b246365bd51a02c2
Do you want to proceed with the proposed reshard plan (yes/no)? yes
Moving slot 0 from 127.0.0.1:30001 to 127.0.0.1:30011:
迁移完成之后,运行命令./redis-cli --cluster info 127.0.0.1:30001
查看集群槽分布情况:

可以看到30011节点上多了一个槽。
全自动模式
全自动模式就是将交互模式下需要输入的参数全放到了命令中,接下来使用全自动模式将30011节点上的1个槽迁移回30001:
./redis-cli --cluster reshard 127.0.0.1:30001 --cluster-from 79a28e2df5e13dd726c892c42ee35a15423b00fb --cluster-to d85dc362370f81fe627305e9b246365bd51a02c2 --cluster-slots 1
运行结果:

看似失败了,实际上已经成功了,可以运行./redis-cli --cluster info 127.0.0.1:30001
命令检查:

可以看到30001节点的槽已经恢复,而且还多了一个从节点,同时,30011节点不见了。。可以猜想到发生了什么事情了:30011节点变成了30001节点的从节点了,更详细的信息可以通过./redis-cli --cluster check 127.0.0.1:30001
命令查看。
为什么会发生这种事情呢?我们只是迁移了一个槽,为什会发生主节点降级成从节点的事情?
Redis集群有个特殊的机制,如果一个 主节点失去了所有槽位,Redis Cluster 可能会自动将其降级为从节点,在 Redis 6.2+ 中,如果一个主节点不再管理任何槽位,它可能会被 自动转换为从节点,以避免集群中出现无用的主节点。
我们的30001节点上只有一个槽,这最后一个槽迁移到30001节点上以后,它就失去了所有槽,然后就被自动降级成了从节点。
rebalance:负载均衡
该命令用于重新平衡Redis 集群的哈希槽(slots)分布,确保各个主节点的槽位数量尽可能均匀:
./redis-cli --cluster relalance host:port #集群中的任意一个节点地址
-cluster-weight <node1=w1...nodeN=wN> #指定节点的权重(影响槽位分配比例),node1=2 node2=1 表示 node1 分配 2 倍于 node2 的槽位
--cluster-use-empty-masters #允许对没有槽位的主节点进行重新分配(默认会忽略它们)
--cluster-timeout <arg> #设置操作超时时间(单位:毫秒,默认 60000)
--cluster-simulate #模拟 rebalance,只显示计划,不实际执行
--cluster-pipeline <arg> #设置每次迁移的 key 数量(默认 10)
--cluster-threshold <arg> #设置触发 rebalance 的最小槽位差异(默认 2)。例如:如果节点间槽位数差异 ≤ 2,则不会触发 rebalance
--cluster-replace #强制替换故障节点(如果某些节点不可用)
比如我们的30011节点是新增的节点,就可以使用该命令将槽位重新均衡:
./redis-cli --cluster rebalance 127.0.0.1:30001 --cluster-use-empty-masters
运行结果:

可以看到,五个主节点都分别把自己的一部分槽分给了新增加的30011节点,使用./redis-cli --cluster info 127.0.0.1:30001
命令查看集群节点信息:

可以看到集群中全部槽已经平均分配到了六个主节点中。
delnode:删除节点
当用户不再需要集群中的某个节点时,可以通过cluster选项的del-node子命令来移除该节点:
./redis-cli --cluster del-node host:port node_id
首先看看集群中的节点:
./redis-cli --cluster info 127.0.0.1:30001

集群中现在有6个节点,我想要把30011节点移除掉,运行如下命令:
./redis-cli --cluster del-node 127.0.0.1:30001 79a28e2df5e13dd726c892c42ee35a15423b00fb

移除节点失败了,因为redis集群不允许移除有数据的节点。
先使用reshard命令将全部的槽转移出去,再尝试:
./redis-cli --cluster reshard 127.0.0.1:30001 #使用交互式方式进行槽迁移,从30011转移全部的槽到30001
转移完成之后,重新查看集群信息:

可以看到30011已经没有槽了,此时再删除30011节点:
[root@localhost demo_redis_6.2.1]# ./redis-cli --cluster del-node 127.0.0.1:30001 79a28e2df5e13dd726c892c42ee35a15423b00fb
>>> Removing node 79a28e2df5e13dd726c892c42ee35a15423b00fb from cluster 127.0.0.1:30001
>>> Sending CLUSTER FORGET messages to the cluster...
>>> Sending CLUSTER RESET SOFT to the deleted node.
从日志中可以看到,实际上底层还是使用了cluster的内部集群命令cluster forget
以及cluster reset
。
删除完成之后在查看集群信息:

六个节点只剩了五个,30011节点已经被成功移除。但是槽1的槽数量比较多,可以使用rebalance进行负载均分下:
./redis-cli --cluster rebalance 127.0.0.1:30001

再次查看集群状态,槽数量已经均分到了五个节点:

add-node:添加节点
该命令的完整格式:
./redis-cli --cluster add-node
new_host:new_port #新节点地址
existing_host:existing_port #集群中现有任意节点地址,用于连接集群
--cluster-slave #指定新节点为从节点
--cluster-master-id <master-id> #指定主节点ID
新节点默认以主节点身份加入集群,使用--cluster-slave
选项可以使其以从节点身份加入集群,如果指定了--cluster-master-id
,则会被当做指定主节点的从节点;否则redis会自动为新节点选择一个主节点。
比如我们现在要将30011节点添加到集群,运行如下命令:
./redis-cli --cluster add-node 127.0.0.1:30011 127.0.0.1:30001

可以看到,实际上底层还是使用了cluster的内置命令meet将新节点加入集群的。查看集群状态:./redis-cli --cluster info 127.0.0.1:30001

可以看到新节点已经加入了集群,但是没有任何槽分配,可以使用rebalance命令进行槽均衡分配下:./redis-cli --cluster rebalance 127.0.0.1:30001 --cluster-use-empty-masters

再次查看集群状态,可以看到新节点30011已经分配了槽:

call:执行命令
通过cluster选项的call子命令,用户可以在整个集群的所有节点上执行给定的命令:
./redis-cli --cluster call
host:port #集群任意节点,用于连接集群
command arg arg .. arg #执行的命令
--cluster-only-masters #只在master节点执行
--cluster-only-replicas #只在从节点执行
该命令没什么好说的,尝试运行下get命令:

set-timeout:设置超时时间
通过cluster选项的set-timeout子命令,用户可以为集群的所有节点重新设置cluster-node-timeout选项的值:
./redis-cli --cluster set-timeout host:port milliseconds
超时时间单位是毫秒。
运行如下命令,将超时时间设置为5秒钟:
./redis-cli --cluster set-timeout 127.0.0.1:30001 5000

import:导入数据
import选项用于将某单机上的数据导入集群:
./redis-cli --cluster import
host:port #目标集群的任意节点地址
--cluster-from <arg> #源Redis实例地址
--cluster-from-user <arg> #源实例用户名(如果需要认证)
--cluster-from-pass <arg> #源实例密码(如果需要认证)
--cluster-from-askpass #交互式输入源实例密码
--cluster-copy #复制模式(保留源数据)
--cluster-replace #替换模式(覆盖冲突键)
接下来我们将6379单机redis的数据迁移到redis集群,运行如下命令:
./redis-cli --cluster import 127.0.0.1:30001 --cluster-from 127.0.0.1:6379 --cluster-copy --cluster-replace
backup:备份
./redis-cli --cluster backup host:port backup_directory
该命令用于将集群数据备份到本地目录,比如我们现在将集群备份到data目录:
./redis-cli --cluster backup 127.0.0.1:30001 ./data

看看data文件夹:

可以看到该选项将每个主节点的数据都存到了单独的rdb文件。
END.
注意:本文归作者所有,未经作者允许,不得转载