一、迁移工具安装
RedisShake有很多版本,本文介绍的是4.x版本的使用,不同的版本在设置和配置文件上略有不同,功能也有所不同。 拷贝命令:git clone https://github.com/tair-opensource/RedisShake.git
下载文件之后解压进入目录,执行 sh build.sh 进行编译。或者也可以直接下载编译好的文件,解压就可以使用 。
二、配置文件
配置文件在RedisShake文件夹的bin/shake.toml文件。主要需要修改数据源[sync_reader]
目标数据库[redis_writer],
如出现性能问题可以尝试调节管道命令最大数和缓存区大小。迁移中真正的速度受网络,cpu,磁盘等多方面因素影响,如遇到白名单或内网限制,可调整脚本运行的实际虚拟机灵活解决,在生产服务器运行脚本时,应限制cpu占用数,防止性能问题对生产环境造成影响。
#lua脚本内容
function = ""
# 数据源
[sync_reader]
cluster = false # 是否为集群模式
address = "127.0.0.1:6379" # 源redis的地址,ip:port
username = "" # 用户名(如果有)
password = "" # 密码(如果有)
tls = false # 源端是否开启 TLS/SSL
sync_rdb = true # 全量同步
sync_aof = true # 增量同步
# 通过 SCAN 命令遍历源端数据库中的所有 Key,并使用 DUMP 与 RESTORE 命令来读取与写入 Key 的内容。本方案为次选方案,当可以使用 sync_reader 时,请优选 sync_reader。
# [scan_reader]
# cluster = false # 源端是否为集群
# address = "127.0.0.1:6379" # 源端地址, 当源端为集群时,address 为集群中的任意一个节点即可
# username = "" # 用户名(如果有)
# password = "" # 密码(如果有)
# ksn = false # 开启 ksn 参数后 RedisShake 会在 SCAN 之前使用 Redis keyspace notifications 能力来订阅 Key 的变化。当 Key 发生变化时,RedisShake 会使用 DUMP 与 RESTORE 命令来从源端读取 Key 的内容,并写入目标端。
# tls = false # 源端是否开启 TLS/SSL
# dbs = [] # 源端为非集群模式时,支持指定DB库
# 可以使用 rdb_reader 来从 RDB 文件中读取数据,然后写入目标端。常见于从备份文件中恢复数据。
# [rdb_reader]
# filepath = "/tmp/dump.rdb" #绝对路径
# 可以使用 aof_reader 来从 AOF 文件中读取数据,然后写入目标端。常见于从备份文件中恢复数据,还支持数据闪回。
# [aof_reader]
# filepath = "/tmp/.aof" # 绝对路径
# timestamp = 0 # subsecond
# 目标数据库
[redis_writer]
cluster = false # 是否为集群
address = "127.0.0.1:6380"
username = "" # 用户名(如果有)
password = "" # 密码(如果有)
tls = false # 是否开启 TLS/SSL
[advanced]
dir = "data" #工作目录
ncpu = 0 # 可以占用的cpu数,0为占用默认系统提供数
pprof_port = 0 # pprof监控端口
status_port = 0 # status监控端口
# log
log_file = "shake.log"
log_level = "info" # log级别,可为debug
log_interval = 5 # 日志输出时间间隔
# 当遇到目标库键正忙时可以配置这个选项,默认为停止
# panic: 当遇到“目标密钥名称正忙”错误时,redis-shake将停止。
# rewrite: redis-shake将用新值替换键。
# ignore: redis-shake在遇到“目标密钥名称繁忙”错误时会跳过还原密钥。
rdb_restore_command_behavior = "ignore" # panic, rewrite or skip
# redis-shake 使用管道来提高发送性能。
# 此项限制管道中命令的最大数量。
pipeline_count_limit = 1024
# 缓冲区大小配置,此为1g
target_redis_client_max_querybuf_len = 1024_000_000
# 单个字符串被限制为 512 mb.
target_redis_proto_max_bulk_len = 512_000_000
# 如果源是Elasticache或MemoryDB,则可以设置此项
aws_psync = ""
# 示例: aws_psync = "10.0.0.1:6379@nmfu2sl5osync,10.0.0.1:6379@xhma21xfkssync"
[module]
# 出现数据不兼容时可设置此项
target_mbbloom_version = 20603
启动命令:./redis-shake shake.toml
注意两个Redis的版本最好相同,否则可能会因为新的特性或者新的编码方式出现不兼容问题。迁移方式分为两种,一种是Sync模式,原理是把目标数据库模拟为数据源的从节点进行数据迁移,迁移分为全量迁移和增量迁移两个阶段,增量迁移为迁移所有数据,增量迁移为在迁移期间,数据源发生的数据修改同步到目标数据库。还有一种是Scan模式,使用scan便利数据库中的所有键,在使用dump和restore来读取和写入键的内容。
注意:如果是阿里云redis,需要使用有复制权限的账号来操作
三、数据清洗
数据清洗可以实现把数据源0库的键迁移到目标数据库的1库,或只迁移指定的键,或只迁移指定的库。但是在迁移时,如果是用的是Sync模式,默认都会扫描所有库,所以如果数据量巨大需要一定的时间才会扫描到需要进行迁移的库。这个过程由lua脚本来实现。
从0库迁移到1库:
if DB ~= 0 then
return
end
shake.call(1, ARGV)
从7库迁移到8库同时过滤test字段:
local prefix = "test"
local prefix_len = #prefix
if DB ~= 7 then
return
else if string.sub(KEYS[1], 1, prefix_len) ~= prefix then
return
end
end
shake.call(8, ARGV)
丢弃源端 db
0 的数据,将其他 db
的数据写入到目标端:
shake.log(DB)
if DB == 0
then
return
end
shake.call(DB, ARGV)
修改 Key 的前缀:把 test1 修改为 test2:
local prefix_old = "test1"
local prefix_new = "test2"
shake.log("old=" .. table.concat(ARGV, " "))
for i, index in ipairs(KEY_INDEXES) do
local key = ARGV[index]
if string.sub(key, 1, #prefix_old) == prefix_old then
ARGV[index] = prefix_new .. string.sub(key, #prefix_old + 1)
end
end
shake.log("new=" .. table.concat(ARGV, " "))
shake.call(DB, ARGV)
在lua脚本中还有很多变量可以使用,可以根据自己的需求对数据进行清洗,下面是官方文档的一张表。可以使用的函数有shake.log 和 shake.call
shake.call(DB, ARGV):返回一个 Redis 命令,RedisShake 会将该命令写入目标端。
shake.log(msg):打印日志。
越复杂的lua脚本一定是代表更大的cpu开销,对数据的清洗工作是在本地进行的,如果在部署了redis的服务器上进行数据清洗一定要注意资源的开销,防止对redis造成性能影响。
最后补充一下配置文件中的lua脚本格式要求,如图所示:
官方中文文档:https://tair-opensource.github.io/RedisShake/
官方仓库地址:https://github.com/tair-opensource/RedisShake?tab=readme-ov-file
3.x版本仓库地址:https://github.com/tair-opensource/RedisShake/tree/v3
2.x版本仓库地址:https://github.com/tair-opensource/RedisShake/tree/v2