一、简介

redis-shake是阿里云Redis&MongoDB团队开源的用于redis数据同步的工具。

1.1基本功能

它支持解析、恢复、备份、同步四个功能。以下主要介绍同步sync。

  • 恢复restore:将RDB文件恢复到目的redis数据库。
  • 备份dump:将源redis的全量数据通过RDB文件备份起来。
  • 解析decode:对RDB文件进行读取,并以json格式解析存储。
  • 同步sync:支持源redis和目的redis的数据同步,支持全量和增量数据的迁移。
  • 同步rump:支持源redis和目的redis的数据同步,仅支持全量的迁移。采用scan和restore命令进行迁移。

1.2 基本原理

redis-shake的基本原理就是模拟一个从节点加入源redis集群,首先进行全量拉取并回放,然后进行增量的拉取(通过psync命令)。如下图所示:

如果源端是集群模式,只需要启动一个redis-shake进行拉取,同时不能开启源端的move slot操作。如果目的端是集群模式,可以写入到一个结点,然后再进行slot的迁移,当然也可以多对多写入。   目前,redis-shake到目的端采用单链路实现,对于正常情况下,这不会成为瓶颈,但对于极端情况,qps比较大的时候,此部分性能可能成为瓶颈,后续我们可能会计划对此进行优化。另外,redis-shake到目的端的数据同步采用异步的方式,读写分离在2个线程操作,降低因为网络时延带来的同步性能下降。

1.3 高效性

全量同步阶段并发执行,增量同步阶段异步执行,能够达到毫秒级别延迟(取决于网络延迟)。同时,我们还对大key同步进行分批拉取,优化同步性能。

1.4 监控

用户可以通过我们提供的restful拉取metric来对redis-shake进行实时监控:curl 127.0.0.1:9320/metric。

1.5 校验

可采用redis-full-check来校验同步的正确性。

二、安装redis-shake

2.1 下载

wget https://github.com/alibaba/RedisShake/releases/download/release-v2.0.3-20200724/redis-shake-v2.0.3.tar.gz;
tar zxvf redis-shake-v2.0.3.tar.gz;
cd redis-shake-v2.0.3;

2.2 修改配置文件

vim redis-shake.conf - source.type: 源redis的类型,支持一下4种类型: standalone: 单db节点/主从版模式。 sentinel: sentinel模式。 cluster: 集群模式。 proxy: proxy模式。如果是阿里云redis的集群版,从proxy拉取/写入请选择proxy - source.address: 源redis的地址,不同的类型对应不同的地址: standalone模式下,需填写单个db节点的地址,主从版需输入master或者slave的地址。 sentinel模式下,例如:master:master@127.0.0.1:26379;127.0.0.1:26380 cluster模式下,需填写集群地址,以分号(;)分割。例如:10.1.1.1:20331;10.1.1.2:20441 proxy模式下,需要填写单个proxy的地址,此模式目前仅用于rump。 - source.password_raw:源redis的密码。 - target.type: 目的redis的类型 - target.address:目的redis的地址。 sentinel模式,例如:mymaster@127.0.0.1:26379;127.0.0.1:26380 cluster模式,参见source.address。 proxy模式下,填写proxy的地址,如果是多个proxy,则round-robin循环负载均衡连接,保证一个源端db连接只会对应一个proxy。 - target.password_raw:目的redis的密码。

2.3 配置示例

2.3.1 单个节点到单个节点配置举例

source.type: standalone
source.address: 192.168.118.41:6379
source.password_raw: 12345
target.type: standalone
target.address: 192.168.118.51:6379
target.password_raw: 12345

2.3.2 集群版cluster到集群版cluster配置举例

source.type: cluster
#源集群可只写从节点
source.address: 192.168.118.41:6380;192.168.118.42:6380;192.168.118.43:6380
source.password_raw: 12345
target.type: cluster
target.address: 192.168.118.51:6379;192.168.118.52:6379;192.168.118.53:6379
target.password_raw: 12345

2.3.3 主从版/单节点到cluster配置举例

source.type: standalone
source.address: 192.168.121.221:6380;192.168.121.222:6380;192.168.121.223:6380
source.password_raw: 12345
target.type: cluster
target.address: 192.168.121.224:6379;192.168.121.225:6379;192.168.121.226:6379
target.password_raw: 12345

2.4 测试数据

大概建立了230w的测试数据

#!/bin/bash
for ((i=1;i<2300000;i++))
do
echo -en "helloworld$i" | redis-cli -c -x set name$i >>redis.log
done

2.5 配置源集群从节点,目标集群主节点

source.type = cluster
source.address = 192.168.121.221:6380;192.168.121.222:6380;192.168.121.223:6380
source.password_raw =
target.type = cluster
target.address = 192.168.121.224:6379;192.168.121.225:6379;192.168.121.226:6379
target.password_raw =

2.6 启动

./redis-shake.linux -conf=redis-shake.conf -type=sync
  1. 开始同步

  2. 全量同步阶段,显示百分比:

  3. 增量同步,出现字样sync rdb done后,当前dbSyncer进入增量同步:

其中forwardCommands表示发送的命令个数,filterCommands表示过滤的命令个数,比如opinfo或者指定了filter都会被过滤,writeBytes表示发送的字节数。

  1. 同步完查看源集群和目标集群keys

  1. 同步过程中源集群监控

  1. 同步过程中目标集群监控

2.7 监控

http://192.168.121.226:9320/metric

三、 校验

3.1下载

wget https://github.com/alibaba/RedisFullCheck/releases/download/release-v1.4.8-20200212/redis-full-check-1.4.8.tar.gz
tar zxvf redis-full-check-1.4.8.tar.gz
cd redis-full-check-1.4.8

参数:

-s, --source=SOURCE            源redis库地址(ip:port),
-p, --sourcepassword=Password  源redis库密码
    --sourcedbtype=              源库的类别,0:db(单节点、主从),1: cluster(集群版),2: 阿里云
-t, --target=TARGET              目的redis库地址(ip:port)
-a, --targetpassword=Password   目的redis库密码
    --targetdbtype=            参考sourcedbtype
-d, --db=Sqlite3-DB-FILE          对于差异的key存储的sqlite3 db的位置,默认result.db
    --comparetimes=COUNT      比较轮数
-m, --comparemode=             比较模式,1表示全量比较,2表示只对比value的长度,3只对比key是否存在,4全量比较的情况下,忽略大key的比较
    --id=                         用于打metric
-q, --qps=                       qps限速阈值
    --interval=Second             每轮之间的时间间隔
    --batchcount=COUNT         批量聚合的数量
    --parallel=COUNT              比较的并发协程数,默认5
    --log=FILE                    log文件
    --result=FILE                 不一致结果记录到result文件中,格式:'db  diff-type  key  field'

3.2开始校验

./redis-full-check -s "192.168.121.221:6380;192.168.121.222:6380;192.168.121.223:6380" -t "192.168.121.224:6379;192.168.121.225:6379;192.168.121.226:6379" --comparemode=1 --comparetimes=3  --sourcedbtype=1 --targetdbtype=1

注:–comparemode=1 比较模式:全量比较 –comparetimes=3 比较轮数:3轮

3.3 校验日志分析

  1. 初始化校验

  2. 开始scan比较

  3. 开始比较第二轮

  4. 开始比较第三轮

  5. 校验结果验证

  6. 查看异常表数据

结果会保存在sqlite3 db file中,不指定的话,就是当前目录的 result.db 文件:比如有3轮比较,那么会有result.db.1,result.db.2,result.db.3 3个文件, - 表key:保存不一致的key - 表field:保存hash,set,zset,list不一致的field, list 存的是下标值 - 表feild的key_id字段关联表key的id字段 - 表key_和field_:保存第N轮比较后的结果,即中间结果