| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465 |
- #!/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!"
|