merge_redis.sh 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. #!/bin/bash
  2. # 定义迁移函数
  3. migrate_db() {
  4. local src_db=$1
  5. local dst_db=$2
  6. local cursor=0
  7. local batch_size=500 # 根据实际情况调整批次大小
  8. while true; do
  9. # 使用SCAN分批次获取键(带超时设置)
  10. result=$(timeout 30 redis-cli -n "$src_db" SCAN "$cursor" MATCH "*" COUNT "$batch_size")
  11. cursor=$(echo "$result" | head -n 1)
  12. keys=$(echo "$result" | tail -n +2)
  13. [ -z "$keys" ] && break
  14. # 使用管道处理减少子进程调用
  15. {
  16. echo "$keys" | while read -r key; do
  17. # 键名替换
  18. new_key=$(echo "$key" | sed "s/account_${src_db}_/account_${dst_db}_/g")
  19. # 使用管道处理不同类型的数据
  20. type=$(redis-cli -n "$src_db" TYPE "$key" | tr -d '\r')
  21. case "$type" in
  22. string)
  23. redis-cli -n "$src_db" GET "$key" | xargs -I{} redis-cli -n "$dst_db" SET "$new_key" "{}"
  24. ;;
  25. hash)
  26. 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"
  27. ;;
  28. list)
  29. redis-cli -n "$src_db" LRANGE "$key" 0 -1 | xargs -I{} redis-cli -n "$dst_db" RPUSH "$new_key" "{}"
  30. ;;
  31. set)
  32. redis-cli -n "$src_db" SMEMBERS "$key" | xargs -I{} redis-cli -n "$dst_db" SADD "$new_key" "{}"
  33. ;;
  34. zset)
  35. 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"
  36. ;;
  37. *)
  38. echo "Unsupported type: $type for key: $key"
  39. ;;
  40. esac
  41. done
  42. } | parallel -j 8 # 使用parallel并行处理每个批次
  43. done
  44. }
  45. # 控制并发迁移的任务数量
  46. max_concurrency=4
  47. semaphore=$(mktemp)
  48. for db in {1..30}; do
  49. (
  50. flock -x 200
  51. migrate_db "$db" "$db"
  52. ) 200>"$semaphore"
  53. done
  54. wait
  55. rm -f "$semaphore"
  56. echo "All databases migrated successfully!"