redis-full-check校验工具

2,078 阅读2分钟

redis-full-check校验工具

1. 介绍

redis-full-check是阿里云Redis&MongoDB团队开源的用于校验2个redis数据是否一致的工具,通常用于redis数据迁移(redis-shake)后正确性的校验。   支持:单节点、主从版、集群版、带proxy的云上集群版(阿里云)之间的同构或者异构对比,版本支持2.x-5.x。

2.原理

redis-full-check.png

redis-full-check通过全量对比源端和目的端的redis中的数据的方式来进行数据校验,其比较方式通过多轮次比较:每次都会抓取源和目的端的数据进行差异化比较,记录不一致的数据进入下轮对比(记录在sqlite3 db中)。然后通过多伦比较不断收敛,减少因数据增量同步导致的源库和目的库的数据不一致。最后sqlite中存在的数据就是最终的差异结果。   redis-full-check对比的方向是单向:抓取源库A的数据,然后检测是否位于B中,反向不会检测,也就是说,它检测的是源库是否是目的库的子集。如果希望对比双向,则需要对比2次,第一次以A为源库,B为目的库,第二次以B为源库,A为目的库。

下图是基本的数据流图,redis-full-check内部分为多轮比较,也就是黄色框所指示的部分。每次比较,会先抓取比较的key,第一轮是从源库中进行抓取,后面轮次是从sqlite3 db中进行抓取;抓取key之后是分别抓取key对应的field和value进行对比,然后将存在差异的部分存入sqlite3 db中,用于下次比较。

redis-full-check-data-flow.png

3. 安装

$wget https://github.com/alibaba/RedisFullCheck/releases/download/release-v1.4.7-20191203/redis-full-check-1.4.7.tar.gz . 
$tar -zxvf redis-full-check-1.4.7.tar.gz 
#移到path中
$mv redis-full-check-1.4.7/redis-full-check /usr/local/bin/

安装问题: 有可能在安装后执行,提示缺少lib64/libc.so.6 GLIBC_2.14 问题解决: blog.csdn.net/cocoin/arti…

#看当前的glibc
strings /lib64/libc.so.6  |grep GLIBC
#直载
wget http://ftp.gnu.org/gnu/glibc/glibc-2.14.tar.gz
tar -zxvf glibc-2.14.tar.gz
cd glibc-2.14
mkdir build
cd build
../configure --prefix=/usr/local/glibc-2.14 
make -j8
make install
#拷贝libc-2.14.1.so到/lib64目录下
cd /usr/local/glibc-2.14/lib 
cp libc-2.14.so /lib64/
ll /lib64/libc.so.6 
#创建软连接,因为以前的指向libc-2.12.so,更改可能会有风险
LD_PRELOAD=/lib64/libc-2.14.so ln -s /lib64/libc-2.14.so libc.so.6 
#或要使用的时候,临时修改环境变量
echo $LD_LIBRARY_PATH
export LD_LIBRARY_PATH=/usr/local/glibc-2.14/lib:$LD_LIBRARY_PATH

4. 比较模式

4.1 不一致类型

redis-full-check判断不一致的方式主要分为2类:key不一致和value不一致。

key不一致:

  • lack_target : key存在于源库,但不存在于目的库。
  • type: key存在于源库和目的库,但是类型不一致。
  • value: key存在于源库和目的库,且类型一致,但是value不一致。

value不一致:

  • string: value不同。
  • hash/set/zset/list : 存在field,要比较field的key/value。

4.2 比较模式

对比模式(comparemode)有三种可选:

  • KeyOutline:只对比key值是否相等。
  • ValueOutline:只对比value值的长度是否相等。
  • FullValue:对比key值、value长度、value值是否相等。

5. 参数说明

redis-full-check中主要参数如下:

#redis-full-check中主要参数如下:
  -s, --source=SOURCE               源redis库地址(ip:port),如果是集群版,那么需要以分号(;)分割不同的db,只需要配置主或者从的其中之一。例如:10.1.1.1:1000;10.2.2.2:2000;10.3.3.3:3000。
  -p, --sourcepassword=Password     源redis库密码
      --sourceauthtype=AUTH-TYPE    源库管理权限,开源reids下此参数无用。
      --sourcedbtype=               源库的类别,0:db(standalone单节点、主从),1: cluster(集群版),2: 阿里云
      --sourcedbfilterlist=         源库需要抓取的逻辑db白名单,以分号(;)分割,例如:0;5;15表示db0,db5和db15都会被抓取
  -t, --target=TARGET               目的redis库地址(ip:port)
  -a, --targetpassword=Password     目的redis库密码
      --targetauthtype=AUTH-TYPE    目的库管理权限,开源reids下此参数无用。
      --targetdbtype=               参考sourcedbtype
      --targetdbfilterlist=         参考sourcedbfilterlist
  -d, --db=Sqlite3-DB-FILE          对于差异的key存储的sqlite3 db的位置,默认result.db
      --comparetimes=COUNT          比较轮数
  -m, --comparemode=                比较模式,1表示全量比较,2表示只对比value的长度,3只对比key是否存在,4全量比较的情况下,忽略大key的比较
      --id=                         用于打metric
      --jobid=                      用于打metric
      --taskid=                     用于打metric
  -q, --qps=                        qps限速阈值
      --interval=Second             每轮之间的时间间隔
      --batchcount=COUNT            批量聚合的数量
      --parallel=COUNT              比较的并发协程数,默认5
      --log=FILE                    log文件
      --result=FILE                 不一致结果记录到result文件中,格式:'db    diff-type    key    field'
      --metric=FILE                 metric文件
      --bigkeythreshold=COUNT       大key拆分的阈值,用于comparemode=4
  -f, --filterlist=FILTER           需要比较的key列表,以分号(;)分割。例如:"abc*|efg|m*"表示对比'abc', 'abc1', 'efg', 'm', 'mxyz',不对比'efgh', 'p'。
  -v, --version

6. 使用

例如:源redis库是10.1.1.1:1234,目的库是10.2.2.2:5678:
#sourcedbtype  0: db, 1: cluster ,comparemode
#执行比较
$redis-full-check -s 10.1.1.1:1234 --sourcedbtype=1 -t 10.2.2.2:5678 --targetdbtype=1  -p mock_source_password -a mock_target_password  -m 3 --log log --result result

7.查看结果

结果会保存在sqlite3 db file中,不指定的话,就是当前目录的 result.db 文件:比如有3轮比较,那么会有result.db.1,result.db.2,result.db.33个文件。

  • 表key:保存不一致的key
  • 表field:保存hash,set,zset,list不一致的field, list 存的是下标值
  • 表feild的key_id字段关联表key的id字段
  • 表key_和field_:保存第N轮比较后的结果,即中间结果。

使用举例:

$sqlite3  result.db
$.help
sqlite> .databases 
sqlite> .schema 
sqlite> select * from key;
id          key              type        conflict_type  db          source_len  target_len
----------  ---------------  ----------  -------------  ----------  ----------  ----------
1           keydiff1_string  string      value          1           6           6
2           keydiff_hash     hash        value          0           2           1
3           keydiff_string   string      value          0           6           6
4           key_string_diff  string      value          0           6           6
5           keylack_string   string      lack_target    0           6           0
sqlite>

sqlite> select * from field;
id          field       conflict_type  key_id
----------  ----------  -------------  ----------
1           k1          lack_source    2
2           k2          value          2
3           k3          lack_target    2

参考: