实现在线 + 离线模式进行迁移 Redis 数据实战指南

目录
  • redis-full-check的使用背景
  • redis-full-check的基本介绍
  • 编译源码
  • 数据对比核心流程
  • 参数信息介绍
    • 对比结果差异分析不一致类型
    • key不一致
  • 参考资料

redis-full-check的使用背景

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

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

redis-full-check的基本介绍

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

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

开源地址redis-full-check源码地址: ​​https://github.com/aliyun/redis-full-check​

redis-full-check下载地址: ​​https://github.com/alibaba/RedisFullCheck/releases​

编译源码

运行 ./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中,用于下次比较。

数据对比核心流程

下图是基本的数据流图。

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

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

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

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

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

value不一致的string,重新比较key:从源和目的取key、value比较。value不一致的hash、set和zset,只重新比较不一致的field,之前已经比较且相同的filed不再比较。这是为了防止对于大key情况下,如果更新频繁,将会导致校验永远不通过的情况。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解压redis-full-check.tar.gz:tar -xvf redis-full-check.tar.gz执行如下命令进行数据校验:单机实例之间进行数据对比检测

./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不同。

参考资料

数据参数校验

redis-full-check中文文档

到此这篇关于实现在线 + 离线模式进行迁移 Redis 数据实战指南的文章就介绍到这了,更多相关迁移 Redis 数据实战内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Redis数据导入导出以及数据迁移的4种方法详解

    1.aof 导入方式. 因为这种方式比较简单,所以我就先介绍它. 分两步来实现,第一步先让源 Redis 生成 AOF 数据文件. # 清空上文目标实例全部数据 redis-cli -h 目标RedisIP -a password flushall # 源实例开启 aof 功能,将在 dir 目录下生成 appendonly.aof 文件 redis-cli -h 源RedisIP -a password config set appendonly yes dir 目录,可以通过 config

  • Redis migrate数据迁移工具的使用教程

    前言 在工作中可能会遇到单点Redis向Redis集群迁移数据的问题,但又不能老麻烦运维来做.为了方便研发自己迁移数据,我这里写了一个简单的Redis迁移工具,希望对有需要的人有用. 本工具支持: 单点Redis到单点Redis迁移 单点Redis到Redis集群迁移 Redis集群到Redis集群迁移 Redis集群到单点Redis迁移 该工具已经编译成了多平台命令,直接从Github下载二进制文件执行就好了. 项目地址: https://github.com/icowan/redis-too

  • Redis源码解析:集群手动故障转移、从节点迁移详解

    一:手动故障转移 Redis集群支持手动故障转移.也就是向从节点发送"CLUSTER  FAILOVER"命令,使其在主节点未下线的情况下,发起故障转移流程,升级为新的主节点,而原来的主节点降级为从节点. 为了不丢失数据,向从节点发送"CLUSTER  FAILOVER"命令后,流程如下: a:从节点收到命令后,向主节点发送CLUSTERMSG_TYPE_MFSTART包:          b:主节点收到该包后,会将其所有客户端置于阻塞状态,也就是在10s的时间内

  • php实现redis数据库指定库号迁移的方法

    本文实例讲述了php实现redis数据库指定库号迁移的方法,分享给大家供大家参考.具体如下: redis普通的数据库迁移,只能整个redis save,或者利用主从,当然也可以安装一个redis-dump,不过比较麻烦,这里提供一种php的脚本,实现指定库号的迁移,其实也就是遍历根据存储类型,读出来,插入新库,效果是这样: 复制代码 代码如下: [root@localhost ~]# php 1.php 1/407 101/407 201/407 301/407 401/407 PHP实例代码如

  • 从MySQL到Redis的简单数据库迁移方法

    从mysql搬一个大表到redis中,你会发现在提取.转换或是载入一行数据时,速度慢的让你难以忍受.这里我就要告诉一个让你解脱的小技巧.使用"管道输出"的方式把mysql命令行产生的内容直接传递给redis-cli,以绕过"中间件"的方式使两者在进行数据操作时达到最佳速度. 一个约八百万行数据的mysql表,原本导入到redis中需要90分钟,使用这个方法后,只需要两分钟.不管你信不信,反正我是信了. Mysql到Redis的数据协议 redis-cli命令行工具有

  • 实现在线 + 离线模式进行迁移 Redis 数据实战指南

    目录 redis-full-check的使用背景 redis-full-check的基本介绍 编译源码 数据对比核心流程 参数信息介绍 对比结果差异分析不一致类型 key不一致 参考资料 redis-full-check的使用背景 在经历了之前的文章内容章节内容,已完成Redis迁移后,可能会存在以下问题需要进行数据迁移之后的对比.例如,如果Redis迁移的过程出现异常,源端与目的端Redis的数据将会不一致. 在Redis迁移完成后进行数据校验可以检查数据的一致性,该如何校验就是我们本文的内容

  • redis-shake同步redis数据的实现方法

    目录 前言 redis shake 简介 基本功能 基本原理 环境准备 一.安装redis 二.redis shake使用步骤 前言 和很多同步工具一样,redis shake为同步redis数据而存在.在很多场景下,如果不使用同步工具,如果需要同步redis数据是一件相对繁琐的事情,可能需要编写代码,专门来做同步这件事,这就对开发提出了较高的要求,需要考虑到各种场景, 有了redis shake 之后,同步redis数据库数据变得容易了很多,其实我们可以猜想,它应该利用了解析redis的rdb

  • Laravel中数据迁移与数据填充的详细步骤

    前言 这是一篇基础教程,对标 Laravel 文档中的数据迁移和数据填充,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍把. 关于Laravel数据库迁移的理解 最初看到laravel框架中迁移的时候,会以为这个迁移是把数据从一个数据库中迁到另一个数据库中,又或者是从一个服务器迁移到另一个服务器中.我自己学习有一个学习方法叫做顾名思义,所以所述是我的第一反应,但是学了以后发现这个迁移不是我理解中的迁移,但又不知道为什么叫做迁移,所以去百科查了一下. 迁移是指已经获得的知识.技能,甚

  • 基于C# 写一个 Redis 数据同步小工具

    概念 Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorted set --有序集合)和hash(哈希类型).在此基础上,redis支持各种不同方式的排序.与memcached一样,为了保证效率,数据都是缓存在内存中.区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文

  • 为什么断电后Redis数据不会丢失

    目录 前言 Redis 持久化机制 RDB 持久化机制 RDB 机制触发条件 自动触发 RDB 机制相关配置文件 RDB 机制优点 RDB 机制缺点 AOF 持久化机制 AOF 机制如何开启 AOF 机制数据是否实时写入磁盘 AOF 文件重写 AOF 重写缓冲区 AOF 机制触发条件 AOF 机制机制优点 AOF 机制机制缺点 总结 前言 Redis 作为一款内存数据库,被广泛使用于缓存,分布式锁等场景,那么假如断电或者因其他因素导致 Reids 服务宕机,在重启之后数据会丢失吗? Redis

  • 解决 Redis 数据倾斜、热点等问题

    目录 什么是数据倾斜? 数据倾斜有哪些原因呢? 1.存在大key 2.HashTag 使用不当 3.slot 槽位分配不均 Redis 作为一门主流技术,应用场景非常多,很多大中小厂面试都列为重点考察内容 前几天有星球小伙伴学习时,遇到下面几个问题,来咨询 Tom哥 考虑到这些问题比较高频,工作中经常会遇到,这里写篇文章系统讲解下 问题描述: 1.如果redis集群出现数据倾斜,数据分配不均,该如何解决? 2.处理hotKey时,为key创建多个副本,如k-1,k-2…, 如何让这些副本能均匀写

  • redis数据的两种持久化方式对比

    一.概念介绍 redis提供了两种持久化的方式,分别是RDB(Redis DataBase)和AOF(Apend Only File). RDB方式 RDB方式是一种快照式的持久化方法,将某一时刻的数据持久化到磁盘中. •redis在进行数据持久化的过程中,会先将数据写入到一个临时文件中,待持久化过程都结束了,才会用这个临时文件替换上次持久化好的文件.正是这种特性,让我们可以随时来进行备份,因为快照文件总是完整可用的. •对于RDB方式,redis会单独创建(fork)一个子进程来进行持久化,而

  • 简单粗暴的Redis数据备份和恢复方法

    示例 目标:把服务器CentOS上的redis数据复制到Mac机上 步骤: 在CentOS上找dump文件位置 vi /etc/redis.conf dbfilename dump.rdb dir /var/lib/redis 说明文件在 /var/lib/redis/dump.rdb 在mac上查找dump文件位置 vi /usr/local/etc/redis.conf dbfilename dump.rdb dir /usr/local/var/db/redis 拷贝服务器上的dump.r

  • C++开发的Redis数据导入工具优化

    背景 使用C++开发了一个Redis数据导入工具 从oracle中将所有表数据导入到redis中: 不是单纯的数据导入,每条oracle中的原有记录,需要经过业务逻辑处理, 并添加索引(redis集合): 工具完成后,性能是个瓶颈: 优化效果 使用了2个样本数据测试: 样本数据a表8763 条记录: b表940279 条记录: 优化前,a表耗时11.417s: 优化后,a表耗时1.883s: 用到的工具 gprof, pstrace,time 使用time工具查看每次执行的耗时,分别包含用户时间

随机推荐