从redis-trib.rb到集群加减节点实战

redis-trib.rb工具介绍

redis-trib.rb是redis集群管理工具,可以检查集群、创建删除节点、挪key、批量下发实例命令等等。
不是没有redis-trib.rb就没有集群管理了,没有redis-trib.rb照样可以管理集群。redis本身就有集群相关管理命令,redis-trib.rb只是封装了这些命令,它极大的简化了集群管理工作。
redis-trib.rb以前是开源工具,现在已经合并到redis软件中了,跟redis-cli在一个bin目录下,所以这个命令一般都能直接用。如果没有的话检查下环境变量,或者去官网下一个
redis-trib.rb本身支持交互窗口,但是生产都得提前准备好方案,设置提前写好运行脚本,交互模式不太实用,所以本篇的介绍都是针对非交互式的。

常用命令

redis-trib.rb查看help
redis-trib.rb可做如下操作

command 行为
create 创建集群,需要提前建好实例
check 检查集群,其实也是输出集群信息,check比info更实用一点
info 输出集群信息
fix 修复集群,自检并自动修复集群异常,某些场景无法自动修复
reshard 挪slot命令,加减节点的核心命令
rebalance 因为slot不均匀导致数据倾斜,rebalance可以自动转移slot平衡集群
add-node 添加节点
del-node 删除节点
set-timeout 设置集群心跳连接超时参数
call 在所有节点上执行命令
import 从外部redis导入集群
help 打印此帮助

查看集群状态

redis-trib.rb check  --password  mypass  127.30.30.10:6486 
>>> Performing Cluster Check (using node 127.30.30.10:6486)
M: 62e4f253ce48af6699713c11dcc8baae062a736d 127.30.30.10:6486
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
S: e2f650538610505be567cf4bf87c599e1afd354d 127.30.30.47:6486
   slots: (0 slots) slave
   replicates 62e4f253ce48af6699713c11dcc8baae062a736d
S: 081dad4fadf8cf29a018ef12b703eb9a3363a86a 127.30.30.51:6485
   slots: (0 slots) slave
   replicates 387a5764c93f4d52c9f46996df4af0d74abacf0f
M: 2e0335e3fc413568c3f2900a66c837d34db6565a 127.30.30.51:6484
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
S: 78c01003a13979221d9ef42660f4715c5ccd48aa 127.30.30.45:6484
   slots: (0 slots) slave
   replicates 2e0335e3fc413568c3f2900a66c837d34db6565a
M: 387a5764c93f4d52c9f46996df4af0d74abacf0f 127.30.30.47:6485
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

至少确认两个信息

  • check输出[ok],无异常输出,集群状态正常
  • 节点ID,在reshard和加减节点时会用到

这个经典的3主3从redis集群架构如下
从redis-trib.rb到集群加减节点实战_第1张图片

reshard参数说明

host:port:这个是必传参数,用来从一个节点获取整个集群信息,相当于获取集群信息的入口。
–from :需要从哪些源节点上迁移slot,可从多个源节点完成迁移,以逗号隔开,传递的是节点的node id,还可以直接传递–from all,这样源节点就是集群的所有节点,不传递该参数的话,则会在迁移过程中提示用户输入。
–to :slot需要迁移的目的节点的node id,目的节点只能填写一个,不传递该参数的话,则会在迁移过程中提示用户输入。
–slots :需要迁移的slot数量,不传递该参数的话,则会在迁移过程中提示用户输入。
–yes:设置该参数,可以在打印执行reshard计划的时候,提示用户输入yes确认后再执行reshard。
–timeout :设置migrate命令的超时时间。
–pipeline :定义cluster getkeysinslot命令一次取出的key数量,不传的话使用默认值为10。
非交互的执行命令,如下

redis-trib.rb reshard --password mypass --from f2ce18189001d64fd55d3500f48338aa6d92bf7e 	--to da0b390d8fd35b303f857dd15a3a4ac0ca317c7b --slots 100  --pipeline 1000 --timeout 100000000  --yes 127.10.0.79:6416 

表示非交互模式从节点da0b390d8fd35b303f857dd15a3a4ac0ca317c7b转移100个slot到f2ce18189001d64fd55d3500f48338aa6d92bf7e节点
连接节点为127.10.0.79:6416(redis-trib.rb连接到集群的登陆节点),注意这个节点最好是缩容节点后仍保留的节点

总是报命令错误?

redis-trib.rb的help(直接敲redis-trib.rb就出来help了)有点问题。help看上去把–password放在了命令最后,如果按照help来敲命令,那么你可能总是会得到命令错误的提示:

[ERR] Wrong number of arguments for specified sub command

应该把 --password 放到“中间”,command动作后面,像这样

redis-trib.rb call  --password  mypass  127.30.30.130:7367 config get maxmemory 

操作注意事项

使用redis自带工具redis-trib.rb reshard做slot和key的迁移,步骤很简单。但是仍有一些注意点,有些可能导致reshard中断,需手工修复。
为了减少不必要的麻烦并提高变更的成功率,我们需要注意这些点

  • 只要把缩容后的slot计算均匀,手动分配slot到保留的节点,slot是均匀的,最后不太需要做rebalance操作
  • 确保缩容后,每个机器的节点数不超过总节点数的一半
  • 对于节点较多的集群,可以把命令做成脚本。但是需要注意,在每个reshard命令中间插入sleep 5。reshard命令太“紧凑”也可能导致reshard失败
  • timeout参数尽量设置的够大,设置过小会导致reshard命令中断
  • 对于内存较大、或者有大key的节点,转移这些keys的时间会更长,更应该调大timeout参数
  • 内存得是足够的。比如减少节点后,每个实例的内存是否足够,如果不够需要增加maxmemory或者不要减少那么多节点

变更风险点

reshard是否在线操作?

reshard操作会把slot设置为迁移状态,迁移key时业务还是会有短暂的感知。

加减节点是否需要重启redis实例?

不需要!整个加减节点的所有操作是不需要重启redis实例的

加减节点是否需要重启应用?

不确定!取决于中间件是否缓存了路由
实际案例中增删节点时遇到过有些应用一点感觉没有,有些必须要重启才正常的情况

slot计算

迁移前把迁移后的slot的分配算好,就可以不重复迁移slot,并减少rebalance这一步。再者,如果节点过多或者物理内存(或cg)有限,本身迁移过程中需要把slot分散地reshard到其他各个节点上。所以需要提前计算好slot的分配以及reshard过程中迁移多少slot。
以一个56节点的redis cluster为例,减少16个节点到40个节点
缩容前,每个节点的slots为:16384/56=292.5(292或293)
缩容后,每个节点的slots为:16384/40=409.6(409或410)
那么,reshard时转移的slot为:410-293=117
因为要把删除的节点上的slot全部转移完
所以每个节点上还剩一点slots需要转移完 292.5-117-117=58.5(58或59)
具体数值看节点到底有多少slot,目的是slot均匀且删除节点的slot全部转移,差1、2个slot问题不大

从redis-trib.rb到集群加减节点实战_第2张图片

实施方案案例

从多个集群节点中减少一部分节点,并完成回退方案(回退就是增加节点)

删除集群的一部分节点

  1. 选择要踢出的节点,并计算分配到其他节点的slot个数
    (一般来说,会选择整个机器上部署的所有节点)
RLZLCLUSTER	 RLZLCLUSTER_40	 主库	hostlzl111 	76a301a4f1bd18d19df29aff6dc9c42e141f7225		127.10.11.50:6475  
RLZLCLUSTER	 RLZLCLUSTER_41	 从库	hostlzl111 	1df5c7a055f3e776d856a43f83f0b8414ddb33a5	127.10.11.50:6476  
  1. reshard迁移slot(会转移key)
    把需要剔除的节点上的slot迁移走,迁到不会剔除的节点上
#redis-trib.rb  check 127.10.11.35:6612 |grep -A 2 -B 2  3aca6bf3cc102d65d5dbed9e461773c32d3864c2

#76a301a4f1bd18d19df29aff6dc9c42e141f7225 节点上所有slot迁移,迁移到其他2个节点上

redis-trib.rb reshard --password mypass --from 76a301a4f1bd18d19df29aff6dc9c42e141f7225 	--to 726823529b76f2048711f07aea11615fa4ea5720 --slots 30  --pipeline 1000 --timeout 100000000  --yes 127.10.11.79:6416 
redis-trib.rb reshard --password mypass --from 76a301a4f1bd18d19df29aff6dc9c42e141f7225 	--to da6ced81cbaa2ca65514a5819469ae6f72e99737 --slots 117  --pipeline 1000 --timeout 100000000  --yes 127.10.11.79:6416 
  1. 检查删除的节点没有slot
redis-trib.rb  check --password mypass 127.10.11.79:6416|grep -E -A 1 "127.10.11.50"
  1. 剔除节点 (ip:port为登陆节点,不是删除节点)
#删除从节点:
redis-trib.rb del-node --password mypass 127.10.11.79:6416 1df5c7a055f3e776d856a43f83f0b8414ddb33a5

#删除主节点:
redis-trib.rb del-node --password mypass 127.10.11.79:6416 76a301a4f1bd18d19df29aff6dc9c42e141f7225

回退方案(将节点加回集群)

  1. 将新的单实例加入为主节点
/paic/redis/3.2.12/bin/redis-trib.rb  add-node --password mypass 172.30.32.9:6476  $ip:port  
  1. 将新的单实例加入为从节点
#指定给某个集群的主节点添加从节点
redis-trib.rb add-node --slave --master-id <one_master_id>  
/paic/redis/3.2.12/bin/redis-trib.rb check  --password mypass 127.10.11.50:6495

3.进行rebalance(整个集群只需要执行一次),或者手动reshard

/paic/redis/3.2.12/bin/redis-trib.rb  rebalance  --password mypass --threshold <arg>  127.10.11.50:6495

(附)迁移中断问题处理

迁移命令中断,集群check报错

[OK] All nodes agree about slots configuration.
>>> Check for open slots...
[WARNING] Node 127.10.11.2:6410 has slots in importing state (1312).
[WARNING] Node 127.10.11.50:6475 has slots in migrating state (1312).
[WARNING] The following slots are open: 1312
>>> Check slots coverage...
[OK] All 16384 slots covered.
*** Please fix your cluster problems before resharding

解决方案一:用fix自动修复

redis-trib.rb fix --password mypass 127.10.11.50:6495

解决方案二: 如果fix失败,手动stable,检查key的位置

r -c
CLUSTER SETSLOT 1312 stable
cluster GETKEYSINSLOT 1312 1000  

你可能感兴趣的:(REDIS,redis,redis集群,redis-trib,reshard,加减节点)