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

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

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

上一篇文章教大家手动搭建了一个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.


相关推荐

一篇文章带你了解PHP的学习使用(php的教程)

ThinkPHP5实战...

在memcached管理php的session(memcached libevent)

PHP的session(会话管理)一般是以文件形式进行,而在多个Web服务器之间进行session管理时memecached会比文件管理方式更加方便。在这里介绍如何使用memcached管理PHP的s...

php传值和传引用的区别(php 传值和传引用)

php传值:在函数范围内,改变变量值得大小,都不会影响到函数外边的变量值。PHP传引用:在函数范围内,对值的任何改变,在函数外部也有所体现,因为传引用传的是内存地址。传值:和copy是一样的。【打个比...

PHP 常量详解教程(php常量和变量)

常量类似变量,但是常量一旦被定义就无法更改或撤销定义。PHP常量常量是单个值的标识符(名称)。在脚本中无法改变该值。有效的常量名以字符或下划线开头(常量名称前面没有$符号)。注释:与变量不同,常...

php自学零基础入门小知识(php新手入门教程)

我们就把PHP入门当成一个苹果吧!一口一口的吃掉他!不啰嗦了!开始了1、嵌入方法:类似ASP的<%,PHP可以是<?php或者是<?,结束符号是?>,当然您也可以自己指定。2、...

PHP 语法详解(php语法大全)

PHP脚本在服务器上执行,然后向浏览器发送回纯HTML结果。基础PHP语法PHP脚本可放置于文档中的任何位置。PHP脚本以<?php开头,以?>结尾:<?php...

PHP笔记(一)PHP基础知识(php必背知识点)

创建PHP程序PHP代码框架<?php>2.文件命名规则...

PHP 8新特性之Attributes(注解),你掌握了吗?

PHP8的Alpha版本,过几天就要发布了,其中包含了不少的新特性,当然我自己认为最重要的还是JIT,这个我从2013年开始参与,中间挫折无数,失败无数后,终于要发布的东东。不过,今天呢,我不打算谈J...

PHP基本语法之标记与注释(php注释规范)

1、标记由于PHP是嵌入式脚本语言,它在实际开发中经常会与HTML内容混在一起,所以为了区分HTML与PHP代码,需要使用标记对PHP代码进行标识。如:<html>...

php注解(PHP注解 性能)

目标了解和使用php注解,如果你已经掌握其他一种具有注解的语言,例如:java、python等,你在本文中只需要了解点语法就行。示例php8以前的版本,注解写在注释里,如果你掌握其他语言的注解,你是不...

数据丢失?别慌!MySQL备份恢复攻略

想象一下,某个晴朗的午后,你正享受着咖啡,突然接到紧急电话:你的网站或APP彻底挂了!系统崩溃,界面全白。虽然心头一紧,但你或许还能安慰自己:系统崩溃只是暂停服务,数据还在,修复修复就好了。然而,如果...

MySQL 日志:undo log、redo log、binlog

今天来和大家分享MySQL的三个日志文件,可以说MySQL的多数特性都是围绕日志文件实现,而其中最重要的有以下三种:...

MySQL三大日志:binlog、redolog、undolog全解析

binlog概述在MySQL数据库中,binlog可是个相当重要的存在,它的全称为binarylog,也就是二进制日志。它就像是数据库的“记忆本”,记录了所有的DDL(数据定义语言)和...

1、MySQL数据库介绍(mysql数据库简单介绍)

1.1数据库的核心定义数据库的本质数据库乃存储数据对象之容器,涵盖如下关键组件:表(Table)...

MySQL 日志双雄:实时监控与历史归档实战优化

MySQL日志双雄:实时监控+历史归档实战用这招让你家日志系统再也不卡不爆炸MySQL十亿级日志处理:从洪峰到归档全攻略手把手教你用MySQL搞定ELK级日志监控在微服务架构大行其道的今天,日志系统早...