首页 > 首页 > 数据库 > 非关系型数据库 > Redis > 01-Redis运维必备工具之:RedisShake
2024
06-03

01-Redis运维必备工具之:RedisShake

RedisShake 简介

RedisShake 基本介绍

RedisShake是基于redis-port基础上进行改进的是一款开源的Redis迁移工具,支持Cluster集群的在线迁移与离线迁移(备份文件导入)。数据可平滑迁移,当部署在其他云厂商Redis服务上的Cluster集群数据,由于SYNC、PSYNC命令被云厂商禁用,无法在线迁移时,可以选择离线迁移。

RedisShake 使用背景

RedisShake是一个用于在两个Redis实例之间同步数据的工具,满足非常灵活的同步与迁移需求。Redis实例之间的关系其中可能存在(standalone->standalone),(standalone->Cluster),(Cluster->Cluster)等。目前,比较常用的一个数据迁移工具是Redis-Shake ,这是阿里云Redis和MongoDB团队开发的一个用于 Redis 数据同步的工具。

Redis-Shake 特性概览

  • 高性能:全量同步阶段并发执行,增量同步阶段异步执行,能够达到毫秒级别延迟(取决于网络延迟)。同时,我们还对大key同步进行分批拉取,优化同步性能。
  • 在 Redis 5.0、Redis 6.0 和 Redis 7.0 上测试
  • 支持使用lua自定义过滤规则
  • 支持大实例迁移
  • 支持restore模式和sync模式
  • 支持阿里云 Redis 和 ElastiCache
  • 监控体系:用户可以通过我们提供的restful拉取metric来对redis-shake进行实时监控:curl 127.0.0.1:9320/metric。
  • 数据校验:如何校验同步的正确性?可以采用我们开源的redis-full-check。
  • 支持版本:支持2.8-5.0版本的同步,此外还支持codis,支持云下到云上,云上到云上,云上到云下(阿里云目前支持主从版),其他云到阿里云等链路,帮助用户灵活构建混合云场景。
  • 断点续传。支持断开后按offset恢复,降低因主备切换、网络抖动造成链路断开重新同步拉取全量的性能影响。
01-Redis运维必备工具之:RedisShake - 第1张  | 架构迷

Redis 主从同步原理

Redis 持久化

Redis有两种持久化机制:RDB和AOF。

RDB是一个经过压缩的二进制文件,通过保存Redis数据库中的键值来记录数据库状态。

01-Redis运维必备工具之:RedisShake - 第2张  | 架构迷

AOF通过保存Redis服务器所执行的写命令来记录数据库状态,例如:

01-Redis运维必备工具之:RedisShake - 第3张  | 架构迷

RDB和AOF文件可以恢复成一个数据库,继续提供服务。

  • Replication

复制:包括全量数据的复制和增量数据的复制。

同步操作:将从服务器的数据库状态更新至主服务器当前所处的数据库状态。Master生成RDB文件,Slave载入。

命令传播操作:主服务器的数据库状态被修改,导致主从服务器的数据库状态出现不一致时,让主从服务器的数据库重新回到一致状态。 Master执行的写命令传送到Slave。

Redis 主从复制

在分布式环境中,数据副本 (Replica) 和复制 (Replication) 作为提升系统可用性和读写性能的有效手段被大量应用系统设计中,Redis也不例外。

01-Redis运维必备工具之:RedisShake - 第4张  | 架构迷

在2.8版本之前,主从同步是通过SYNC命令进行的,在2.8版本之后升级到PSYNC命令,下面分别展开介绍。

主从复制 - SYNC

01-Redis运维必备工具之:RedisShake - 第5张  | 架构迷

在发送slaveof ip port的时候,它首先会创建两项主服务器套接字的连接,接着向主服务器发送ping命令,目的在于检查套接字的读写状态,或者是检查主服务器是否能够正常地处理命令。

接下来进行身份验证,然后发送端口信息,最后发送SYNC命令,执行同步操作。

01-Redis运维必备工具之:RedisShake - 第6张  | 架构迷

在主Master接收到SYNC命令之后,它会执行bgsave在后台生成一个RDB文件,并且使用一个缓冲区记录从现在开始执行所有写命令。当bgsave生成的RDB文件完成了之后,它就发送给从服务器去进行载入。在更新状态完成之后,Master再将记录在缓冲区里面的新命令发送给从服务器,这样从服务器进行执行,主从服务器就保持了一致状态。

  • SYNC缺陷
01-Redis运维必备工具之:RedisShake - 第7张  | 架构迷

从服务器到主服务器的复制可以分为两种情况,一种就是初次复制,一种就是断线后的重复制。初次复制就是进行建立连接,然后进行全量和增量的同步,它的SYNC可以很好地完成任务。

但对于断线后的重复制,处于命令传播阶段的主从服务器因为网络原因而中断又重连,会再次发送SYNC命令做全量+增量同步,效率较低。

SYNC命令是一个非常耗费资源的操作,资源包括CPU、内存、磁盘、宽带、流量等。

主从复制 - PSYNC

为了解决SYNC在处理断线重复制时候的低效问题,Redis从2.8版本之后开始使用PSYNC命令,它支持完整重同步和部分重同步。

完整重同步和SYNC一样,部分重同步就是在处理断线重新链接之后,主节点只向从节点发送链接断开期间的写命令,它的实现基于以下三部分:

1)复制偏移量(replication offset)

n  Master:每次向Slave发送n个字节数据时,就会将自己的offset+n;

n  Slave:每次收到Master发送来的n个字节数据时,就会将自己的offset+n;

n  如果主从服务器处于一致状态,那么Master和Slave的Offset总是相同的。

01-Redis运维必备工具之:RedisShake - 第8张  | 架构迷

2)复制积压缓冲区(replication backlog)

  • Master上维护的每一个固定大小(fixed-size)的FIFO队列,保存着一部分最近传播的写命令。
  • Master进行命令传播时,不仅会将命令发送给所有Slave,还会将写命令入队到复制积压缓冲区。
  • 复制积压缓冲区会为队列中的每个字节记录相应的复制偏移量;
  • Slave重连Master时,会通过PSYNC命令将自己的Offset发送给Master,如果Slave的Offset与Master的Offset不相等,并且Slave的Offset偏移量之后的数据仍存在于replication backlog中,那么Master将对Slave执行部分重同步操作;否则,需要执行完整重同步操作。
01-Redis运维必备工具之:RedisShake - 第9张  | 架构迷

3)服务器ID(run ID)

  • 每个Redis服务器,Master、Slave、都有run ID自动生成。
  • 当Slave对Master进行初次复制时,Master会将自己的run ID传送给Slave,Slave会记录Master的run ID。
  • 当Slave重新连接上一个Master时,会发送之前保存的run ID,用于确认是否为同一个Master。

1. PSYNC—fullresync

01-Redis运维必备工具之:RedisShake - 第10张  | 架构迷

过程如上图所示,抛去刚开始的建立连接不谈,对于初次复制,它会发送一个“PSYNC ? -1”命令,主动请求主服务器去进行完整的重同步。

01-Redis运维必备工具之:RedisShake - 第11张  | 架构迷

主服务器接收到命令之后会返回FULLRESYNC,表示执行完整重同步,下面的步骤就和SYNC是一样的。

2. PSYNC—partial resync

01-Redis运维必备工具之:RedisShake - 第12张  | 架构迷

当在增量阶段突然断线,它会再次建立连接。Slave向主服务器发送run ID和offset,run ID就是上一次复制的主服务器的运行ID,offset就是从服务器当前的复制偏移量。接收到命令之后,主服务器会通过这两个参数去判断,如果判断条件满足,就返回CONTINUE,之后发送缓冲区中的那些写命令再去执行,就回到了一致的状态。

RedisShake 基本原理

主要功能

RedisShake主要是支持Redis的RDB文件的解析、恢复、备份、同步四个功能:

  • 恢复(restore):将 RDB 文件恢复到目标Redis数据库。
  • 备份(dump):将源 Redis 的全量数据通过RDB文件备份起来。
  • 解析(decode):读取 RDB 文件,并以 JSON 格式解析存储。
  • 同步(sync):支持源redis和目的redis的数据同步,支持全量和增量数据的迁移,支持从云下到阿里云云上的同步,也支持云下到云下不同环境的同步,支持单节点、主从版、集群版之间的互相同步
  • 同步(rump):支持源 Redis 和目的 Redis 的数据同步,仅支持全量迁移。采用scan和restore命令进行迁移,支持不同云厂商不同redis版本的迁移。

注意:如果源端是集群版,可以启动一个RedisShake,从不同的db结点进行拉取,同时源端不能开启move slot功能;对于目的端,如果是集群版,写入可以是1个或者多个db结点。

基本同步模式

01-Redis运维必备工具之:RedisShake - 第13张  | 架构迷

基本同步模式流程图

  • 支持的Redis形态:

1)Standalone:单源拉取,主从版/单节点

2)Sentinel:从Sentinel获取地址并拉取

3)Cluster:开源Cluster模式

4)Proxy:从Proxy拉取

下面举例说明:

01-Redis运维必备工具之:RedisShake - 第14张  | 架构迷

现在要将一个主从版的数据迁移到集群版,可以在配置文件中配置源端信息和目的端信息,同时在配置地址的时候,对于集群版可以配置一个分片的地址,因为它是支持自动发现的。

数据流图

01-Redis运维必备工具之:RedisShake - 第15张  | 架构迷

上图是SYNC模式下全量+增量的数据流图,第一次复制向源端发送了之后,源端给它发RDB文件,解析RDB文件放到Pipe中。

它可以通过并发Restore到目的端,同步完成之后就会自动启动增量。增量就是从源端拉取写命令,进行解析过滤,然后再放到目的端,同时还需要接收回复。

全量同步

01-Redis运维必备工具之:RedisShake - 第16张  | 架构迷

首先可以看全量同步,DbSyncer维护了连接链路,它是一个结构体,源端是6379,目的端是一个集群,它代表了一个数据链路。

假如说原来配置的是一个三主三从的集群模式,那么就会开启三个DbSyncer,同时有ID对它进行标识。每个DbSyncer管理一个连接,如6379首先是向RDB文件发送过来,然后Loader会解析出一些信息,包括DB、Key、Type等,然后放到Pipe中。然后需要向目的端写入,写入的时候全量模式支持并发。

从Pipe出来后先进行过滤,因为RedisShake支持DB、Key、Slot这些级别的过滤,用户可以设置黑白名单。正常情况下就可以Restore到目的端,然后再接收回复。对于lua ,可以进行script load,也可以设置过滤lua。对于BigKey,需要根据编码形式进行拆分解析。

增量同步

01-Redis运维必备工具之:RedisShake - 第17张  | 架构迷

全量同步结束之后会自动开启增量同步,增量同步主要是由四个协程完成。

第一个协程定期从源端获取RedisShake的偏移量。

第二个协程主要是从源端拉取写命令。因为原来是模拟源端的一个从,从执行写命令的时候会发送一条Binlog到RedisShake,RedisShake读到之后交给Decoder,然后会将Binlog解析成一个原生命令,同时还会计算一下偏移量。得到命令后有Key,然后就可以进行过滤,再放到Sendbuffer中,Sendbuffer就是最终要发送到目的端的一些写命令。

第三个协程就是Sender,它执行发送逻辑,从Sendbuffer中取出写命令,并不是立即发送过去,它是和Checkpoint绑成一个事务,一块写入目的端。断点续传的原理是会先放到cache里边,就像是一层缓存,然后触发一定条件之后就去执行sendFunc函数。这是一个事务,它会先去写这些增数据,然后再去修改Checkpoint值。

第四个协程就是接收目的端的回复,可能是写入成功,也可能是写入出错的,主要用于统计。

下面我们模拟发送一个命令,观察会发生什么事情。

01-Redis运维必备工具之:RedisShake - 第18张  | 架构迷

首先源客户发送了一个“SET msg hello”,然后源端会以一个Binlog的形式写入到RedisShake。RedisShake读到之后先解析出原生的写命令,就会调用Send函数。Send函数目的端是一个集群,它需要知道自己应该发送到哪个节点上。

因为集群方式有槽概念,RedisShake还维护了 Slot数组,它的 index就是槽的ID,它对应的值就是槽所在的节点上。Node是一个结构体,里边有一个字段address,就是节点的地址。

调用Send函数的时候,首先需要获取到这个Key是应该发送到哪个节点上,会调用getNodeByKey,实际上就是对Key进行一次Hash,调用的是crc16算法。Key会算到它在哪个槽上,然后再通过下面 Slots数组,就知道这个槽是在哪个节点上,然后再调用do把它写入到 node上,写入之后会Receive目的端的回复。然后我们就需要去检查这个回复是什么,如果是有异常的话,就会直接将这个结果返回过去,再由上一层去进行判断。

假如说是move或者是ask,可能会调用回调函数handleMove或handleAsk两个重定向。

MOVE/ASK重定向

1.MOVE重定向

01-Redis运维必备工具之:RedisShake - 第19张  | 架构迷

上图为MOVE重定向流程图,因为RedisShake是模拟一个客户端,然后RedisShake向节点写命令时,这个节点也会进行一次Hash去看它是不是应该在写到自身。如果是的话就执行,不是的话就返回一个MOVE。

这个MOVE代表这个Key应该写到这个节点上,因为目的端可能会进行扩容,所以说槽的分布可能是会有变化,RedisShake支持进行扩缩容。收到MOVE的时候,它会提取到目标节点的信息,再向目标节点重新发送键命令。

2.ASK重定向

01-Redis运维必备工具之:RedisShake - 第20张  | 架构迷

上方为ASK重定向流程图,主要是发生在Slots迁移的时候,RedisShake向A节点发送键命令的时候,A在同一向里回复一个ASK转向,表示这一次向B去写入,然后RedisShake再向B发送键命令。

断点续传原理

断点续传是RedisShake2.0版本增加的功能,是根据Redis PSYNC协议写的,下方是它的流程图。

01-Redis运维必备工具之:RedisShake - 第21张  | 架构迷

如上图所示,目的端开启了断点续传,获取到Checkpoint保存的最大偏移量,然后通过PSYNC指令发送源端,然后在源端去检查是否合法。

如果需要的写指令还在复制缓存区中,它就会回复一个Continue,然后进入增量同步,如果不是的话就会进行全量同步。

主从版的断点续传方案会在每个节点DB上记录一个Checkpoint,名字固定是RedisShake Checkpoint,类型是Hash。

01-Redis运维必备工具之:RedisShake - 第22张  | 架构迷

在写数据的时候,Redis是将Checkpoint和数据捆绑成一个事务写入目的端的。

  • 讨论两个问题:

1)为什么每个逻辑DB都记录一个Checkpoint?

2)为什么要将Checkpoint和数据捆绑成一个事务写入目的Redis端?

关于问题一,分DB存储的优势就是在刚启动的时候,只需要拉取所有DB的offset,挑取最大的就知道它是在哪个DB上,上一次是在哪个DB,以及同步的最大偏移量。

关于问题二,捆绑封装成一个事务是为了保证一致性。

应用场景

数据同步——SYNC

01-Redis运维必备工具之:RedisShake - 第23张  | 架构迷

在SYNC模式下支持全量同步与增量同步,当然它有一个限制,需要源端支持PSYNC/SYNC,在向源端发送SYNC/PSYNC命令的时候,可以收到源端的回复。源端、目的端的形态可以是主从集群/Proxy/Cluster,迁移也可以用于云下到云上,云上到云下这种混合云迁移。

多云厂商之间数据迁移

对于某些云上redis,比如部分云厂商不支持SYNC/PSYNC权限,如何进行行迁移?

01-Redis运维必备工具之:RedisShake - 第24张  | 架构迷

RedisShake对于这种场景也做了支持,比如绕过SYNC和PSYNC的同步方式。它是以Scan的方式从源端Redis获取到全量数据,再写入到目的端,实现数据迁移。

比如有一个fetcher,它会先Scan一定的数据量, 然后配置COUNT,然后将收到的Key给DUMP下来放到PIPE中,然后writer从PIPE中取到Restore到目的端,同时它也有BigKey的优化。

多活

多活通常是用于解决因地域网络传输层面带来的问题,也就是异地多活。比如说业务层面想要在北京机房写入一条数据,要求在上海机房也能够读到,同样反过来也可以,这样会需要做到一个多活。

01-Redis运维必备工具之:RedisShake - 第25张  | 架构迷

上图给出来的是一个根据RedisShake创建多活的方案,是一种伪多活而不是真正的多活。

用户需要编写一个Proxy进行流量分发,比如对a或者是b库的写操作都分发在左边的DB,对c库的写操作都分发到右边的DB。RedisShake提供了按库过滤的功能,可以配置源库到目的库的Shake链路值,同步ab,然后目的库到源库的只同步c,这样就解决了一个环形复制的问题。

数据备份与恢复

01-Redis运维必备工具之:RedisShake - 第26张  | 架构迷

数据备份使用dump功能,就可以直接备份一份rdb,将这些rdb根据时间命名。

01-Redis运维必备工具之:RedisShake - 第27张  | 架构迷
  • 数据恢复restore
  • 自建Redis迁移上云
  • 云上数据迁移到云下
  • 将数据库恢复至之前的状态,数据回滚
  • 配合Filter使用,只恢复部分Key

RDB文件解析decode

  • RDB文件解析 decode

1)读取RDB文件,以JSON格式解析存储

2)可以进行Key分析

  • 高版本向低版本迁移

源端版本大于目的端版本,比如源端是4.0,目的端2.8,某些数据结构格式已经修改导致无法同步,可以通过配置绕过这个限制。

  • 扫描迁移 rump

以SCAN的方式从源端Redis获取全量数据,写入到目的端,实现数据迁移。

  • 对于不支持sync/psync权限的迁移
  • 跨云迁移

全球分布式缓存—全球级联同步场景

假如用户业务遍布全球,有很多个数据中心,之间的数据迁移也可以用RedisShake,它支持全球级联同步,方便用户进一步扩大自己的业务。

01-Redis运维必备工具之:RedisShake - 第28张  | 架构迷

检验迁移后的数据

01-Redis运维必备工具之:RedisShake - 第29张  | 架构迷

redis-full-check是用来检验两个Redis数据是否一致的工具。

通常在用RedisShake进行数据迁移之后,可以用这个工具进行校验,它的原理主要是通过全量对比源端和目的端Redis中的数据方式来进行数据校验。

如图可以看到,比较的方式是内部多轮次进行比较,每次比较都会先抓取比较Key。第一轮是从源端进行抓取,后面从Sqlite中进行抓取。抓取之后如果存在有差异的部分,会存在SqliteDB中,后面的抓取直接去更新Sqlite中的数据就可以了。

参考文档:

https://developer.aliyun.com/article/783138

https://www.cnblogs.com/liboware/p/17032487.html

最后编辑:
作者:摘星怪
这个作者貌似有点懒,什么都没有留下。

留下一个回复

你的email不会被公开。