redis-port支持前缀迁移
一、介绍
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
// 解析 sourcePrefix 前缀
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:
看下实例B中的数据:
可以看到只有order前缀的数据才迁移过来了。
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Docker六脉神剑(一) Mac极速体验
- React-Router 5.0 制作导航栏+页面参数传递
- Vue3.0快速入门(速查)
- 憧憬博客Nginx到Tengine的迁移
- SpringCloud微服务构建浅析
- 宋宝华:Linux设备与驱动的手动解绑与手动绑定
- ELK7.x日志系统搭建 1. elk基础搭建
- 腾讯云直播开发日记 (二)附近直播-直播礼物-直播回放
- 腾讯云直播开发日记(三) 聊天室-直播转码-连麦混流
- c#类(class)
- es 7.2 生产集群 index 无数据写入故障定位
- HashMap都在用,原理你真的了解吗?
- Android必知必会--事件分发机制
- 又被逼着优化代码,这次我干掉了出入参 Log日志
- C#委托进阶,事件和委托,一次就看明白,附源码