Chinaunix首页 | 论坛 | 博客
  • 博客访问: 7000249
  • 博文数量: 590
  • 博客积分: 13065
  • 博客等级: 上将
  • 技术积分: 10253
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-26 16:44
个人简介

推荐: blog.csdn.net/aquester https://github.com/eyjian https://www.cnblogs.com/aquester http://blog.chinaunix.net/uid/20682147.html

文章分类

全部博文(590)

分类: 系统运维

2020-08-11 15:19:50

工具下载:
https://github.com/eyjian/redis-tools/blob/master/move_redis_slot.sh
支持迁移已有的keys。

  1. #!/bin/sh
  2. # Writed by yijian on 2020/8/10
  3. # 迁移 slot 工具,但一次只能迁移一个 slot
  4. #
  5. # 使用时,需要指定如下几个参数:
  6. # 1)参数1:必选参数,用于指定被迁移的 slot
  7. # 2)参数2:必选参数,用于指定源节点(格式为:ip:port)
  8. # 3)参数3:必选参数,用于指定目标节点(格式为:ip:port)
  9. # 6)参数4:可选参数,用于指定访问 redis 的密码
  10. #
  11. # 使用示例(将2020从10.9.12.8:1383迁移到10.9.12.9:1386):
  12. # move_redis_slot.sh 2020 10.9.12.8:1383 10.9.12.9:1386
  13. #
  14. # 执行本脚本时,有两个“确认”,
  15. # 第一个“确认”是提示参数是否正确,
  16. # 第二个“确认”是提示是否迁移已有的keys,
  17. # 如果输入非yes则只迁移slot,不迁移已有keys。
  18. # 确保redis-cli可用
  19. REDIS_CLI=${REDIS_CLI:-redis-cli}
  20. which "$REDIS_CLI" > /dev/null 2>&1
  21. if test $? -ne 0; then
  22. echo "\`redis-cli\` not exists or not executable"
  23. exit 1
  24. fi
  25. # 参数检查
  26. if test $# -ne 3 -a $# -ne 4; then
  27. echo -e "Usage: `basename $0` \033[1;33mslot\033[m source_node destition_node redis_password"
  28. echo -e "Example1: `basename $0` \033[1;33m2020\033[m 127.0.0.1:6379 127.0.0.1:6380"
  29. echo -e "Example2: `basename $0` \033[1;33m2020\033[m 127.0.0.1:6379 127.0.0.1:6380 password123456"
  30. exit 1
  31. fi
  32. SLOT=$1
  33. SRC_NODE="$2"
  34. DEST_NODE="$3"
  35. REDIS_PASSOWRD="$4"
  36. # 得到指定节点的 nodeid
  37. function get_node_id()
  38. {
  39. node="$1"
  40. node_ip="`echo $node|cut -d':' -f1`"
  41. node_port=`echo $node|cut -d':' -f2`
  42. # 得到对应的 nodeid
  43. $REDIS_CLI --raw --no-auth-warning -a "$REDIS_PASSOWRD" \
  44. -h $node_ip -p $node_port \
  45. CLUSTER NODES | awk -v node=$node '{if ($2==node) printf("%s",$1);}'
  46. }
  47. SRC_NODE_ID="`get_node_id $SRC_NODE`"
  48. SRC_NODE_IP="`echo $SRC_NODE|cut -d':' -f1`"
  49. SRC_NODE_PORT=`echo $SRC_NODE|cut -d':' -f2`
  50. DEST_NODE_ID="`get_node_id $DEST_NODE`"
  51. DEST_NODE_IP="`echo $DEST_NODE|cut -d':' -f1`"
  52. DEST_NODE_PORT=`echo $DEST_NODE|cut -d':' -f2`
  53. echo -e "\033[1;33mSource\033[m node: $SRC_NODE_IP:$SRC_NODE_PORT"
  54. echo -e "\033[1;33mDestition\033[m node: $DEST_NODE_IP:$DEST_NODE_PORT"
  55. echo -en "Confirm to continue? [\033[1;33myes\033[m/\033[1;33mno\033[m]"
  56. read -r -p " " input
  57. if test "$input" != "yes"; then
  58. exit 1
  59. fi
  60. echo "........."
  61. # 目标节点上执行 IMPORTING 操作
  62. # 如果 $SLOT 已在目标节点,则执行时报错“ERR I'm already the owner of hash slot 1987”
  63. echo -e "\033[1;33mImporting\033[m $SLOT from $SRC_NODE to $DEST_NODE ..."
  64. err=`$REDIS_CLI --raw --no-auth-warning -a "$REDIS_PASSOWRD" \
  65. -h $DEST_NODE_IP -p $DEST_NODE_PORT \
  66. CLUSTER SETSLOT $SLOT IMPORTING $SRC_NODE_ID`
  67. if test "X$err" != "XOK"; then
  68. echo "[destition://$DEST_NODE_IP:$DEST_NODE_PORT] $err"
  69. exit 1
  70. fi
  71. # 源节点上执行 MIGRATING 操作
  72. # 如果 $SLOT 并不在源节点上,则执行时报错“ERR I'm not the owner of hash slot 1987”
  73. echo -e "\033[1;33mMigrating\033[m $SLOT from $SRC_NODE to $DEST_NODE ..."
  74. err=`$REDIS_CLI --raw --no-auth-warning -a "$REDIS_PASSOWRD" \
  75. -h $SRC_NODE_IP -p $SRC_NODE_PORT \
  76. CLUSTER SETSLOT $SLOT MIGRATING $DEST_NODE_ID`
  77. if test "X$err" != "XOK"; then
  78. echo "[source://$SRC_NODE_IP:$SRC_NODE_PORT] $err"
  79. exit 1
  80. fi
  81. # 是否迁移已有的keys?
  82. echo -en "Migrate keys in slot://$SLOT? [\033[1;33myes\033[m/\033[1;33mno\033[m]"
  83. read -r -p " " input
  84. if test "$input" = "yes"; then
  85. first=1 # 是否第一轮keys迁移操作
  86. batch=100 # 一次批量迁移的keys数
  87. timeout_ms=60000 # 超时时长(单位:毫秒)
  88. destination_db=0 # 对于redis集群,取值总是为0
  89. num_keys=0
  90. echo "........."
  91. echo -e "Migrating keys in slot://$SLOT ..."
  92. while true
  93. do
  94. # 在源节点上执行:
  95. # 借助命令“CLUSTER GETKEYSINSLOT”和命令“MIGRATE”迁移已有的keys
  96. keys="`$REDIS_CLI --raw --no-auth-warning -a '$REDIS_PASSOWRD' \
  97. -h $SRC_NODE_IP -p $SRC_NODE_PORT \
  98. CLUSTER GETKEYSINSLOT $SLOT $batch | tr '\n' ' ' | xargs`"
  99. if test -z "$keys"; then
  100. if test $first -eq 1; then
  101. echo -e "No any keys to migrate in slot://$SLOT"
  102. else
  103. echo -e "Finished migrating all keys ($num_keys) in slot://$SLOT"
  104. fi
  105. break
  106. fi
  107. first=0
  108. n=`echo "$keys" | tr -cd ' ' | wc -c`
  109. num_keys=$(($num_keys + $n))
  110. # 在源节点上执行命令“MIGRATE”迁移到目标节点
  111. # MIGRATE returns OK on success,
  112. # or NOKEY if no keys were found in the source instance
  113. if test -z "$REDIS_PASSOWRD"; then
  114. err=`$REDIS_CLI --raw \
  115. -h $SRC_NODE_IP -p $SRC_NODE_PORT \
  116. MIGRATE $DEST_NODE_IP $DEST_NODE_PORT "" $destination_db $timeout_ms \
  117. REPLACE KEYS $keys`
  118. else
  119. err=`$REDIS_CLI --raw --no-auth-warning -a "$REDIS_PASSOWRD" \
  120. -h $SRC_NODE_IP -p $SRC_NODE_PORT \
  121. MIGRATE $DEST_NODE_IP $DEST_NODE_PORT "" $destination_db $timeout_ms \
  122. REPLACE AUTH "$REDIS_PASSOWRD" KEYS $keys`
  123. fi
  124. if test "X$err" = "XNOKEY"; then
  125. break
  126. fi
  127. done
  128. fi
  129. # 取得所有 master 节点
  130. nodes=(`$REDIS_CLI --raw --no-auth-warning -a "$REDIS_PASSOWRD" -h $DEST_NODE_IP -p $DEST_NODE_PORT \
  131. CLUSTER NODES | awk '{if (match($3,"master")) printf("%s\n",$2);}'`)
  132. # 在所有 master 节点上执行 NODE 操作
  133. # 实际上,只可对源节点和目标节点执行 NODE 操作,
  134. # 新的配置会自动在集群中传播。
  135. echo "........."
  136. for node in ${nodes[*]}; do
  137. node_ip="`echo $node|cut -d':' -f1`"
  138. node_port=`echo $node|cut -d':' -f2`
  139. echo -en "NODE: $node_ip:$node_port "
  140. err=`$REDIS_CLI --raw --no-auth-warning -a "$REDIS_PASSOWRD" \
  141. -h $node_ip -p $node_port \
  142. CLUSTER SETSLOT $SLOT NODE $DEST_NODE_ID`
  143. echo -e "\033[1;33m$err\033[m"
  144. done

阅读(1758) | 评论(0) | 转发(0) |
0

上一篇:Redis的slot迁移

下一篇:Redis之延迟监控

给主人留下些什么吧!~~