Redis的slot迁移工具

工具下载:

https://github.com/eyjian/redis-tools/blob/master/move_redis_slot.sh

支持迁移已有的keys。

#!/bin/sh# 迁移 slot 工具,但一次只能迁移一个 slot
#
使用时,需要指定如下几个参数:
1)参数1:必选参数,用于指定被迁移的 slot
2)参数2:必选参数,用于指定源节点(格式为:ip:port)
3)参数3:必选参数,用于指定目标节点(格式为:ip:port)
6)参数4:可选参数,用于指定访问 redis 的密码
#
使用示例(将2020从10.9.12.8:1383迁移到10.9.12.9:1386):
move_redis_slot.sh 2020 10.9.12.8:1383 10.9.12.9:1386
#
执行本脚本时,有两个"确认",
第一个"确认"是提示参数是否正确,
第二个"确认"是提示是否迁移已有的keys,
如果输入非yes则只迁移slot,不迁移已有keys。

确保redis-cli可用
REDIS_CLI=${REDIS_CLI:-redis-cli}
which "$REDIS_CLI" > /dev/null 2>&1
if test $? -ne 0; then
    echo "\redis-cli\ not exists or not executable"
    exit 1
fi

参数检查
if test $# -ne 3 -a $# -ne 4; then
  echo -e "Usage: basename $0 \033[1;33mslot\033[m source_node destition_node redis_password"
  echo -e "Example1: basename $0 \033[1;33m2020\033[m 127.0.0.1:6379 127.0.0.1:6380"
  echo -e "Example2: basename $0 \033[1;33m2020\033[m 127.0.0.1:6379 127.0.0.1:6380 password123456"
  exit 1
fi

SLOT=$1
SRC_NODE="$2"
DEST_NODE="$3"
REDIS_PASSOWRD="$4"

得到指定节点的 nodeid
function get_node_id()
{
  node="$1"
  node_ip="echo $node|cut -d':' -f1"
  node_port=echo $node|cut -d':' -f2

  # 得到对应的 nodeid
  $REDIS_CLI --raw --no-auth-warning -a "$REDIS_PASSOWRD" \
-h $node_ip -p $node_port \
CLUSTER NODES | awk -v node=$node -F'[ @]' '{if ($2==node) printf("%s",$1);}'
}

SRC_NODE_ID="get_node_id $SRC_NODE"
SRC_NODE_IP="echo $SRC_NODE|cut -d':' -f1"
SRC_NODE_PORT=echo $SRC_NODE|cut -d':' -f2
DEST_NODE_ID="get_node_id $DEST_NODE"
DEST_NODE_IP="echo $DEST_NODE|cut -d':' -f1"
DEST_NODE_PORT=echo $DEST_NODE|cut -d':' -f2

echo -e "\033[1;33mSource\033[m node: $SRC_NODE_IP:$SRC_NODE_PORT($SRC_NODE_ID)"
echo -e "\033[1;33mDestition\033[m node: $DEST_NODE_IP:$DEST_NODE_PORT($DEST_NODE_ID)"
if test -z "$SRC_NODE_ID"; then
  echo -e "Can not get the source node ID of \033[1;33m$SRC_NODE\033[m"
  exit 1
fi
if test -z "$DEST_NODE_ID"; then
  echo -e "Can not get the destition node ID of \033[1;33m$DEST_NODE\033[m"
  exit 1
fi

echo -en "Confirm to continue? [\033[1;33myes\033[m/\033[1;33mno\033[m]"
read -r -p " " input
if test "$input" != "yes"; then
  exit 1
fi
echo "........."

目标节点上执行 IMPORTING 操作
如果 $SLOT 已在目标节点,则执行时报错"ERR I'm already the owner of hash slot 1987"
echo -e "\033[1;33mImporting\033[m $SLOT from $SRC_NODE($SRC_NODE_ID) to $DEST_NODE($DEST_NODE_ID) ..."
err=$REDIS_CLI --raw --no-auth-warning -a "$REDIS_PASSOWRD" \
-h $DEST_NODE_IP -p $DEST_NODE_PORT \
CLUSTER SETSLOT $SLOT IMPORTING $SRC_NODE_ID
if test "X$err" != "XOK"; then
  echo "[destition://$DEST_NODE_IP:$DEST_NODE_PORT] $err"
  exit 1
fi

源节点上执行 MIGRATING 操作
如果 $SLOT 并不在源节点上,则执行时报错"ERR I'm not the owner of hash slot 1987"
echo -e "\033[1;33mMigrating\033[m $SLOT from $SRC_NODE($SRC_NODE_ID) to $DEST_NODE($DEST_NODE_ID) ..."
err=$REDIS_CLI --raw --no-auth-warning -a "$REDIS_PASSOWRD" \
-h $SRC_NODE_IP -p $SRC_NODE_PORT \
CLUSTER SETSLOT $SLOT MIGRATING $DEST_NODE_ID
if test "X$err" != "XOK"; then
  echo "[source://$SRC_NODE_IP:$SRC_NODE_PORT] $err"
  exit 1
fi

是否迁移已有的keys?
echo -en "Migrate keys in slot://$SLOT? [\033[1;33myes\033[m/\033[1;33mno\033[m]"
read -r -p " " input
if test "$input" = "yes"; then
  first=1 # 是否第一轮keys迁移操作
  batch=100 # 一次批量迁移的keys数
  timeout_ms=60000 # 超时时长(单位:毫秒)
  destination_db=0 # 对于redis集群,取值总是为0
  num_keys=0

  echo "........."
  echo -e "Migrating keys in slot://$SLOT ..."
  while true
  do
    # 在源节点上执行:
    # 借助命令"CLUSTER GETKEYSINSLOT"和命令"MIGRATE"迁移已有的keys
    keys="$REDIS_CLI --raw --no-auth-warning -a "$REDIS_PASSOWRD" \
-h $SRC_NODE_IP -p $SRC_NODE_PORT \
CLUSTER GETKEYSINSLOT $SLOT $batch | tr '\n' ' ' | xargs"
    if test -z "$keys"; then
      if test $first -eq 1; then
        echo -e "No any keys to migrate in slot://$SLOT"
      else
        echo -e "Finished migrating all keys (\033[1;33m$num_keys\033[m) in slot://$SLOT"
      fi
      break
    fi
    first=0
    n=echo "$keys" | tr -cd ' ' | wc -c
    num_keys=$(($num_keys + $n))
    #echo -e "(\033[1;33m$n\033[m)$keys"

    # 在源节点上执行命令"MIGRATE"迁移到目标节点
    # MIGRATE returns OK on success,
    # or NOKEY if no keys were found in the source instance
    if test -z "$REDIS_PASSOWRD"; then
      err=$REDIS_CLI --raw \
-h $SRC_NODE_IP -p $SRC_NODE_PORT \
MIGRATE $DEST_NODE_IP $DEST_NODE_PORT "" $destination_db $timeout_ms \
REPLACE KEYS $keys
    else
      err=$REDIS_CLI --raw --no-auth-warning -a "$REDIS_PASSOWRD" \
-h $SRC_NODE_IP -p $SRC_NODE_PORT \
MIGRATE $DEST_NODE_IP $DEST_NODE_PORT "" $destination_db $timeout_ms \
REPLACE AUTH "$REDIS_PASSOWRD" KEYS $keys
    fi
    if test "X$err" = "XNOKEY"; then
      break
    fi
    echo -e "\033[1;33m$n\033[m keys migratd"
  done
fi

取得所有 master 节点
nodes=($REDIS_CLI --raw --no-auth-warning -a "$REDIS_PASSOWRD" -h $DEST_NODE_IP -p $DEST_NODE_PORT \
CLUSTER NODES | awk '{if (match($3,"master")) printf("%s\n",$2);}')

在所有 master 节点上执行 NODE 操作
实际上,只可对源节点和目标节点执行 NODE 操作,
新的配置会自动在集群中传播。
echo "........."
for node in ${nodes[*]}; do
  node_ip="echo $node|cut -d':' -f1"
  node_port=echo $node|cut -d':' -f2
  echo -en "NODE: $node_ip:$node_port "
  err=$REDIS_CLI --raw --no-auth-warning -a "$REDIS_PASSOWRD" \
-h $node_ip -p $node_port \
CLUSTER SETSLOT $SLOT NODE $DEST_NODE_ID
  echo -e "\033[1;33m$err\033[m"
done

Original: https://www.cnblogs.com/aquester/p/13475797.html
Author: -见
Title: Redis的slot迁移工具

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/529094/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 壁纸爬取——协程应用

    (协程)壁纸爬取 一、 算法解析 1.1 进入爬取壁纸的网站(表层网页) 彼岸桌面壁纸-二次元 少爬涩图,健康生活! 1.2 获取显示单张壁纸的页面(深层网页)地址 选择网页元素:…

    Linux 2023年6月14日
    0177
  • 001.AD域控简介及使用

    一 AD概述 域(Domain)是Windows网络中独立运行的单位,域之间相互访问则需要建立信任关系。 当一个域与其他域建立了信任关系后,2个域之间不但可以按需要相互进行管理,还…

    Linux 2023年6月7日
    0134
  • C语言静态库与动态库

    库 是一种代码的二进制的封装形式,将.o文件打包封装就成了库。库可以在任何地方使用,但用户却不能看见他的具体实现。库有利于代码模块化,只要接口设计得合理,改变库的内部实现,不会影响…

    Linux 2023年6月7日
    091
  • 005 Linux 命令三剑客之-sed

    grep:数据查找定位 awk:数据切片,数据格式化,功能最复杂 *sed:数据修改 三剑客各有所长,就从锅碗瓢盆一一开始吧! [En] The three swordsmen h…

    Linux 2023年5月27日
    097
  • 阿里云OSS + PicGo搭建图床

    配置 PicGo 下载安装完成后,打开 PicGo,配置阿里云 OSS。 其中,KeyId 即创建 RAM 用户的 AccessKey ID,KeySecret 即 AccessK…

    Linux 2023年6月7日
    0130
  • windows环境安装VNC及远程连接linux(centos7)

    基础环境: 客户端:windows 10 服务器:centos7 软件:windows客户端安装 VNC-Viewer-6.21.1109-Windows.exe 下载地址:htt…

    Linux 2023年5月27日
    092
  • 面向对象编程三⼤特性 –封装、继承、多态

    作者:小牛呼噜噜 | https://xiaoniuhululu.com计算机内功、JAVA底层、面试相关资料等更多精彩文章在公众号「小牛呼噜噜 」 封装 继承 多态 一道简单的面…

    Linux 2023年6月6日
    0112
  • rsync

    rsync是什么 rsync特性 1)可以镜像保存整个目录树和文件系统。 2)可以很容易做到保持原来文件的权限、时间、软硬连接等。 3)无需特殊权限即可安装。 4)快速:第一次同步…

    Linux 2023年6月6日
    091
  • VMware 虚拟机图文安装和配置 Rocky Linux 8.5 教程

    前言这是《VMware 虚拟机图文安装和配置 AlmaLinux OS 8.6 教程》一文的姐妹篇教程,如果你需要阅读它,请点击这里。2020 年,CentOS 宣布:计划未来将重…

    Linux 2023年6月7日
    0225
  • 搭建部署Docker

    Docker安装准备: 首先看下服务器是否有旧版本,如果有需要卸载并且安装依赖 然后下载docker仓库repo源: 安装完成后查看docker仓库版本信息: yum安装docke…

    Linux 2023年6月8日
    0106
  • Redis基础

    1.简介 Redis (远程字典服务器)是一 个开源的、使用C语言编写的NoSQL数据库。Redis基于内存运行并支持持久化,采用 key-value (键值对)的存储形式,是目前…

    Linux 2023年6月13日
    083
  • lvs负载均衡

    Lvs 一.Lvs简介 二. 体系结构 三. Lvs管理工具 1. ipvs 2. ipvsadm 四.lvs工作模式及原理 1.NAT模式 2. DR模式 3.TUN模式(隧道模…

    Linux 2023年6月7日
    0126
  • Windows 10安装

    使用U盘安装操作系统教程 本教程介绍如何使用U盘安装操作系统,以安装Windows 10过程作为举例。 1 获取操作系统iso镜像文件 获取操作系统ISO镜像文件有很多途径,此处介…

    Linux 2023年6月13日
    094
  • 建表参数PCTFREE、PCTUSED、INITRANS和MAXTRANS释疑

    PCTFREE与PCTUSED建表时可以指定以上两个参数的值(整数),PCTFREE表示一个块中保留的剩余空间大小百分比,该保留空间主要用于已有记录的更 新操作;PCTUSED表示…

    Linux 2023年6月14日
    090
  • 每周一个linux命令(ping)

    基础环境 ping命令介绍 ping命令主要用来…

    Linux 2023年6月8日
    092
  • 【Python】【爬虫】【问题解决方案记录】调试输出存在数据,print在控制台确丢失数据

    调试输出存在数据,print在控制台确丢失数据 如下图,调试可以看到数据是完整的 但是print输出的,恰好丢失了中间的一大堆数据。对,下图打问号的地方应该是小说才对。 看代码可能…

    Linux 2023年6月14日
    070
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球