redis迁移方案
本文主要为DBA提供Redis实例的几种迁移方案与操作指导。
- 参考:华为云-迁移方案概览
- 参考:华为云-使用Redis-port迁移自建rdb文件
- 参考:阿里云-通过Redis-shake将自建Redis迁移至阿里云
- 参考:阿里云-redis-shake数据同步&迁移工具
- 参考:阿里云-redis-full-check校验工具
[TOC]
使用 redis-port 迁移 Redis 上云(RDB文件)
场景:2021.11.02.模拟迁移redis从阿里云到华为云dcs
思路:利用 redis-port 迁移redis
源库IP:127.0.0.1:7001
目的IP:127.0.0.1:7002
源redis:准备测试数据
echo "set dba kevin" | /usr/local/bin/redis-cli -h 127.0.0.1 -a *** -c -p 7001 2>/dev/null
echo "set dev sam" | /usr/local/bin/redis-cli -h 127.0.0.1 -a *** -c -p 7001 2>/dev/null
echo "info keyspace" | /usr/local/bin/redis-cli -h 127.0.0.1 -a *** -c -p 7001 2>/dev/null
步骤1:安装redis-port
cd /opt/
wget -c http://iso.sqlfans.cn/redis/redis-port-v2.0-beta-go1.10.1-linux.zip
unzip redis-port-v2.0-beta-go1.10.1-linux.zip
chmod +x /opt/redis-port/redis*
步骤2:导出RDB文件
/opt/redis-port/redis-dump -n 3 -m ***@127.0.0.1:7001 -o /data/ali_1.rdb
/usr/local/bin/redis-cli -h 127.0.0.1 -p 7001 -a *** --rdb /data/ali_2.rdb
注:参数-n表示多个CPU并行处理导出任务;参数-m表示密码,不支持某些特殊字符;华为云dcs的Redis 4.0/5.0不支持sync,不能使用redis-dump导出为RDB文件,只能在控制台下载rdb文件。
步骤3:清空目标redis实例所有数据,
echo "flushall" | /usr/local/bin/redis-cli -h 127.0.0.1 -a *** -c -p 7002 2>/dev/null
echo "info keyspace" | /usr/local/bin/redis-cli -h 127.0.0.1 -a *** -c -p 7002 2>/dev/null
注:务必禁用flushall、flushdb等高危命令,这里为了方便而临时开放目的实例的flushall
步骤4:导入rdb文件到目标redis
/opt/redis-port/redis-restore -i /data/ali_1.rdb -t ***@127.0.0.1:7002
亲测:利用redis-port-v2.0-beta向redis 6.2.5导入5.0.9或6.2.5版本的rdb(rdb开头:REDIS0009dis-ver6.2.5)会报错“loader.go:50: [PANIC] Can't handle RDB format version = 9”,而向redis 6.2.5导入4.0.11版本的rdb(rdb开头:REDIS0008dis-ver4.0.11)则正常。猜测 redis-port 不支持Redis 5.0+
补充:redis-restore 工具支持将 Redis 的备份文件(RDB)导入到指定 Redis 实例,同时也支持导入 AOF 文件,支持 Redis 2.8、3.0、3.2、4.0 版本的 RDB 文件格式。
步骤5:执行 info keyspace 验证一下
echo "info keyspace" | /usr/local/bin/redis-cli -h 127.0.0.1 -a *** -c -p 7002 2>/dev/null
使用 redis-shake 实时迁移 Redis 上云(推荐)
redis-shake是阿里云Redis&MongoDB团队开源的用于redis数据同步的工具,它是基于redis-port基础上进行改进的一款产品。它的基本原理就是模拟一个从节点加入源redis集群,首先进行全量拉取并回放,然后进行增量的拉取(通过psync命令)。如下图所示:
功能介绍:
- 支持:支持云下到云上,云上到云上,云上到云下,其他云到阿里云等链路
- 监控:通过restful拉取metric来对redis-shake进行实时监控:curl 127.0.0.1:9320/metric
步骤1:安装redis-shake
cd /opt/
wget -c http://iso.sqlfans.cn/redis/redis-shake-v2.1.1-20210903.tar.gz
tar xvf redis-shake-v2.1.1-20210903.tar.gz
chmod +x /opt/redis-shake/redis-shake.linux
步骤2:修改配置文件
cp /opt/redis-shake/redis-shake.conf /opt/redis-shake/redis-shake.conf.$(date +%Y%m%d%H%M%S)
sed -i '/^pid_path =/c pid_path = /tmp' /opt/redis-shake/redis-shake.conf
sed -i '/^http_profile =/c http_profile = 9320' /opt/redis-shake/redis-shake.conf
sed -i '/^source.type =/c source.type = standalone' /opt/redis-shake/redis-shake.conf
sed -i '/^source.address =/c source.address = 127.0.0.1:7001' /opt/redis-shake/redis-shake.conf
sed -i '/^source.password_raw =/c source.password_raw = ***' /opt/redis-shake/redis-shake.conf
sed -i '/^source.auth_type =/c source.auth_type = auth' /opt/redis-shake/redis-shake.conf
sed -i '/^target.type =/c target.type = standalone' /opt/redis-shake/redis-shake.conf
sed -i '/^target.address =/c target.address = 127.0.0.1:7002' /opt/redis-shake/redis-shake.conf
sed -i '/^target.password_raw =/c target.password_raw = ***' /opt/redis-shake/redis-shake.conf
sed -i '/^resume_from_break_point =/c resume_from_break_point = true' /opt/redis-shake/redis-shake.conf
cat /opt/redis-shake/redis-shake.conf | grep -n ^[^#]
步骤3:清空目标redis实例所有数据
echo "flushall" | /usr/local/bin/redis-cli -h 127.0.0.1 -a *** -c -p 7002 2>/dev/null
echo "info keyspace" | /usr/local/bin/redis-cli -h 127.0.0.1 -a *** -c -p 7002 2>/dev/null
亲测:若目标实例已有部分数据则步骤4启动失败,报错“[PANIC] target key name is busy: dev4”,所以迁移之前建议清空一下目标实例。
步骤4:启动 redis-shake 执行数据迁移
/opt/redis-shake/redis-shake.linux -type=sync -conf=/opt/redis-shake/redis-shake.conf
步骤5:实时监控迁移过程
curl 127.0.0.1:9320/metric
步骤6:观察打印的日志,等待返回日志中writeBytes对应值连续多次为0时,使用Ctrl+C结束数据迁移任务
亲测:利用redis-shake向redis 6.2.5实时迁移6.2.5版本测试ok。在迁移过程中,目标实例新写入的其他数据不会被覆盖。
步骤7:执行 info keyspace 验证一下
echo "info keyspace" | /usr/local/bin/redis-cli -h 127.0.0.1 -a *** -c -p 7002 2>/dev/null
使用 redis-cli 迁移自建 Redis(AOF文件)
思路:利用 AOF 迁移自建 redis
源库IP:127.0.0.1:7001
目的IP:127.0.0.1:7002
步骤1:生成AOF文件
/usr/local/bin/redis-cli -h 127.0.0.1 -p 7001 -a *** config set appendonly yes
/usr/local/bin/redis-cli -h 127.0.0.1 -p 7001 -a *** config get dir
- 开启持久化之后,如果AOF文件大小不再变化,说明AOF文件为全量缓存数据
- 输入命令 config get dir 查看AOF文件保存路径,文件名如果没有特殊指定则默认为 appendonly.aof
- 生成AOF文件后如需关闭同步,可输入命令 config set appendonly no 进行关闭
步骤2:根据步骤1的输出,确认aof文件
more /data/redis_7001/dump/appendonly.aof
步骤3:清空目标redis实例所有数据
echo "flushall" | /usr/local/bin/redis-cli -h 127.0.0.1 -a *** -c -p 7002 2>/dev/null
echo "info keyspace" | /usr/local/bin/redis-cli -h 127.0.0.1 -a *** -c -p 7002 2>/dev/null
注:务必禁用flushall、flushdb等高危命令,这里为了方便而临时开放目的实例的flushall
步骤4:导入aof文件到目标redis
/usr/local/bin/redis-cli -h 127.0.0.1 -p 7002 -a *** --pipe < /data/redis_7001/dump/appendonly.aof
亲测:向redis 6.2.5导入6.2.5版本的aof,测试ok。
关于aof导出和导入的效率
- AOF文件的生成较快,适用于可以进入Redis服务器并修改配置的场景,如ecs自建的Redis服务。
- VPC内进行导入,平均100w数据(每条数据20字节),大概4~10秒完成。
通过重启进程来迁移自建 Redis(RDB文件)
场景:2021.08.05.不知道账号密码及备份的情况下迁移自建redis
思路:把dump.rdb放到启动redis的目录下,重启redis即可恢复数据
步骤1:[老实例] 搜索redis及端口和密码
find / -name redis-cli
netstat -lnpt | grep redis
cat /usr/local/redis-4.0.6/redis.conf | grep pass
步骤2:[老实例] 获取redis备份目录(yum安装的是在/var/lib/redis目录下面)
echo "save" | /usr/local/bin/redis-cli -h 127.0.0.1 -a *** -c -p 6397 2>/dev/null
echo "config get dir" | /usr/local/bin/redis-cli -h 127.0.0.1 -a *** -c -p 6397 2>/dev/null
步骤3:[老实例] 搜索rdb文件所在
find / -name redis.conf
cat /usr/local/redis-4.0.6/redis.conf | egrep "(dbfilename|dir)"
find / -name dump.rdb
步骤4:[老实例] 通过第2步的save甄别哪个是真的备份,并拷贝到新机器(示例 192.168.4.199)
scp -r -P22 /var/app/dump.rdb it_support@192.168.4.199:/home/it_support/
步骤5:[新机器] 执行save确定dump.rdb位置,用老实例的rdb文件覆盖,并重启redis
echo "save" | /usr/local/bin/redis-cli -h 127.0.0.1 -a *** -c -p 6397 2>/dev/null
echo "shutdown" | /usr/local/bin/redis-cli -h 127.0.0.1 -a *** -c -p 6397 2>/dev/null
/usr/local/bin/redis-server /etc/redis/redis.conf
步骤6:[新机器] 确认数据
echo "keys *" | /usr/local/bin/redis-cli -h 127.0.0.1 -a *** -c -p 6397 2>/dev/null
redis-full-check校验工具
redis-full-check是阿里云Redis&MongoDB团队开源的用于校验2个redis数据是否一致的工具,通常用于redis数据迁移(redis-shake)后正确性的校验。
支持:单节点、主从版、集群版、带proxy的云上集群版(阿里云)之间的同构或者异构对比,版本支持2.x-5.x。
步骤1:安装redis-full-check
cd /opt/
wget -c http://iso.sqlfans.cn/redis/redis-full-check-1.4.8.zip
unzip redis-full-check-1.4.8.zip
chmod +x /opt/redis-full-check
步骤2:启动对比任务
/opt/redis-full-check --comparetimes=1 -s 127.0.0.1:7001 -p *** -t 127.0.0.1:7002 -a *** --log=/tmp/redis-check.log --db=/tmp/redis-result.db
注:参数-p表示源redis库密码,参数-a表示目的redis库密码,参数--comparetimes表示比较轮数
步骤3:确认对比结果
- 对比结果会保存在sqlite3 db file中,不指定的话,就是当前目录的 result.db 文件:比如有3轮比较,那么会有result.db.1,result.db.2,result.db.33个文件。
cat /tmp/redis-check.log echo "select * from key;" | sqlite3 /tmp/redis-result.db.1 echo "select * from field;" | sqlite3 /tmp/redis-result.db.1
注:比对一致的话,check.log最后一行应该是:all finish successfully, totally 0 key(s) and 0 field(s) conflict