redis集群间迁移的数据方式有很多,假如现在只是想把部分数据从A集群迁移到B集群有什么好办法?
当然方法也有很多啦,不过有没有很廉价、很便捷、高度复用的方法?当然有啦。那就是bash这个利器。
我抽空写了一个,支持从两个集群间搬迁,有以下特点:
1、自动识别类型,不用写策略模式了
2、scan扫描,规避集群block风险
3、自动forward到正确的分片
4、自定义key,支持部分搬迁也支持整体搬迁
不足就是速度稍微慢一些,毕竟由client频繁的建立并释放连接。
#!/bin/bash##################################################################### @Author: xianshuangzhang ##### @Date: 2020-08-06 12:24:48 ##### usage: sh redis.sh ##### any questions,please mail to:xianshuangzhang@gmail.com ###################################################################please set the keys prefix which to be movedkeys="fortune* *many_more_keys*"#the original redis cluster connection infosrc_cluster_nodes="10.141.17.68:6379 10.141.17.68:6389 10.141.17.68:6399"src_cluster_passwd="redisclusternew"#the destination redis cluster connection infodest_cluster_nodes="10.141.19.36:6379 10.141.19.36:6389 10.141.19.36:6399 10.141.19.36:7379 10.141.19.36:7389 10.141.19.36:7399"dest_cluster_passwd="perftest"global_node_info=#to find the destination redis node,accroding the moved instructionsfunction destClusterNode(){all_nodes=(${dest_cluster_nodes})node_info=($(echo ${all_nodes[0]}|awk -F ":" '{print $1,$2}'))response=$(redis-cli -h ${node_info[0]} -p ${node_info[1]} -a $dest_cluster_passwd --no-auth-warning exists "$1"|awk '{print $0}')if [[ "$response" == "0" ]]thenecho "dest node found :["${all_nodes[0]}"],key:["$1"]"global_node_info=${all_nodes[0]}elif [[ "$response" == "1" ]]thenglobal_node_info="skip"echo "dest key first key exists skipped:["$1"]"elif [[ ${#response} -gt 6 && ${response:0:5} == "MOVED" ]]thenglobal_node_info=`echo $response|awk '{print $3}'`echo "dest node founded!["$global_node_info"]"elseglobal_node_info=${all_nodes[0]}fi}#using scan command to find all of the keys,avoid redis connection blockingfunction funScanKeys(){redis-cli -h "$1" -p "$2" -a $3 --no-auth-warning SCAN $4 match "$5" count 100 |while read keym_host=$1m_port=$2doglobal_node_info="skip"if [[ -z $key ]]thenbreakfiisnumber=`echo "$key" |sed 's/\.//g'|sed 's/-//g' | grep [^0-9] >/dev/null`if [[ -z "$key" || -z $(echo $key|sed 's/\.//g'|sed 's/-//g' | grep [^0-9]) ]]thenecho 1 >/dev/nullelseresp_redis=$(redis-cli -h "$1" -p "$2" -a $3 --no-auth-warning --raw dump "$key"|awk '{print $0}')if [[ ${#resp_redis} -gt 6 && ${resp_redis:0:5} == "MOVED" ]]then#find the src node info,when movedmoved_host_port=($(echo $resp_redis|awk -F "[ :]" '{print $3,$4}'))m_host=${moved_host_port[0]}m_port=${moved_host_port[1]}echo "src node found:"$m_host":"$m_portfidestClusterNode $keyif [[ $global_node_info != "skip" && ! -z $global_node_info ]]thendest_node_info=($(echo $global_node_info|awk -F ":" '{print $1,$2}'))double_check_resp=$(redis-cli -h ${dest_node_info[0]} -p ${dest_node_info[1]} --no-auth-warning -a $dest_cluster_passwd exists "$key")if [[ "$double_check_resp" == "0" ]]thentrans_resp=$(redis-cli -h $m_host -p $m_port -a $src_cluster_passwd --no-auth-warning --raw dump "$key" | perl -pe 'chomp if eof' | redis-cli -h ${dest_node_info[0]} -p ${dest_node_info[1]} --no-auth-warning -a $dest_cluster_passwd -x restore "$key" 0)echo "transf:"$trans_resp",from:"$m_host":"$m_port",to:"${dest_node_info[0]}":"${dest_node_info[1]}",key:["$key"]"elseecho "key double check exists,skipped:["$key"]"fififidone}function funKeyHandler(){for node in ${src_cluster_nodes}doport=${node#*:}host=${node%%:*}ended="false"start_index=0funScanKeys ${host} $port $src_cluster_passwd ${start_index} $1while [[ $ended == "false" ]]doline_text=`redis-cli -h "${host}" -p "$port" --no-auth-warning -a $src_cluster_passwd SCAN ${start_index} match "$1" count 100 |awk '{if($1!=""){print $1}}'`start_index=`echo $line_text|awk '{print $1}'`if [[ -z "$start_index" || "$start_index" -eq "0" ]]thenended="true"elsefunScanKeys ${host} $port $src_cluster_passwd ${start_index} $1fidonedone}function begin(){for key in $keysdofunKeyHandler $keydone}#the main methodbegin

文章转载自技术万花筒,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




