一、介绍

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. JDK1.8源码学习-String

    JDK1.8源码学习-String 目录 一.String简介 String类是Java中最常用的类之一,所有字符串的字面量都是String类的实例,字符串是常量,在定义之后不能被改变. 二.定义 p ...

  2. realm数据库报错:Changing Realm data can only be done from inside a transaction.

    在编写realm数据库相关时: 代码: List<Student> delByStudent(String priNum){ RealmResults<Student> stu ...

  3. Jmeter 常用函数(8)- 详解 __MD5

    如果你想查看更多 Jmeter 常用函数可以在这篇文章找找哦 https://www.cnblogs.com/poloyy/p/13291704.html 作用 将指定的字符串 MD5 加密并返回,加 ...

  4. client-go workqueue demo

    链接地址:https://github.com/kubernetes/client-go [root@wangjq examples]# tree . ├── create-update-delete ...

  5. qemu-img check命令详解

    1.问题现象 生产环境上,对计算节点文件系统修复,导致某些虚机的镜像文件数据丢失,出现异常,最终造成虚机无法启动,查看对应计算节点的nova日志,报如下错误 nova-compute: File &q ...

  6. 使用Spring Cloud Config统一管理配置,别再到处放配置文件了

    1 前言 欢迎访问南瓜慢说 www.pkslow.com获取更多精彩文章! 可配置是一个成熟软件系统应该提供的特性,而配置管理对于大型系统就显得十分重要,特别是对于拥有多个应用的微服务系统.可喜的是, ...

  7. javascript 查找属性的过程

     当执行 一个对象赋值操作的时候  js引擎会怎样处理呢??? 例如  有个foo对象  ,要进行这个操作 foo.a=2 1, 首先会在foo对象中查找,如果不存在a属性,就会去原型链上面找,如果原 ...

  8. “路由大当家”OSPF的小秘密

    引入 OPSF是应用最广的路由协议,基本上,所有的IGP用到的都是OSPF,下面我们看看它的“小秘密” 优点: •没有跳数限制 •使用组播更新变化的路由和网络信息 •路由收敛速度较快 •以开销(Cos ...

  9. 超全Python IDE武器库大总结,优缺点一目了然!

    本文介绍了多个 Python IDE,并评价其优缺点.读者可以参考此文列举的 Python IDE 列表,选择适合自己的编辑器. 写 Python 代码最好的方式莫过于使用集成开发环境(IDE)了.它 ...

  10. android Studio(3.1) 常用快捷键

    说  明 快捷键 全部保存 Ctrl + S 最大话/最小化编辑器 Ctrl + Shift + F12 搜索内容(包括代码和菜单) 按两次Shift 查找 Ctrl + F 查找下一个 F3 查找上 ...