迁移类型:阿里云云数据库redis间的迁移
需求:多台redis迁移到1台
问题:直接使用阿里云DMS(DTS)创建迁移任务,迁移1台(数据在DB1)后再建任务迁移另一台(数据也在DB1)提示“目标库中的表不为空”
解决思路:
a.阿里云这边提工单咨询,结论是没办法通过阿里云实现类似:源DB1→目标DB2的方式,但是可以“确认屏蔽”上图警告,意思是评估考虑是否需要跳过该检查项。
提醒:选择为忽略报错并继续执行后,如果在迁移过程中遇到目标端的Key与源端中的Key相同,会将源端的数据覆盖写入目标端中,从而可能会导致目标端原有的数据丢失,请谨慎选择。
b.结合业务评估后,还是先在源redis上move数据后再通过阿里云迁移吧,需要与开发沟通结合业务重新配置数据所在DB。
redis基础:
参考:
https://blog.csdn.net/I_r_o_n_M_a_n/article/details/124637203 Reids 基础 — Redis数据库通用命令
[root@localhost ~]# redis-cli # 连接本地redis 127.0.0.1:6379> select 1 # 切换至指定的数据库 OK 127.0.0.1:6379[1]> keys * # 获取所有与给定匹配符相匹配的键,支持匹配符 1) "1 1" 127.0.0.1:6379[1]> SET Key0 Value0 # 创建数据 OK 127.0.0.1:6379[1]> SET Key1 Value1 OK 127.0.0.1:6379[1]> KEYS * 1) "Key0" 2) "1 1" 3) "Key1" 127.0.0.1:6379[1]> KEYS key0 (empty list or set) 127.0.0.1:6379[1]> KEYS Key0 1) "Key0" 127.0.0.1:6379[1]> help SCAN # 以渐进方式迭代数据库中的键 # 因为KEYS命令需要检查数据库包含的所有键,并一次性将符合条件的所有键全部返回给客户端,所以当数据库包含的键数量比较大时,使用KEYS命令可能会导致服务器被阻塞。 为了解决这个问题,Redis从2.8.0版本开始提供SCAN命令,该命令是一个迭代器,它每次被调用的时候都会从数据库中获取一部分键,用户可以通过重复调用SCAN命令来迭代数据库包含的所有键。 SCAN cursor [MATCH pattern] [COUNT count] summary: Incrementally iterate the keys space since: 2.8.0 group: generic 127.0.0.1:6379[1]> MOVE Key0 2 # 将指定的键移动到另一个数据库 (integer) 1 # 返回1表示成功 127.0.0.1:6379[1]> select 2 OK 127.0.0.1:6379[2]> KEYS * 1) "Key0" 127.0.0.1:6379[2]>
redis-cli基础:
参考:
https://www.cnblogs.com/xiao-xue-di/p/17264983.html redis-cli 命令详解https://www.cnblogs.com/EikiXu/p/9428855.html Redis进阶实践之十四 Redis-cli命令行工具使用详解https://redis.io/docs/manual/patterns/bulk-loading/ Bulk loading using the Redis protocolhttps://www.dbs724.com/336162.html redis查看key总数https://blog.51cto.com/u_16099246/6680255 批处理打开多个redis redis批量操作https://zhuanlan.zhihu.com/p/552975488?utm_id=0 redis安装与客户端redis-cli的使用(批量操作)
[root@localhost ~]# redis-cli -h redis地址 -a '账号密码' info keyspace # -h -a 远程连接redis、info查看Redis服务器的各种信息 Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe. # Keyspace db1:keys=1123075,expires=1123075,avg_ttl=13054711964 db11:keys=10113,expires=9909,avg_ttl=126542238 db22:keys=3372,expires=2873,avg_ttl=1264542475 db31:keys=148,expires=1,avg_ttl=3234822 [root@localhost ~]# redis-cli -n 2 keys "Key*" # 指定数据库 1) "Key1" 2) "Key0" [root@localhost ~]# [root@localhost ~]# redis-cli -n 2 --no-raw keys "K*"|grep -o '".*"'|awk '{print "move",$0,"1"}' >data.txt [root@localhost ~]# cat data.txt move "Key0" 1 move "Key1" 1 [root@localhost ~]# cat data.txt |redis-cli -n 2 --pipe # 批量操作,加上官方的--pipe后居然不行 All data transferred. Waiting for the last reply... ERR unknown command 'ove' ERR unknown command '2' ERR unknown command '$4' ERR wrong number of arguments for 'echo' command ERR unknown command '$20' ERR Protocol error: unbalanced quotes in request ^C [root@localhost ~]# cat data.txt |redis-cli -n 2 # 使用管道符执行批量操作 (integer) 1 (integer) 1 [root@localhost ~]# redis-cli -n 1 keys "K*" 1) "Key1" 2) "Key0" [root@localhost ~]# [root@localhost ~]# redis-cli -n 2 keys "1 1" # 一般的key可以用下一条命令移动 1) "1 1" [root@localhost ~]# redis-cli -n 2 keys "1 1"|xargs -i redis-cli -n 2 move {} 1 (integer) 1 [root@localhost ~]# [root@localhost ~]# redis-cli -n 2 keys "ho*" # 特殊key同样的命令不行,看起来是因为通过管道后原来的key是一行被当做多行了 1) "horizon:snapshot:job:horizon:job:Closure ( \xe9\x94\x80\xe5\x94\xae\xe5\xbc\x80\xe5\x8d\x95\xe6\x88\x96\xe5\xb7\xb2\xe6\x94\xaf\xe4\xbb\x98\xef\xbc\x8c\xe8\xb5\xb0\xe6\x99\xae\xe9\x80\x9a\xe8\xae\xa2\xe5\x8d\x95\xe6\x94\xb6\xe8\xb4\xa7\xe9\x80\xbb\xe8\xbe\x91\xef\xbc\x88\xe5\x8c\x85\xe6\x8b\xac\xe5\x90\x88\xe7\xba\xa6\xe5\xae\xa2\xe6\x88\xb7\xef\xbc\x89\n (new \\App\\Services\\Trade\\Order\\CompleteService())->receiveDelivery($order['order_no'], $order['user_id'], $order['shop_id'], [], $order['buyer_shop_id'], $opUserId);\n });\n }:14)" [root@localhost ~]# redis-cli -n 2 keys "ho*"|xargs -i redis-cli -n 2 move {} 1 (integer) 0 (integer) 0 (integer) 0 (integer) 0 [root@localhost ~]# # 使用下一条命令移动成功,实质类似cat data.txt |redis-cli -n 2 # 使用管道符执行批量操作 [root@localhost ~]# redis-cli -n 2 --no-raw keys "ho*"|grep -o '".*"'|awk '{print "move",$0,"1"}' |redis-cli -n 2 (integer) 1 [root@localhost ~]# redis-cli -n 2 keys "ho*" (empty list or set) [root@localhost ~]# redis-cli -n 1 --no-raw keys "ho*"|grep -o '".*"'|awk '{print "move",$0,"2"}' move "horizon:snapshot:job:horizon:job:Closure ( \xe9\x94\x80\xe5\x94\xae\xe5\xbc\x80\xe5\x8d\x95\xe6\x88\x96\xe5\xb7\xb2\xe6\x94\xaf\xe4\xbb\x98\xef\xbc\x8c\xe8\xb5\xb0\xe6\x99\xae\xe9\x80\x9a\xe8\xae\xa2\xe5\x8d\x95\xe6\x94\xb6\xe8\xb4\xa7\xe9\x80\xbb\xe8\xbe\x91\xef\xbc\x88\xe5\x8c\x85\xe6\x8b\xac\xe5\x90\x88\xe7\xba\xa6\xe5\xae\xa2\xe6\x88\xb7\xef\xbc\x89\n (new \\App\\Services\\Trade\\Order\\CompleteService())->receiveDelivery($order['order_no'], $order['user_id'], $order['shop_id'], [], $order['buyer_shop_id'], $opUserId);\n });\n }:14)" 2 [root@localhost ~]# [root@localhost ~]# redis-cli -n 1 --no-raw keys "ho*"|grep -o '".*"' "horizon:snapshot:job:horizon:job:Closure ( \xe9\x94\x80\xe5\x94\xae\xe5\xbc\x80\xe5\x8d\x95\xe6\x88\x96\xe5\xb7\xb2\xe6\x94\xaf\xe4\xbb\x98\xef\xbc\x8c\xe8\xb5\xb0\xe6\x99\xae\xe9\x80\x9a\xe8\xae\xa2\xe5\x8d\x95\xe6\x94\xb6\xe8\xb4\xa7\xe9\x80\xbb\xe8\xbe\x91\xef\xbc\x88\xe5\x8c\x85\xe6\x8b\xac\xe5\x90\x88\xe7\xba\xa6\xe5\xae\xa2\xe6\x88\xb7\xef\xbc\x89\n (new \\App\\Services\\Trade\\Order\\CompleteService())->receiveDelivery($order['order_no'], $order['user_id'], $order['shop_id'], [], $order['buyer_shop_id'], $opUserId);\n });\n }:14)" [root@localhost ~]# # 用下一条命令也不行为啥? [root@localhost ~]# redis-cli -n 1 --no-raw keys "ho*"|grep -o '".*"'|xargs -i redis-cli -n 1 move {} 2 (integer) 0 [root@localhost ~]# [root@localhost ~]# redis-cli -n 1 keys "ho*"|grep -o '".*"'|awk '{print "move",$0,"2"}' [root@localhost ~]# redis-cli -n 1 keys "ho*"|awk '{print "move",$0,"2"}' # 这里可以看出没使用--no-raw参数,按原始(可读)格式被当做多行拼接了 move horizon:snapshot:job:horizon:job:Closure ( 销售开单或已支付,走普通订单收货逻辑(包括合约客户) 2 move (new \App\Services\Trade\Order\CompleteService())->receiveDelivery($order['order_no'], $order['user_id'], $order['shop_id'], [], $order['buyer_shop_id'], $opUserId); 2 move }); 2 move }:14) 2 [root@localhost ~]# [root@localhost ~]# redis-cli -n 1 --no-raw keys "ho*"|awk '{print "move",$0,"2"}' move 1) "horizon:snapshot:job:horizon:job:Closure ( \xe9\x94\x80\xe5\x94\xae\xe5\xbc\x80\xe5\x8d\x95\xe6\x88\x96\xe5\xb7\xb2\xe6\x94\xaf\xe4\xbb\x98\xef\xbc\x8c\xe8\xb5\xb0\xe6\x99\xae\xe9\x80\x9a\xe8\xae\xa2\xe5\x8d\x95\xe6\x94\xb6\xe8\xb4\xa7\xe9\x80\xbb\xe8\xbe\x91\xef\xbc\x88\xe5\x8c\x85\xe6\x8b\xac\xe5\x90\x88\xe7\xba\xa6\xe5\xae\xa2\xe6\x88\xb7\xef\xbc\x89\n (new \\App\\Services\\Trade\\Order\\CompleteService())->receiveDelivery($order['order_no'], $order['user_id'], $order['shop_id'], [], $order['buyer_shop_id'], $opUserId);\n });\n }:14)" 2 [root@localhost ~]# [root@localhost ~]# redis-cli -n 1 --no-raw keys "ho*"|grep -o '".*"'|awk '{print "move",$0,"2"}' move "horizon:snapshot:job:horizon:job:Closure ( \xe9\x94\x80\xe5\x94\xae\xe5\xbc\x80\xe5\x8d\x95\xe6\x88\x96\xe5\xb7\xb2\xe6\x94\xaf\xe4\xbb\x98\xef\xbc\x8c\xe8\xb5\xb0\xe6\x99\xae\xe9\x80\x9a\xe8\xae\xa2\xe5\x8d\x95\xe6\x94\xb6\xe8\xb4\xa7\xe9\x80\xbb\xe8\xbe\x91\xef\xbc\x88\xe5\x8c\x85\xe6\x8b\xac\xe5\x90\x88\xe7\xba\xa6\xe5\xae\xa2\xe6\x88\xb7\xef\xbc\x89\n (new \\App\\Services\\Trade\\Order\\CompleteService())->receiveDelivery($order['order_no'], $order['user_id'], $order['shop_id'], [], $order['buyer_shop_id'], $opUserId);\n });\n }:14)" 2 [root@localhost ~]# [root@localhost ~]# redis-cli -n 1 keys "ho*" 1) "horizon:snapshot:job:horizon:job:Closure ( \xe9\x94\x80\xe5\x94\xae\xe5\xbc\x80\xe5\x8d\x95\xe6\x88\x96\xe5\xb7\xb2\xe6\x94\xaf\xe4\xbb\x98\xef\xbc\x8c\xe8\xb5\xb0\xe6\x99\xae\xe9\x80\x9a\xe8\xae\xa2\xe5\x8d\x95\xe6\x94\xb6\xe8\xb4\xa7\xe9\x80\xbb\xe8\xbe\x91\xef\xbc\x88\xe5\x8c\x85\xe6\x8b\xac\xe5\x90\x88\xe7\xba\xa6\xe5\xae\xa2\xe6\x88\xb7\xef\xbc\x89\n (new \\App\\Services\\Trade\\Order\\CompleteService())->receiveDelivery($order['order_no'], $order['user_id'], $order['shop_id'], [], $order['buyer_shop_id'], $opUserId);\n });\n }:14)" [root@localhost ~]# redis-cli -n 1 keys "ho*" >111.txt # 如果重定向到文件的话也需要加--no-raw参数 [root@localhost ~]# cat -n 111.txt 1 horizon:snapshot:job:horizon:job:Closure ( 销售开单或已支付,走普通订单收货逻辑(包括合约客户) 2 (new \App\Services\Trade\Order\CompleteService())->receiveDelivery($order['order_no'], $order['user_id'], $order['shop_id'], [], $order['buyer_shop_id'], $opUserId); 3 }); 4 }:14) [root@localhost ~]# redis-cli -n 1 --no-raw keys "ho*" >222.txt [root@localhost ~]# cat -n 222.txt 1 1) "horizon:snapshot:job:horizon:job:Closure ( \xe9\x94\x80\xe5\x94\xae\xe5\xbc\x80\xe5\x8d\x95\xe6\x88\x96\xe5\xb7\xb2\xe6\x94\xaf\xe4\xbb\x98\xef\xbc\x8c\xe8\xb5\xb0\xe6\x99\xae\xe9\x80\x9a\xe8\xae\xa2\xe5\x8d\x95\xe6\x94\xb6\xe8\xb4\xa7\xe9\x80\xbb\xe8\xbe\x91\xef\xbc\x88\xe5\x8c\x85\xe6\x8b\xac\xe5\x90\x88\xe7\xba\xa6\xe5\xae\xa2\xe6\x88\xb7\xef\xbc\x89\n (new \\App\\Services\\Trade\\Order\\CompleteService())->receiveDelivery($order['order_no'], $order['user_id'], $order['shop_id'], [], $order['buyer_shop_id'], $opUserId);\n });\n }:14)" [root@localhost ~]# # 下面试一下del [root@localhost ~]# redis-cli -n 2 keys "*" |wc -l 10001 [root@localhost ~]# redis-cli -n 2 keys "*" | redis-cli -n 2 del # 这里管道符后面不加xargs报错,原因是:不加xargs相当于把整个管道(pipe文件)当做一个参数,加了xargs就相当于把管道内容逐一转换为参数 ERR wrong number of arguments for 'del' command [root@localhost ~]# # 上一条报错参考:https://www.cnblogs.com/enbug/p/16166664.html [root@localhost ~]# redis-cli -n 2 keys "*" |xargs redis-cli -n 2 del xargs: unmatched double quote; by default quotes are special to xargs unless you use the -0 option [root@localhost ~]# redis-cli -n 2 keys "*" |wc -l # 上一条命令删除了一部分key,根据报错发现是因为又有个特殊key:a"a 544 [root@localhost ~]# redis-cli -n 2 keys "*" |head # 特殊key:a"a后面的都没删除 a"a 5358 505 6009 4860 6683 4094 6116 9134 546 [root@localhost ~]# # 下一条命令也不行 [root@localhost ~]# redis-cli -n 2 --no-raw keys "*" |grep -o '".*"'|xargs -i redis-cli -n 2 del {} xargs: unmatched double quote; by default quotes are special to xargs unless you use the -0 option [root@localhost ~]# [root@localhost ~]# redis-cli -n 2 --no-raw keys "*" |wc -l 544 [root@localhost ~]# # 所以还是用下面这条命令吧 [root@localhost ~]# redis-cli -n 2 --no-raw keys "*" |grep -o '".*"'|awk '{print "del",$0}'|redis-cli -n 2 (integer) 1 ... [root@localhost ~]# redis-cli -n 2 --no-raw keys "*" (empty list or set) [root@localhost ~]# redis-cli info keyspace # Keyspace db1:keys=4,expires=0,avg_ttl=0 [root@localhost ~]#
步骤:
- 确定新DB配置
例:
源redis1数据在DB1→目标redis数据在DB1
源redis2数据在DB1、DB2→目标redis数据在DB11、DB12
- 代码发布:包括1、业务暂停通知 2、关闭业务或者更新业务redis连接配置到非源redis和目标redis(即源redis和目标redis均暂停写入数据),这样做是因为阿里云redis变更连接地址太慢了,需要5分钟以上。
- 通过一台ECS使用redis-cli工具移动源redis数据
例:源redis2数据在DB1、DB2→源redis数据在DB11、DB12
# 查看数据 [root@localhost ~]# redis-cli -h redis地址 -a '账号密码' info keyspace # 移动数据 [root@localhost ~]# redis-cli -n 1 --no-raw keys "*"|grep -o '".*"'|awk '{print "move",$0,"11"}' |redis-cli -n 2 (integer) 1 ... # 核对移动后的数据 [root@localhost ~]# redis-cli -h redis地址 -a '账号密码' info keyspace # 以此类推完成多台源redis数据移动
- 阿里云DMS控制台创建全量迁移任务(只迁移源redis中有数据的DB,即上一步移动后的DB)
- DMS全量迁移完成后,核对数据迁移情况
- DMS迁移完成且无误,停止或释放迁移任务
- 代码发布:包括业务重启或者更新业务redis连接配置到目标redis(即开始向迁移后的那台目标redis写入数据)
- 根据情况处理源redis
专业!!