百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT技术 > 正文

redis专题系列18 -- redis-trib.rb常用命令详解

wptr33 2025-01-05 20:32 10 浏览

上一篇文章教大家手动搭建了一个Cluster集群,并演示了故障转移的过程,本文接着讲Cluster集群的动态扩展,简单来讲就是如何在Cluster模式下实现节点的新增和废弃节点的删除以及如何重新分配slot来达到集群的高可用,实现集群的动态扩展,而这一切都基于redis-trib.rb脚本,首先,我们对redis-trib.rb的命令开始说起:

本文分两部分:1,redis-trib.rb 常用命令介绍 2.命令演示

1.redis-trib.rb 常用命令介绍

可以使用 redis-trib.rb help 查看说明文档

常用命令使用演示

1.创建集群

命令格式:redis-trib.rb create --replicas n [host:port,...]

--replicas参数指定集群中每个主节点配备n从节点。

备注:如果创建集群时,单节点的数据库文件包含slot数据(例如nodes.7000.conf包含其他节点配置信息或者dump.7000.rdb包含0~16384某个slot的数据),集群会创建失败。所有节点的配置文件和上文(redis专题系列17 -- redis 集群模式之Cluster集群)提到的一样.

示例:

先依次启动要加入集群的节点,然后创建集群,我把这些命令放在了 batch.bat 脚本中执行,然后把batch.bat放到redis安装目录下



创建集群窗口日志:


关于主从节点的选择及槽的分配,其算法如下:

1> 把节点按照host分类,这样保证master节点能分配到更多的主机中。

2> 遍历host列表,从每个host列表中弹出一个节点,放入interleaved数组。直到所有的节点都弹出为止。

3> 将interleaved数组中前master个数量的节点保存到masters数组中。

4> 计算每个master节点负责的slot数量,16384除以master数量取整,这里记为N。

5> 遍历masters数组,每个master分配N个slot,最后一个master,分配剩下的slot。

6> 接下来为master分配slave,分配算法会尽量保证master和slave节点不在同一台主机上。对于分配完指定slave数量的节点,还有多余的节点,也会为这些节点寻找master。分配算法会遍历两次masters数组。

7> 第一次遍历master数组,在余下的节点列表找到replicas数量个slave。每个slave为第一个和master节点host不一样的节点,如果没有不一样的节点,则直接取出余下列表的第一个节点。

8> 第二次遍历是分配节点数除以replicas不为整数而多出的一部分节点。

2.检查/校验集群状态

命令格式:redis-trib.rb check 任意节点h:p

示例:

3.查看集群信息

命令格式:redis-trib.rb info 任意节点h:p

示例:


4.修复单节点

命令格式:redis-trib.rb fix 故障节点h:p

目前fix命令能修复两种异常,

1. 节点中存在处于迁移中(importing或migrating状态)的slot。

2. 节点中存在未分配的slot。

其他异常不能修复。

示例:


5.在线迁移slot

交互环境中使用

命令格式: redis-trib.rb reshard 节点h:p


如果你不知带7002的节点id是多少,可以去看log中的记录,或者使用前面的命名info , check,或者去看日志nodes.7002.conf. 示例中7002节点对应的id为:24789385e9540dca53f853e836c6d1dd8c26aba8

输入接受这1000个slots的节点id,接着会询问你源节点(即要移动哪个节点的1000 slots到7002节点上),我们选择节点7001(如果想从其他的节点平均分配到7002,可以输入all),id为 a796e7ea80024a3dfb88df25ead248454638a907,接着输入done,trib为我们生成分配计划

输入yes,执行slots分配计划,看到7001的节点5461~6460共1000个slots分配到7002。

此时查看slots分配状况:

下面我们再演示一下all的情形,分配200个节点到7000上:

此时集群slots的分配状况为:

7000的slots从5461->5661(成功的增加200 slots),7001 slots 6461 ->6342(减少了120 slots),7002 slots 从4462->4381(减少了80 slots),trib根据7001和7002的slots数量按照比例共分配了200个slots到7000上,即 7001应分配的slots数量为 200*(6461/(6461+4462))=120,剩下的(200-120=80)slots由7002提供,所有的slots迁移都是由小到大。

完整命令:

redis-trib.rb reshard host:port --from <arg> --to <arg> --slots <arg> --yes --timeout <arg> --pipeline <arg>

其中,

host:port:必传参数,集群内任意节点地址,用来获取整个集群信息。

--from:源节点id,如果有多个源节点,使用逗号分隔,如果是all,则源节点为集群内出目标节点外的其它所有主节点。

--to:目标节点id,只能填写一个。

--slots:需要迁移槽的总数量。

--yes:迁移无需用户手动确认。

--timeout:控制每次migrate操作的超时时间,默认为60000毫秒。

--pipeline:控制每次批量迁移键的数量,默认为10。

如,

redis-trib.rb reshard --from a8b3d0f9b12d63dab3b7337d602245d96dd55844 --to f413fb7e6460308b17cdb71442798e1341b56cbc --slots 10923 --yes --pipeline 20 127.0.0.1:6383

6.平衡集群节点slot数量

我们知道,假设由于reshard造成单点的slots数量过多,那么对应的其key命中率就越高,访问压力就过大,这个节点就会成为集群中的瓶颈。那么,rebalance可以很好的为我们解决这个问题。

命令格式:

rebalance host:port

--weight <arg>

--auto-weights

--use-empty-masters

--timeout <arg>

--simulate

--pipeline <arg>

--threshold <arg>

参数释义:

--weight <arg>:节点的权重,格式为node_id=weight,如果需要为多个节点分配权重的话,需要添加多个--weight <arg>参数,即--weight b31e3a2e=5 --weight 60b8e3a1=5,node_id可为节点名称的前缀,只要保证前缀位数能唯一区分该节点即可。没有传递–weight的节点的权重默认为1。

--auto-weights:自动将每个节点的权重默认为1。如果--weight和--auto-weights同时指定,则--auto-weights会覆盖前者。

--threshold <arg>:只有节点需要迁移的slot阈值超过threshold,才会执行rebalance操作。

--use-empty-masters:默认没有分配slot节点的master是不参与rebalance的。如果要让其参与rebalance,需添加该参数。

--timeout <arg>:设置migrate命令的超时时间。

--simulate:设置该参数,只会提示用户会迁移哪些slots,而不会执行真正的迁移操作。

--pipeline <arg>:定义cluster getkeysinslot命令一次取出的key数量,不传的话使用默认值为10。

示例:

命令:

redis-trib.rb rebalance --weight a796e7ea80024a3dfb88df25ead248454638a907=3 --weight 24789385e9540dca53f853e836c6d1dd8c26aba8=4 --use-empty-masters 127.0.0.1:7001

然后redis集群会执行平衡计划,移动slots多的节点到少的节点,每一个跳动的#号就代表一个移动中的slot.

此时集群就会按照权重调整不同节点对应的slots数量,rebalance后的slots数量为:

7.删除节点

语法:redis-trib.rb del-node host:port node_id

在删除节点之前,其对应的槽必须为空,所以,在进行节点删除动作之前,必须使用redis-trib.rb reshard将其迁移出去。

需要注意的是,如果某个节点的槽被完全迁移出去,其对应的slave也会随着更新,指向迁移的目标节点。

示例:


8.添加新节点

命令格式:redis-trib add-node new_host:new_port existing_host:existing_port --slave --master-id <arg>

new_host:new_port:待添加的节点,必须确保其为空或不在其它集群中。否则,会提示以下错误。

[ERR] Node 127.0.0.1:6379 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.

所以,线上建议使用redis-trib.rb添加新节点,因为其会对新节点的状态进行检查。如果手动使用cluster meet命令加入已经存在于其它集群的节点,会造成被加入节点的集群合并到现有集群的情况,从而造成数据丢失和错乱,后果非常严重,线上谨慎操作。

existing_host:existing_port:集群中任意一个节点的地址。

如果添加的是主节点,只需指定源节点和目标节点的地址即可。


如果添加的是从节点,其语法如下

redis-trib.rb add-node --slave --master-id f413fb7e6460308b17cdb71442798e1341b56cbc 127.0.0.1:6379 127.0.0.1:6384

注意:--slave和--master-id必须写在前面

9.设置节点的超时时间

redis-trib.rb set-timeout host:port milliseconds

其实就是批量修改集群各节点的cluster-node-timeout参数。

10.在集群所有节点上执行命令

格式:

redis-trib.rb call host:port command arg arg .. arg

示例:

11.将外部redis数据导入集群

redis-trib.rb import --from 127.0.0.1:7000 127.0.0.1:7001

其内部处理流程如下:

1> 通过load_cluster_info_from_node方法加载集群信息,check_cluster方法检查集群是否健康。

2> 连接外部redis节点,如果外部节点开启了cluster_enabled,则提示错误([ERR] The source node should not be a cluster node.)

3> 通过scan命令遍历外部节点,一次获取1000条数据。

4> 遍历这些key,计算出key对应的slot。

5> 执行migrate命令,源节点是外部节点,目的节点是集群slot对应的节点,如果设置了--copy参数,则传递copy参数,其会保留源节点的key,如果设置了--replace,则传递replace参数。如果目标节点中存在同名key,其值会被覆盖。两个参数可同时指定。

6> 不停执行scan命令,直到遍历完所有key。

7> 迁移完成。

示例:


OK,redis-trib.rb相关命令到此为止,下面针对cluster集群就轻而易举了。

补充:redis5.0之后,有关集群的相关命令集成到了redis-cli中,查看相关命令redis-cli --cluster help.


相关推荐

【推荐】一款开源免费、美观实用的后台管理系统模版

如果您对源码&技术感兴趣,请点赞+收藏+转发+关注,大家的支持是我分享最大的动力!!!项目介绍...

Android架构组件-App架构指南,你还不收藏嘛

本指南适用于那些已经拥有开发Android应用基础知识的开发人员,现在想了解能够开发出更加健壮、优质的应用程序架构。首先需要说明的是:AndroidArchitectureComponents翻...

高德地图经纬度坐标批量拾取(高德地图批量查询经纬度)

使用方法在桌面上新建一个index.txt文件,把下面的代码复制进去保存,再把文件名改成index.html保存,双击运行打开即可...

flutter系列之:UI layout简介(flutter ui设计)

简介对于一个前端框架来说,除了各个组件之外,最重要的就是将这些组件进行连接的布局了。布局的英文名叫做layout,就是用来描述如何将组件进行摆放的一个约束。...

Android开发基础入门(一):UI与基础控件

Android基础入门前言:...

iOS的布局体系-流式布局MyFlowLayout

iOS布局体系的概览在我的CSDN博客中的几篇文章分别介绍MyLayout布局体系中的视图从一个方向依次排列的线性布局(MyLinearLayout)、视图层叠且停靠于父布局视图某个位置的框架布局(M...

TDesign企业级开源设计系统越发成熟稳定,支持 Vue3 / 小程序

TDesing发展越来越好了,出了好几套组件库,很成熟稳定了,新项目完全可以考虑使用。...

WinForm实现窗体自适应缩放(winform窗口缩放)

众所周知,...

winform项目——仿QQ即时通讯程序03:搭建登录界面

上两篇文章已经对CIM仿QQ即时通讯项目进行了需求分析和数据库设计。winform项目——仿QQ即时通讯程序01:原理及项目分析...

App自动化测试|原生app元素定位方法

元素定位方法介绍及应用Appium方法定位原生app元素...

61.C# TableLayoutPanel控件(c# tabcontrol)

摘要TableLayoutPanel在网格中排列内容,提供类似于HTML元素的功能。TableLayoutPanel控件允许你将控件放在网格布局中,而无需精确指定每个控件的位置。其单元格...

想要深入学习Android性能优化?看完这篇直接让你一步到位

...

12个python数据处理常用内置函数(python 的内置函数)

在python数据分析中,经常需要对字符串进行各种处理,例如拼接字符串、检索字符串等。下面我将对python中常用的内置字符串操作函数进行介绍。1.计算字符串的长度-len()函数str1='我爱py...

如何用Python程序将几十个PDF文件合并成一个PDF?其实只要这四步

假定你有一个很无聊的任务,需要将几十个PDF文件合并成一个PDF文件。每一个文件都有一个封面作为第一页,但你不希望合并后的文件中重复出现这些封面。即使有许多免费的程序可以合并PDF,很多也只是简单的将...

Python入门知识点总结,Python三大数据类型、数据结构、控制流

Python基础的重要性不言而喻,是每一个入门Python学习者所必备的知识点,作为Python入门,这部分知识点显得很庞杂,内容分支很多,大部分同学在刚刚学习时一头雾水。...