一、介绍

redis-port是一款redis数据迁移工具,用来将数据从一个redis迁移到另一个redis实例/redis集群中 ,以下是官方地址:

https://github.com/CodisLabs/redis-port

使用也是非常的简单:

/redis-port sync -f 127.0.0.1:6379 -t 127.0.0.1:6380 -n 8

上述命令将127.0.0.1:6379这个redis实例的数据迁移到 127.0.0.1:6380 中。

我们在生产上迁移了多个redis集群的数据,运行非常稳定。

最近有这么一个场景:只迁移指定前缀的key,因为一个redis集群有好几个应用在用,如果全部都迁,时间太长,占的内存也比较大。

二、改造过程

我们先整理下redis-port的工作流程:

1、伪装一个从,向主redis 发起同步请求;

2、主redis将当前数据以rdb发送给redis-port;

3、redis-port解析rdb文件,然后1条1条的向目标redis写入数据;

4、接收主redis发送过来的增量命令,发往目标redis。

所以如果要改造的话,需要修改3和4两处,当然了还得增加参数解析的代码,具体步骤如下:

1、先修改cmd/flags.go 增加前缀的参数:

type Flags struct {
Source, Target string //过滤前缀,即只迁移这个前缀的key
SourcePrefixs []string AofPath string
TmpFile struct {
Path string
Size int64
}
ExpireOffset time.Duration
}

  

其中SourcePrefixs为新加的字段,类型为一个字符串数组,因为前缀可能有多个。

2、修改cmd/flags.go解析参数函数parseFlagsFromArgs

  for _, key := range []string{"--sourcePrefix"} {
var prefix string
if s, ok := d[key].(string); ok && s != "" {
prefix = s
} //通过,分隔
flags.SourcePrefixs = strings.Split(prefix, ",")
}

3、修改cmd/libs.go,增加判断key是否包含指定前缀的函数

func strHasPrefix(key string, sourcePrefix []string)  bool{
if len(sourcePrefix) < 1 {
return true
} var hasPrefix bool
hasPrefix = false
for i := 0; i < len(sourcePrefix); i++{
if (strings.HasPrefix(key, sourcePrefix[i])) {
hasPrefix = true
break
}
} return hasPrefix
}

  

4、修改cmd/libs.go处理rdb文件的函数genRestoreCommands增加相应逻辑

//过滤非前缀的key
if (strHasPrefix(e.Key.String(), sourcePrefix) != true) {
log.Debug(e.Key.String() + " has no prefix: ignore it")
return
}

doRestoreDBEntry增加sourcePrefix参数

func doRestoreDBEntry(entryChan <-chan *rdb.DBEntry
, targetPrefix string, sourcePrefix []string, addr, auth string, on func(e *rdb.DBEntry) bool) {

5、修改cmd/libs.go回放aof文件函数doRestoreAoflog

func doRestoreAoflog(reader *bufio2.Reader, targetPrefix string, sourcePrefix []string, addr, auth string, on func(db uint64, cmd string) bool) {

//省略一些代码

//如果前缀不为空,则判断是否为这个前缀
if (len(r.Array) > 1) {
var key= string(r.Array[1].Value)
if strHasPrefix(key, sourcePrefix) != true {
continue
}
} //后续逻辑处理
}

6、在入口cmd/sync.go增加参数声明

Options:
-n N, --ncpu=N Set runtime.GOMAXPROCS to N.
-m MASTER, --master=MASTER The master redis instance ([auth@]host:port).
-t TARGET, --target=TARGET The target redis instance ([auth@]host:port).
--sourcePrefix=SP filter source key use prefix, separte with, .
--db=DB Accept db = DB, default is *.
--tmpfile=FILE Use FILE to as socket buffer.

再make编译下,可以试下效果:

开两个redis实例,实例A为6379端口,实例B为6380端口,实例A数据如下:

执行redis-sync:

可以看到只有order前缀的数据才迁移过来了。

Redis迁移工具redis-port使用&代码分析

扩展Redis:增加Redis命令

更多精彩文章,请关注公众号:

redis-port支持前缀迁移的更多相关文章

  1. 用redis实现支持优先级的消息队列

    http://www.cnblogs.com/tianqiq/p/4309791.html http://www.cnblogs.com/it-cen/p/4312098.html http://ww ...

  2. Redis删除相同前缀的key

          如何优雅地删除Redis set集合中前缀相同的key?       Redis中有删除单条数据的命令DEL,却没有批量删除特定前缀key的指令,但我们经常遇到需要根据前缀来删除的业务场景 ...

  3. Redis01——Redis究竟支持哪些数据结构

    Redis已经越来越多地应用到互联网技术中,而关于Redis的相关问题,也成为面试中必不可少的一部分,本文开始将会逐渐把我了解到的关于Redis的一些面试问题整理出来,供各位参考,如有不对之处,烦请指 ...

  4. php redis 获取指定前缀的所有key

    php redis 获取指定前缀的所有key 以laravel框架为例: $key = $this->redis->keys('db:shipping:shippingId:' . &qu ...

  5. Redisson使用起来很方便,但是需要redis环境支持eval命令

    Redisson使用起来很方便,但是需要redis环境支持eval命令,否则一切都是悲剧,比如me.结果还是要用RedisCommands去写一套.例子就如下,获得一个RLock锁对象,然后tryLo ...

  6. 从ASM迁移到ARM(1):平台支持的迁移服务

    Azure上的ARM模式为用户带来更好的管理,更多新的特性,更好的体验,因此目前正在使用经典模式(ASM)的用户,在了解和使用了ARM之后,也在考虑如何将原来基于ASM模式的虚拟机,存储,网络等IAA ...

  7. Redis所支持的数据结构

    1.启动Redis2.Redis所支持的数据结构 2.1.Redis常用操作 2.2.String类型及操作 2.3.Hash类型及操作 2.4.List类型及操作 2.5.Set类型及操作 2.6. ...

  8. Android 支持库迁移到AndroidX

    一.背景 Android系统版本在不断更新,从最初的Android 1.0到现在Google和各大手机厂商正在推的Android 10,平均下来每个年头都有一个大的版本更新.但用户正在用的手机上的An ...

  9. redis不支持多个数据库实例但是支持多个字典

    Redis多个数据库 注意:Redis支持多个数据库,并且每个数据库的数据是隔离的不能共享,并且基于单机才有,如果是集群就没有数据库的概念. Redis是一个字典结构的存储服务器,而实际上一个Redi ...

随机推荐

  1. excel如何写宏?如何用按钮?

    注:本次测试版本 excel版本2019 写宏? 准备工作(使用宏的一切前提)===========文件-选项-自定义功能区 (勾选开发工具) 开始写宏=======右击sheet1--查看代码    ...

  2. Mybatis_day2

    二 mybatis配置详解 MyBatis最关键的组成部分是SqlSessionFactory,我们可以从中获取SqlSession, 并执行映射的SQL语句.SqlSessionFactory对象可 ...

  3. 如何在Linux上使用xargs命令

    大家好,我是良许. 在使用 Linux 时,你是否遇到过需要将一些命令串在一起,但是其中一个命令不接受管道输入的情况呢?在这种情况下,我们就可以使用 xargs 命令.xargs 可以将一个命令的输出 ...

  4. 区块链入门到实战(6)之区块链 – 哈希(Hash)

    密码学中,最重要的函数之一是哈希函数.哈希函数将任意大小的数据(内容)映射到固定大小的数据(哈希值). 哈希函数是单向的,从内容生成哈希值很容易,但从哈希值映射到内容很难. 比特币使用SHA-256哈 ...

  5. Element UI - DatePicker 自定义日期选择期间

    <el-date-picker v-else v-model="searchForm.data_Selected" type="daterange" un ...

  6. Spark RDD中Runtime流程解析

    一.Runtime架构图 (1)从Spark  Runtime的角度讲,包括五大核心对象:Master.Worker.Executor.Driver.CoarseGrainedExecutorBack ...

  7. Google解析Json库Gson

    1.资料 官网: http://groups.google.com/group/google-gson 代码: https://github.com/google/gson jar包下载: http: ...

  8. Mysql 部署

    设置 path 环境变量 C:\mysql\mysql-5.7.17-winx64\bin; 创建C:\mysql\mysql-5.7.17-winx64\my.ini 内容如下 [mysql] # ...

  9. windows环境下利用Gitblit搭建Git服务器并实现自动部署Web站点目录

    Git服务搭建多见于linux环境,但windows主机也不少,目前网上文章诸多不全,且以讹传讹,不甚清楚.下面介绍windows环境下的自动部署和发布. 所需环境及资源:Java环境.Gitblit ...

  10. Codeforces 1337D Xenia and Colorful Gems

    题意 给你3个数组\(a, b\)和\(c\),最小化\((x-y)^2+(y-z)^2+(z-x)^2\),其中\(x \in a, y \in b, z \in c\). 解题思路 这题其实第一眼 ...