Redis-shake是一个用于在两个redis之间同步数据的工具,满足用户非常灵活的同步、迁移需求。
GitHub地址:https://github.com/alibaba/RedisShake

  1. 下载解压

    1. wget -c https://github.com/alibaba/RedisShake/releases/download/release-v1.6.24-20191220/redis-shake-1.6.24.tar.gz
    2. tar -zxvf redis-shake-1.6.24.tar.gz
    3. cd redis-shake-1.6.24.tar.gz
  2. 配置文件 ```shell

    this is the configuration of redis-shake.

id

id = redis-shake

log file,日志文件,不配置将打印到stdout

log_file =

pprof port

system_profile = 9310

restful port,查看metric端口

http_profile = 9320

runtime.GOMAXPROCS, 0 means use cpu core number: runtime.NumCPU()

ncpu = 0

parallel routines number used in RDB file syncing.

parallel = 4

input RDB file. read from stdin, default is stdin (‘/dev/stdin’).

used in decode and restore.

如果是decode或者restore,这个参数表示读取的rdb文件

input_rdb = local_dump

output RDB file. default is stdout (‘/dev/stdout’).

used in decode and dump.

如果是decode或者dump,这个参数表示输出的rdb

output_rdb = local_dump

source redis configuration.

used in dump and sync.

ip:port

源redis地址

source.address = 127.0.0.1:20441

password.

source.password_raw = kLNIl691OZctWST

auth type, don’t modify it

source.auth_type = auth

version number, default is 6 (6 for Redis Version <= 3.0.7, 7 for >=3.2.0)

source.version = 6

target redis configuration. used in restore and sync.

used in restore and sync.

ip:port

目的redis地址

target.address = 10.101.72.137:20551

password.

target.password_raw = kLNIl691OZctWST

auth type, don’t modify it

target.auth_type = auth

version number, default is 6 (6 for Redis Version <= 3.0.7, 7 for >=3.2.0)

target.version = 6

all the data will come into this db. < 0 means disable.

used in restore and sync.

target.db = -1

use for expire key, set the time gap when source and target timestamp are not the same.

用于处理过期的键值,当迁移两端不一致的时候,目的端需要加上这个值

fake_time =

force rewrite when destination restore has the key

used in restore and sync.

当源目的有重复key,是否进行覆写

rewrite = true

filter db or key or slot

choose these db, e.g., 5, only choose db5. defalut is all.

used in restore and sync.

支持过滤db,只让指定的db通过

filter.db =

filter key with prefix string. multiple keys are separated by ‘;’.

e.g., a;b;c

default is all.

used in restore and sync.

支持过滤key,只让指定的key通过,分号分隔

filter.key =

filter given slot, multiple slots are separated by ‘;’.

e.g., 1;2;3

used in sync.

指定过滤slot,只让指定的slot通过

filter.slot =

big key threshold, the default is 500 1024 1024. The field of the big key will be split in processing.

我们对大key有特殊的处理,此处需要指定大key的阈值

big_key_threshold = 524288000

use psync command.

used in sync.

默认使用sync命令,启用将会使用psync命令

psync = false

enable metric

used in sync.

是否启用metric

metric = true

print in log

是否将metric打印到log中

metric.print_log = true

heartbeat

send heartbeat to this url

used in sync.

心跳的url地址,redis-shake将会发送到这个地址

heartbeat.url = http://127.0.0.1:8000

interval by seconds

心跳保活周期

heartbeat.interval = 3

external info which will be included in heartbeat data.

在心跳报文中添加额外的信息

heartbeat.external = test external

local network card to get ip address, e.g., “lo”, “eth0”, “en0”

获取ip的网卡

heartbeat.network_interface =

sender information.

sender flush buffer size of byte.

used in sync.

发送缓存的字节长度,超过这个阈值将会强行刷缓存发送

sender.size = 104857600

sender flush buffer size of oplog number.

used in sync.

发送缓存的报文个数,超过这个阈值将会强行刷缓存发送

sender.count = 5000

delay channel size. once one oplog is sent to target redis, the oplog id and timestamp will also stored in this delay queue. this timestamp will be used to calculate the time delay when receiving ack from target redis.

used in sync.

用于metric统计时延的队列

sender.delay_channel_size = 65535

————————splitter————————

below variables are useless for current opensource version so don’t set.

replace hash tag.

used in sync.

replace_hash_tag = false

used in restore and dump.

extra = false

  1. 部分内容
  2. ```shell
  3. 这部分应该是用户最困惑的地方,为了满足用户的灵活配置,目前开放了较多的配置项,但用户一开始使用并不需要管这么多的项。默认sync模式只需要配置以下几个内容:
  4. source.type: 源redis的类型,支持一下4种类型:
  5.   standalone: 单db节点/主从版模式。如果源端是从多个db节点拉取就选择这个模式,即便是codis等开源的proxy-db架构。
  6.   sentinel: sentinel模式。
  7.   cluster: 集群模式。开源的cluster。对于阿里云来说,用户目前无法拉取db的地址,所以此处只能是proxy。
  8.   proxy: proxy模式。如果是阿里云redis的集群版,从proxy拉取/写入请选择proxy,从db拉取请选择cluster。正常cluster到cluster同步源端请选择cluster模式,proxy模式目前只用于rump。。
  9. source.address: 源redis的地址,从1.6版本开始我们支持集群版,不同的类型对应不同的地址:
  10. standalone模式下,需要填写单个db节点的地址,主从版需要输入master或者slave的地址。
  11. sentinel模式下,需要填写sentinel_master_name:master_or_slave@sentinel_cluster_address。sentinel_master_name表示sentinel配置下master的名字,master_or_slave表示从sentinel中选择的db是master还是slave,sentinel_cluster_address表示sentinel的单节点或者集群地址,其中集群地址以分号(;)分割。例如:mymaster:master@127.0.0.1:26379;127.0.0.1:26380。注意,如果是sentinel模式,目前只能拉取一个master或者slave信息,如果需要拉取多个节点,需要启动多个shake。
  12. cluster模式下,需要填写集群地址,以分号(;)分割。例如:10.1.1.1:20331;10.1.1.2:20441。同样也支持上面sentinel介绍的自动发现机制,包含@即可,参考3.2。
  13. proxy模式下,需要填写单个proxy的地址,此模式目前仅用于rump。
  14. source.password_raw:源redis的密码。
  15. target.type: 目的redis的类型,与source.type一致。注意,目的端如果是阿里云的集群版,类型请填写proxy,填写cluster只会同步db0。
  16. target.address:目的redis的地址。从1.6版本开始我们支持集群版,不同的类型对应不同的地址。 standalone模式,参见source.address。
  17. sentinel模式,需要填写sentinel_master_name@sentinel_cluster_address。sentinel_master_name表示sentinel配置下master的名字,sentinel_cluster_address表示sentinel的单节点或者集群地址,其中集群地址以分号(;)分割。例如:mymaster@127.0.0.1:26379;127.0.0.1:26380
  18. cluster模式,参见source.address。
  19. proxy模式下,填写proxy的地址,如果是多个proxy,则round-robin循环负载均衡连接,保证一个源端db连接只会对应一个proxy。如果是阿里云的集群版请选择这种模式。
  20. target.password_raw:目的redis的密码。
  21. 用户配置完配置文件,然后以不同的模式启动即可:./redis-shake -conf=redis-shake.conf -type=sync。
  22. 3.1 单个节点到单个节点配置举例。
  23. source.type: standalone
  24. source.address: 10.1.1.1:20441
  25. source.password_raw: 12345
  26. target.type: standalone
  27. target.address: 10.1.1.1:20551
  28. target.password_raw: 12345
  29. 3.2 集群版cluster到集群版cluster配置举例
  30. source.type: cluster
  31. source.address: 10.1.1.1:20441;10.1.1.1:20443;10.1.1.1:20445
  32. source.password_raw: 12345
  33. target.type: cluster
  34. target.address: 10.1.1.1:20551;10.1.1.1:20553;10.1.1.1:20555
  35. target.password_raw: 12345
  36.   对于source.address或者target.address,需要配置源端的所有集群中db节点列表以及目的端集群所有db节点列表,用户也可以启用自动发现机制,地址以'@'开头,redis-shake将会根据cluster nodes命令自动去探测有几个节点。对于source.address,用户可以在'@'前面配置master(默认)或者slave表示分表从master或者slave进行拉取;对于target.address,只能是master或者不配置:
  37. source.type: cluster
  38. source.address: master@10.1.1.1:20441 # 将会自动探测到10.1.1.1:20441集群下的所有节点,并从所有master进行拉取。同理如果是slave@10.1.1.1:20441将会扫描集群下的所有slave节点。
  39. source.password_raw: 12345
  40. target.type: cluster
  41. target.address: @10.1.1.1:20551 # 将会自动探测到10.1.1.1:20551集群下的所有节点,并写入所有master。
  42. target.password_raw: 12345
  43.   以上的说明是开源cluster,当然,源端也可以是别的集群架构模式,比如带proxy的集群(比如codis,或者别的云集群架构,但这种情况下有些不支持自动发现,需要手动配置所有master或者slave的地址),那么需要选择db节点进行拉取,source.type同样选择cluster,source.address后面跟所有db的地址(只要主或者从的其中一个即可)。
  44. 3.3 集群版cluster到proxy配置举例
  45. source.type: cluster
  46. source.address: 10.1.1.1:20441;10.1.1.1:20443;10.1.1.1:20445;10.1.1.1:20447
  47. source.password_raw: 12345
  48. target.type: proxy
  49. target.address: 10.1.1.1:30331;10.1.1.1:30441;10.1.1.1:30551
  50. target.password_raw: 12345
  51.   source.address同样支持自动发现机制,参考3.2。此外,target.address为proxy的地址,proxy支持roundrobin写入,也就是说,对于这个配置来说,10.1.1.1:20441和10.1.1.1:20447将会写入10.1.1.1:30331;10.1.1.1:20443写入10.1.1.1:30441;10.1.1.1:20445写入10.1.1.1:30551。
  52.   如3.2中所述,源端也可以是别的集群架构模式。
  53. 3.4 主从版/单节点到cluster配置举例
  54. source.type: standalone
  55. source.address: 10.1.1.1:20441
  56. source.password_raw: 12345
  57. target.type: cluster
  58. target.address: 10.1.1.1:30331;10.1.1.1:30441;10.1.1.1:30551
  59. target.password_raw: 12345

更详细的查看: https://github.com/alibaba/RedisShake/wiki/%E7%AC%AC%E4%B8%80%E6%AC%A1%E4%BD%BF%E7%94%A8%EF%BC%8C%E5%A6%82%E4%BD%95%E8%BF%9B%E8%A1%8C%E9%85%8D%E7%BD%AE%EF%BC%9F

重点修改参数:

  1. source.type: standalone
  2. source.address: 10.1.1.1:20441
  3. source.password_raw: 12345
  4. target.type: standalone
  5. target.address: 10.1.1.1:20551
  6. target.password_raw: 12345
  7. rewrite=true 当存在相同key的时候,处理方式: 重写/忽略
  8. key_exists 当源目的有重复key,是否覆写, rewrite:覆写 none:直接进程退出 ignore:保留目的端key,忽略远端同步的key,该值在rump模式下没有用
  9. target.db = -1 默认是全部的数据, 也可以指定同步某个库中的数据 例如,要将所有数据迁移到目的Redis中的DB10,则需将此参数的值设置为10。当该值设置为-1时,逻辑数据库名在源Redis和目的Redis中的名称相同,即源Redis中的DB0将被迁移至目的Redis中的DB0DB1将被迁移至DB1,以此类推。
  10. filter.db.whitelist 指定的db被通过, 比如0;5;10将会是db0,db5,db10通过, 其他都会被过滤
  1. 启动

启动二进制:

  1. ./redis-shake.linux -conf=redis-shake.conf -type=xxx # xxx为sync, restore, dump, decode, rump其中之一,全量+增量同步请选择sync。

mac下请使用redis-shake.darwin,windows请用redis-shake.windows.
完成同步则会显示:
2022/03/21 18:19:07 [INFO] DbSyncer[0] total = 3.59MB - 3.59MB [100%] entry=23 filter=205
2022/03/21 18:19:07 [INFO] DbSyncer[0] sync rdb done

  1. 校验同步(redis-full-check github:https://github.com/alibaba/RedisFullCheck)

在Redis迁移完成后进行数据校验可以检查数据的一致性。
1) 下载,解压

  1. wget -c https://github.com/alibaba/RedisFullCheck/releases/download/release-v1.4.7-20191203/redis-full-check-1.4.7.tar.gz
  2. tar -zxvf redis-full-check-1.4.7.tar.gz && cd redis-full-check-1.4.7.tar.gz

2) 执行数据校验命令

  1. ./redis-full-check -s "<Redis集群地址1连接地址:Redis集群地址1端口号;Redis集群地址2连接地址:Redis集群地址2端口号;Redis集群地址3连接地址:Redis集群地址3端口号>" -p <Redis集群密码> -t <Redis连接地址:Redis端口号> -a <Redis密码> --comparemode=1 --comparetimes=1 --qps=10 --batchcount=100 --sourcedbtype=1 --targetdbfilterlist=0

注意: 如果目标是集群的话,需要指定—targetdbtype 类型为1

选项 说明 示例值
-s 源端Redis的连接地址和端口。

说明
- 如果源Redis为集群版,每个集群地址间需要以半角分号(;)分割不同的连接地址。
- 集群地址前后需要添加半角双引号(”)。
- 该选项必填。
r-bp1xxxxxxxxxxxxx.redis.rds.aliyuncs.com:6379


“10.xx.xx.1:7000;10.xx.xx.1:7001;10.xx.xx.2:7002;10.xx.xx.2:7003”
-p 源端Redis的密码。 SourcePwd233
-t 目的端Redis的连接地址和端口。

说明
- 如果目的Redis为集群版,每个集群地址间需要以半角分号(;)分割不同的连接地址。
- 集群地址前后需要添加半角双引号(”)。
- 该选项必填。
r-bp1xxxxxxxxxxxxx.redis.rds.aliyuncs.com:6379



“10.xx.xx.1:7000;10.xx.xx.1:7001;10.xx.xx.2:7002;10.xx.xx.2:7003”
-a 目的端Redis的密码。 TargetPwd233
—sourcedbtype 源库的类别:
- 0:单节点版、主从版
- 1:集群版
- 2:阿里云/腾讯云
—sourcedbtype=1
—sourcedbfilterlist 源端Redis指定需要校验的DB。

说明
- 开源集群版Redis无需填写该选项。
- 非开源集群版Redis不指定该选项表示校验所有DB。
- 多个DB之间使用半角分号(;)连接。
—sourcedbfilterlist=0;1;2
—targetdbtype 目的库的类别:
- 0:单节点版、主从版
- 1:集群版
- 2:阿里云/腾讯云
—targetdbtype=0
—targetdbfilterlist 目的端Redis指定需要校验的DB。

说明
- 开源集群版Redis无需填写该选项。
- 非开源集群版Redis不指定该选项表示校验所有DB。
- 多个DB之间使用半角分号(;)连接。
—targetdbfilterlist=0;1;2
-d 异常数据列表保存的文件名称,默认为result.db。 xxx.db
—comparetimes 校验次数。
- 该选项不填则默认为3次。
- 最小值为1。
- 无最大值,建议不超过5次。
—comparetimes=1
-m 校验模式。
- 1:全量校验
- 2:仅校验value的长度
- 3:仅校验key是否存在
- 4:全量对比的情况下,忽略大key的比较
1
—qps 限速阈值。

说明
- 最小值为1。
- 最大值取决于服务器性能。
—qps=10
—filterlist 需要比较的key列表,以竖线(|)分割。

说明
- abc*:表示匹配所有abc开头的key。
- abc:表示仅匹配abc这个key。
—filterlist=abc|efg|m

3)校验结果验证
image.png
i) 执行查看命令

  1. sqlite3 result.db.3

ii)查看异常表数据

  1. select * from key;

image.png

  1. 数据的导入与导出 ```shell 数据导出: ./redis-shake.linux -conf=redis-shake.conf -type=dump

数据导入: ./redis-shake.linux -conf=redis-shake.conf -type=restore

注意: 数据导入的时候需要配置要导入的类型与数据源 source.rdb.input = local_dump.0

  1. 有问题可以查看官方FAQ:https://github.com/alibaba/RedisShake/wiki/FAQ
  2. 常见问题:<br />1.[PANIC] target key name is busy: hash:user:auth:server:*<br />这种是因为目的redis已经存在该key, 官方提供了三种解决方案<br />1)删除目的端redis内容<br />2)配置文件中开启rewrite=true (key_exists=rewrite) 存在则覆写<br />3)设置key_exists=ignore, 忽略冲突的键
  3. 2. 同步的时候 没有反应, 出现堵塞的情况,<br />需要修改配置项:
  4. ```shell
  5. slave-serve-stale-data yes
  6. # bgsave失败的时候是否停止写入
  7. stop-writes-on-bgsave-error no