redis-trib.rb是官方提供的Redis Cluster的管理工具,无需额外下载,默认位于源码包的src目录下,但因该工具是用ruby开发的,所以需要准备相关的依赖环境。
wget https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.1.tar.gz yum -y install zlib-devel tar xvf ruby-2.5.1.tar.gz cd ruby-2.5.1/ ./configure -prefix=/usr/local/ruby make make install cd /usr/local/ruby/ cp bin/ruby /usr/local/bin cp bin/gem /usr/local/bin
wget http://rubygems.org/downloads/redis-3.3.0.gem gem install -l redis-3.3.0.gem
# redis-trib.rb help Usage: redis-trib <command> <options> <arguments ...> create host1:port1 ... hostN:portN --replicas <arg> check host:port info host:port fix host:port --timeout <arg> reshard host:port --from <arg> --to <arg> --slots <arg> --yes --timeout <arg> --pipeline <arg> rebalance host:port --weight <arg> --auto-weights --use-empty-masters --timeout <arg> --simulate --pipeline <arg> --threshold <arg> add-node new_host:new_port existing_host:existing_port --slave --master-id <arg> del-node host:port node_id set-timeout host:port milliseconds call host:port command arg arg .. arg import host:port --from <arg> --copy --replace help (show this help) For check, fix, reshard, del-node, set-timeout you can specify the host and port of any working node in the cluster.
支持的操作如下: - create:创建集群 - check:检查集群 - info:查看集群信息 - fix:修复集群 - reshard:在线迁移slot - rebalance:平衡集群节点slot数量 - add-node:添加新节点 - del-node:删除节点 - set-timeout:设置节点的超时时间 - call:在集群所有节点上执行命令 - import:将外部redis数据导入集群
redis-trib.rb create --replicas 1 127.0.0.1:6379 127.0.0.1:6380 127.0.0.1:6381 127.0.0.1:6382 127.0.0.1:6383 127.0.0.1:6384 --replicas参数指定集群中每个主节点配备几个从节点,这里设置为1
关于主从节点的选择及槽的分配,其算法如下: - 把节点按照host分类,这样保证master节点能分配到更多的主机中。 - 遍历host列表,从每个host列表中弹出一个节点,放入interleaved数组。直到所有的节点都弹出为止。 - 将interleaved数组中前master个数量的节点保存到masters数组中。 - 计算每个master节点负责的slot数量,16384除以master数量取整,这里记为N。 - 遍历masters数组,每个master分配N个slot,最后一个master,分配剩下的slot。 - 接下来为master分配slave,分配算法会尽量保证master和slave节点不在同一台主机上。 - 对于分配完指定slave数量的节点,还有多余的节点,也会为这些节点寻找master。分配算法会遍历两次masters数组。 - 第一次遍历master数组,在余下的节点列表找到replicas数量个slave。每个slave为第一个和master节点host不一样的节点,如果没有不一样的节点,则直接取出余下列表的第一个节点。 - 第二次遍历是分配节点数除以replicas不为整数而多出的一部分节点。
redis-trib.rb check 127.0.0.1:6379 指定任意一个节点即可。
redis-trib.rb info 127.0.0.1:6383
redis-trib.rb fix 127.0.0.1:6379 目前fix命令能修复两种异常 - 节点中存在处于迁移中(importing或migrating状态)的slot。 - 节点中存在未分配的slot。 其它异常不能通过fix命令修复。
redis-trib.rb reshard 127.0.0.1:6379 redis-trib.rb reshard host:port --from <arg> --to <arg> --slots <arg> --yes --timeout <arg> --pipeline <arg> redis-trib.rb reshard --from a8b3d0f9b12d63dab3b7337d602245d96dd55844 --to f413fb7e6460308b17cdb71442798e1341b56cbc --slots 10923 --yes --pipeline 20 127.0.0.1:6383 其中 host:port:必传参数,集群内任意节点地址,用来获取整个集群信息。 --from:源节点id,如果有多个源节点,使用逗号分隔,如果是all,则源节点为集群内出目标节点外的其它所有主节点。 --to:目标节点id,只能填写一个。 --slots:需要迁移槽的总数量。 --yes:迁移无需用户手动确认。 --timeout:控制每次migrate操作的超时时间,默认为60000毫秒。 --pipeline:控制每次批量迁移键的数量,默认为10。
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 del-node host:port node_id 在删除节点之前,其对应的槽必须为空,所以,在进行节点删除动作之前,必须使用redis-trib.rb reshard将其迁移出去。 需要注意的是,如果某个节点的槽被完全迁移出去,其对应的slave也会随着更新,指向迁移的目标节点。
redis-trib add-node new_host:new_port existing_host:existing_port --slave --master-id <arg> new_host:new_port:待添加的节点,必须确保其为空或不在其它集群中。 existing_host:existing_port:集群中任意一个节点的地址。 如果添加的是主节点,只需指定源节点和目标节点的地址即可。 redis-trib.rb add-node 127.0.0.1:6379 127.0.0.1:6384 如果添加的是从节点,其语法如下, redis-trib.rb add-node --slave --master-id f413fb7e6460308b17cdb71442798e1341b56cbc 127.0.0.1:6379 127.0.0.1:6384 注意: --slave和--master-id必须写在前面 添加从节点,可不设置--master-id,此时会随机选择主节点 线上建议使用redis-trib.rb添加新节点,因为其会对新节点的状态进行检查。如果手动使用cluster meet命令加入已经存在于其它集群的节点,会造成被加入节点的集群合并到现有集群的情况,从而造成数据丢失和错乱,后果非常严重,线上谨慎操作。
redis-trib.rb set-timeout host:port milliseconds 其实就是批量修改集群各节点的cluster-node-timeout参数。
redis-trib.rb call host:port command arg arg .. arg
redis-trib.rb import --from 127.0.0.1:6378 127.0.0.1:6379 其内部处理流程如下: - 通过load_cluster_info_from_node方法加载集群信息,check_cluster方法检查集群是否健康。 - 连接外部redis节点,如果外部节点开启了cluster_enabled,则提示错误([ERR] The source node should not be a cluster node.) - 通过scan命令遍历外部节点,一次获取1000条数据。 - 遍历这些key,计算出key对应的slot。 - 执行migrate命令,源节点是外部节点,目的节点是集群slot对应的节点,如果设置了--copy参数,则传递copy参数,其会保留源节点的key,如果设置了--replace,则传递replace参数。如果目标节点中存在同名key,其值会被覆盖。两个参数可同时指定。 - 不停执行scan命令,直到遍历完所有key。 - 迁移完成。
redis-trib.rb命令详解