首页 > 数据库 >【Redis 技术探索】「数据迁移实战」手把手教你如何实现在线 + 离线模式进行迁移 Redis 数据实战指南(数据检查对比)

【Redis 技术探索】「数据迁移实战」手把手教你如何实现在线 + 离线模式进行迁移 Redis 数据实战指南(数据检查对比)

时间:2023-01-10 13:34:05浏览次数:66  
标签:实战 full -- Redis redis value key 迁移 check

redis-full-check的使用背景

在经历了之前的文章内容章节内容,已完成Redis迁移后,可能会存在以下问题需要进行数据迁移之后的对比。例如,如果Redis迁移的过程出现异常,源端与目的端Redis的数据将会不一致。

  • 【Redis 技术探索】「数据迁移实战」手把手教你如何实现在线 + 离线模式进行迁移 Redis 数据实战指南(在线同步数据)
  • 【Redis 技术探索】「数据迁移实战」手把手教你如何实现在线 + 离线模式进行迁移 Redis 数据实战指南(离线同步数据)
  • 【Redis 技术探索】「数据迁移实战」手把手教你如何实现在线 + 离线模式进行迁移 Redis 数据实战指南(scan 模式迁移)

在Redis迁移完成后进行数据校验可以检查数据的一致性,该如何校验就是我们本文的内容。我们在这里采用的是阿里开源的数据对比工具与Redis-Shake形成伴侣模式的开源工具redis-full-check,使用redis-full-check进行校验能够找出异常数据,为数据对齐提供可靠依据,本文主要介绍如何使用RedisFullCheck。

【Redis 技术探索】「数据迁移实战」手把手教你如何实现在线 + 离线模式进行迁移 Redis 数据实战指南(数据检查对比)_Redis

redis-full-check的基本介绍

redis-full-check是阿里云自研的Redis数据校验工具,能够提取源端和目的端的数据进行多轮差异化比较,并将比较结果记录在一个SQLite3数据库中,从而达到全量数据校验的目的。

迁移源端和目的端Redis实例需为主从版、单节点版、开源集群版以及部分云上带proxy的集群版(阿里云、腾讯云)。

开源地址

【Redis 技术探索】「数据迁移实战」手把手教你如何实现在线 + 离线模式进行迁移 Redis 数据实战指南(数据检查对比)_redis_02

【Redis 技术探索】「数据迁移实战」手把手教你如何实现在线 + 离线模式进行迁移 Redis 数据实战指南(数据检查对比)_Redis_03

编译源码

运行 ./bin/redis-full-check.darwin64 or redis-full-check.linux64,它分别在OSX和Linux中构建,然而,二进制文件并不总是最新版本。 或者您可以根据以下步骤构建red- full-check自己:

git clone https://github.com/alibaba/RedisFullCheck.git
cd RedisFullCheck/src/vendor
GOPATH=`pwd`/../..; govendor sync

注意:必须先安装govendor,然后拉出所有依赖

cd ../../ && ./build.sh

执行build.sh进行编译即可。

基本原理

  • redis-full-check通过全量对比源端目的端的redis中的数据的方式来进行数据校验,其比较方式通过多轮次比较:每次都会抓取源和目的端的数据进行差异化比较,记录不一致的数据进入下轮对比(记录在sqlite3 db中)。
  • 通过多伦比较不断收敛,减少因数据增量同步导致的源库和目的库的数据不一致。最后sqlite中存在的数据就是最终的差异结果。

数据对比介绍

redis-full-check对比的方向是单向,如果希望对比双向,则需要对比2次,第一次以A为源库,B为目的库,第二次以B为源库,A为目的库。

  • 首次对别:会抓取源库A的数据,然后检测是否位于B中,反向不会检测,它检测的是源库是否是目的库的子集。每次比较,会先抓取比较的key。

第一轮是从源库中进行抓取,后面轮次是从sqlite3 db中进行抓取;抓取key之后是分别抓取key对应的field和value进行对比,然后将存在差异的部分存入sqlite3 db中,用于下次比较

数据对比核心流程

下图是基本的数据流图。

【Redis 技术探索】「数据迁移实战」手把手教你如何实现在线 + 离线模式进行迁移 Redis 数据实战指南(数据检查对比)_数据_04

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

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

对比会进行comparetimes轮(默认comparetimes=3)比较:

  • 第一轮,首先找出在源库上所有的key,然后分别从源库和目的库抓取进行比较。
  • 第二轮,开始迭代比较,只比较上一轮结束后仍然不一致的key和field。
不一致场景下分析

对于key不一致的情况,包括lack_source ,lack_target 和type,从源库和目的库重新取key、value进行比较。

  1. value不一致的string,重新比较key:从源和目的取key、value比较。
  2. value不一致的hash、set和zset,只重新比较不一致的field,之前已经比较且相同的filed不再比较。这是为了防止对于大key情况下,如果更新频繁,将会导致校验永远不通过的情况。
  3. value不一致的list,重新比较key:从源和目的取key、value比较。

每轮之间会停止一定的时间(Interval)。

对于hash,set,zset,list大key处理采用以下方式:
  • len <= 5192,直接取全量field、value进行比较,使用如下命令:hgetall,smembers,zrange 0 -1 withscores,lrange 0 -1。
  • len > 5192,使用hscan,sscan,zscan,lrange分批取field和value。

使用redis-full-check

  1. 解压redis-full-check.tar.gz:tar -xvf redis-full-check.tar.gz
  2. 执行如下命令进行数据校验:
  • 单机实例之间进行数据对比检测
./redis-full-check -s $(source_redis_ip_port) -p $(source_password) -t $(target_redis_ip_port) -a $(target_password)
  • 集群实例之间进行数据对比检测
./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

参数信息介绍

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

对比实现案例

对比2个主从版/单节点:
./redis-full-check -t 10.101.72.137:30661 -s 10.101.72.137:30551
对比主从和集群:
./redis-full-check -s "100.81.164.177:21331;100.81.164.177:21332;100.81.164.177:21333" -t 10.101.72.137:30551 --comparemode=1 --comparetimes=1 --qps=10 --batchcount=100 --sourcedbtype=1 --targetdbfilterlist=0

由于集群版只有db0,所以如果一端是集群版,另一端是非集群版(多个逻辑db),则需要添加sourcedbfilterlist或者targetdbfilterlist(非集群版本的一端)

查询对比结果

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

对比结果差异分析

不一致类型

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

key不一致

key不一致主要分为以下几种情况:

  • lack_target : key存在于源库,但不存在于目的库。
  • type: key存在于源库和目的库,但是类型不一致。
  • value: key存在于源库和目的库,且类型一致,但是value不一致。
  • value不一致
不同数据类型有不同的对比标准:
  • string: value不同。
  • hash: 存在field,满足下面3个条件之一:
  • field存在于源端,但不存在与目的端。
  • field存在于目的端,但不存在与源端。
  • field同时存在于源和目的端,但是value不同。
  • set/zset:与hash类似。
  • list: 与hash类似。

field冲突类型有以下几种情况(只存在于hash,set,zset,list类型key中)

  • lack_source: field存在于源端key,field不存在与目的端key。
  • lack_target: field不存在与源端key,field存在于目的端key。
  • value: field存在于源端key和目的端key,但是field对应的value不同。

参考资料

标签:实战,full,--,Redis,redis,value,key,迁移,check
From: https://blog.51cto.com/alex4dream/6000209

相关文章

  • 【Redis 技术探索】「数据迁移实战」手把手教你如何实现在线 + 离线模式进行迁移 Redi
    在线数据迁移方式对于大多数场景下的Redis的数据迁移,还是比较推荐大家参考我之前的前两篇文章。【Redis技术探索】「数据迁移实战」手把手教你如何实现在线+离线模......
  • 我的新书《Flink大数据分析实战》出版啦
    本书基于Flink1.13.X最新版本编写,作为Flink的入门书,主要使用函数式编程语言Scala进行讲解,知识面比较广,涵盖了当前整个Flink生态系统主流的大数据开发技术。内容全面,以实操案......
  • Redis基本讲解
    前言1.什么是Redis?它主要用来什么的?Redis,英文全称是RemoteDictionaryServer(远程字典服务),是一个开源的使用ANSIC语言编写、支持网络、可基于内存亦可持久化的日志型、K......
  • Redis-单机数据库-数据库键空间
    Redis是一个键值对(key-valuepair)数据库服务器,服务器中的每个数据库都由一个 redis.h/redisDb 结构表示,其中, redisDb 结构的dict 字典保存了数据库中的所有键值对,......
  • Redis的String类型,原来这么占内存
    Redis的String类型,原来这么占内存存一个Long类型这么占内存,Redis的内存开销都花在哪儿了?1、场景介绍假设现在我们要开发一个图片存储系统,要求这个系统能够根据图片......
  • SimpleAdmin手摸手教学之:Redis缓存
    一、说明系统中有很多数据是不会经常修改的,但是读取的频率确很高,所以这时候就需要使用缓存将这些数据缓存起来。本系统采用Redis分布式缓存,将一些基本信息表缓存在内存中,......
  • 迁移学习(IIMT)——《Improve Unsupervised Domain Adaptation with Mixup Training》
    论文信息论文标题:ImproveUnsupervisedDomainAdaptationwithMixupTraining论文作者:ShenYan,HuanSong,NanxiangLi,LincanZou,LiuRen论文来源:arxiv2020论文......
  • Redis-数据结构与对象-对象
    对象Redis并没有直接使用这些数据结构来实现键值对数据库,而是基于这些数据结构创建了一个对象系统,这个系统包含字符串对象、列表对象、哈希对象、集合对象和有序集合对......
  • Knowage迁移教程
    1.将老机器的webapp目录备份2.老机器的数据库备份3.新机器安装MYSQL4.新机器安装knowage包5.新机器执行汉化6.将老机器的webapp替换到新机器7.将数据库覆盖式的导入到新机器......
  • Redis 数据结构-简单动态字符串
    Redis数据结构-简单动态字符串 无边落木萧萧下,不尽长江滚滚来。 1、简介Redis之所以快主要得益于它的数据结构、操作内存数据库、单线程和多路I/O......