zoukankan      html  css  js  c++  java
  • 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` 33[1;33mslot33[m source_node destition_node redis_password"
      echo -e "Example1: `basename $0` 33[1;33m202033[m 127.0.0.1:6379 127.0.0.1:6380"
      echo -e "Example2: `basename $0` 33[1;33m202033[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 "33[1;33mSource33[m node: $SRC_NODE_IP:$SRC_NODE_PORT($SRC_NODE_ID)"
    echo -e "33[1;33mDestition33[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 33[1;33m$SRC_NODE33[m"
      exit 1
    fi
    if test -z "$DEST_NODE_ID"; then
      echo -e "Can not get the destition node ID of 33[1;33m$DEST_NODE33[m"
      exit 1
    fi
    
    echo -en "Confirm to continue? [33[1;33myes33[m/33[1;33mno33[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 "33[1;33mImporting33[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 "33[1;33mMigrating33[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? [33[1;33myes33[m/33[1;33mno33[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 '
    ' ' ' | 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 (33[1;33m$num_keys33[m) in slot://$SLOT"
          fi
          break
        fi
        first=0
        n=`echo "$keys" | tr -cd ' ' | wc -c`
        num_keys=$(($num_keys + $n))
        #echo -e "(33[1;33m$n33[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 "33[1;33m$n33[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
    ",$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 "33[1;33m$err33[m"
    done
  • 相关阅读:
    互斥量
    读写锁
    死锁
    pthread
    线程
    守护进程
    信号捕捉
    信号集
    信号
    mmap
  • 原文地址:https://www.cnblogs.com/aquester/p/13475797.html
Copyright © 2011-2022 走看看