|
|
@@ -0,0 +1,65 @@
|
|
|
+#!/bin/bash
|
|
|
+
|
|
|
+# 定义迁移函数
|
|
|
+migrate_db() {
|
|
|
+ local src_db=$1
|
|
|
+ local dst_db=$2
|
|
|
+ local cursor=0
|
|
|
+ local batch_size=500 # 根据实际情况调整批次大小
|
|
|
+
|
|
|
+ while true; do
|
|
|
+ # 使用SCAN分批次获取键(带超时设置)
|
|
|
+ result=$(timeout 30 redis-cli -n "$src_db" SCAN "$cursor" MATCH "*" COUNT "$batch_size")
|
|
|
+ cursor=$(echo "$result" | head -n 1)
|
|
|
+ keys=$(echo "$result" | tail -n +2)
|
|
|
+
|
|
|
+ [ -z "$keys" ] && break
|
|
|
+
|
|
|
+ # 使用管道处理减少子进程调用
|
|
|
+ {
|
|
|
+ echo "$keys" | while read -r key; do
|
|
|
+ # 键名替换
|
|
|
+ new_key=$(echo "$key" | sed "s/account_${src_db}_/account_${dst_db}_/g")
|
|
|
+
|
|
|
+ # 使用管道处理不同类型的数据
|
|
|
+ type=$(redis-cli -n "$src_db" TYPE "$key" | tr -d '\r')
|
|
|
+
|
|
|
+ case "$type" in
|
|
|
+ string)
|
|
|
+ redis-cli -n "$src_db" GET "$key" | xargs -I{} redis-cli -n "$dst_db" SET "$new_key" "{}"
|
|
|
+ ;;
|
|
|
+ hash)
|
|
|
+ redis-cli -n "$src_db" HGETALL "$key" | awk 'NR%2==1 {k=$0} NR%2==0 {print k, $0}' | xargs -L 2 redis-cli -n "$dst_db" HMSET "$new_key"
|
|
|
+ ;;
|
|
|
+ list)
|
|
|
+ redis-cli -n "$src_db" LRANGE "$key" 0 -1 | xargs -I{} redis-cli -n "$dst_db" RPUSH "$new_key" "{}"
|
|
|
+ ;;
|
|
|
+ set)
|
|
|
+ redis-cli -n "$src_db" SMEMBERS "$key" | xargs -I{} redis-cli -n "$dst_db" SADD "$new_key" "{}"
|
|
|
+ ;;
|
|
|
+ zset)
|
|
|
+ redis-cli -n "$src_db" ZRANGE "$key" 0 -1 WITHSCORES | awk '{if(NR>1) print $1, $2}' | xargs -L 2 redis-cli -n "$dst_db" ZADD "$new_key"
|
|
|
+ ;;
|
|
|
+ *)
|
|
|
+ echo "Unsupported type: $type for key: $key"
|
|
|
+ ;;
|
|
|
+ esac
|
|
|
+ done
|
|
|
+ } | parallel -j 8 # 使用parallel并行处理每个批次
|
|
|
+ done
|
|
|
+}
|
|
|
+
|
|
|
+# 控制并发迁移的任务数量
|
|
|
+max_concurrency=4
|
|
|
+semaphore=$(mktemp)
|
|
|
+
|
|
|
+for db in {1..30}; do
|
|
|
+ (
|
|
|
+ flock -x 200
|
|
|
+ migrate_db "$db" "$db"
|
|
|
+ ) 200>"$semaphore"
|
|
|
+done
|
|
|
+
|
|
|
+wait
|
|
|
+rm -f "$semaphore"
|
|
|
+echo "All databases migrated successfully!"
|