Redis Migrate Tool (RMT) 是唯品会(Vipshop)开发的一款高性能Redis数据迁移工具,支持多种Redis部署模式间的数据迁移,包括单实例、Twemproxy、Redis集群以及从RDB/AOF文件加载数据
RMT工具概述
RMT具有以下核心特性:
- 高速多线程迁移
- 基于Redis复制协议
- 在线迁移(源Redis可持续服务)
- 异构迁移(支持不同Redis部署模式间转换)
- 支持Twemproxy和Redis集群
- 迁移状态实时查看
- 数据验证机制
AOF迁移配置示例
AOF迁移的典型配置如下:
[source]
type: aof file
servers:
- /data/redis/appendonly1.aof
- /data/redis/appendonly2.aof
[target]
type: redis cluster
servers:
- 127.0.0.1:7379
[common]
listen: 0.0.0.0:8888
step: 2
此配置表示从多个AOF文件加载数据并迁移到Redis集群。
AOF迁移实现原理
RMT的AOF迁移实现涉及以下关键流程:
1. 初始化阶段
// rmt.c中加载配置并初始化上下文
int init_context(struct instance *nci) {
// 加载配置文件
nci->conf = conf_create(nci->conf_filename);
// 初始化核心组件
core_init();
}
// 触发迁移流程
void core_start() {
// 调用迁移主函数
redis_migrate();
}
2. 迁移启动阶段
// rmt_core.c中创建Redis组
static void redis_migrate() {
// 创建源组
source_group = source_group_create();
// 确定读写线程数量(读线程占20%)
read_threads = total_threads * 0.2;
write_threads = total_threads - read_threads;
// 根据配置创建Redis组对象
group_create_from_option(option);
}
对于AOF文件源,RMT会:
- 将source_type设置为GROUP_TYPE_AOF_FILE
- 解析配置中的AOF文件路径
- 为每个AOF文件创建处理结构
3. AOF解析与数据迁移流程
AOF迁移的关键流程包括:
// 1. 读取AOF文件
int aof_reader_start() {
// 打开AOF文件
fd = open(aof_path, O_RDONLY);
// 创建AOF解析器
aof_parser = aof_parser_create();
// 开始解析过程
aof_parse_commands();
}
// 2. 解析AOF命令
int aof_parse_commands() {
while ((cmd = aof_parser_next_command()) != NULL) {
// 将AOF命令转换为内部命令结构
rmt_command = convert_aof_to_command(cmd);
// 将命令加入处理队列
enqueue_command(rmt_command);
// 通知写线程处理
notify_write_thread();
}
}
// 3. 写线程处理
void writeThreadCron() {
// 监听通知管道
if (pipe_readable()) {
// 从队列获取命令
cmd = dequeue_command();
// 发送到目标Redis
send_data_to_target(cmd);
// 接收目标响应
recv_data_from_target();
}
}
4. 写线程同步机制
从提供的信息可以看出,RMT使用管道通信机制在读线程和写线程之间传递同步请求:
// 写线程主循环
void *writeThreadMain() {
while (!stop) {
// 等待管道中的通知
event_wait(pipe_event);
// 从链表获取要发送的数据
data = list_pop_front(pending_data);
// 发送数据到目标
send_data_to_target(data);
// 接收目标响应
recv_data_from_target();
}
}
数据流和内存管理
AOF迁移过程中的数据流如下:
- AOF文件读取 → 文件内容被读入内存
- AOF解析 → 解析AOF格式,提取有效Redis命令
- 命令队列 → 解析后的命令存储在内存队列中
- 写线程处理 → 从队列获取命令并发送到目标Redis
- 响应处理 → 接收目标Redis的响应并确认命令执行成功
为了高效处理大量数据,RMT在内存中使用链表结构暂存待处理的命令,并通过step参数控制批处理大小,平衡内存使用和性能。
与RDB迁移的区别
相比RDB迁移,AOF迁移具有以下特点:
- 命令级别迁移:AOF迁移是按命令重放,而RDB迁移是按对象复制
- 增量特性:AOF包含增量命令记录,可以捕获最新变更
- 处理逻辑不同:
- RDB:
rmtRedisRdbDataPost()
→ 解析RDB文件结构 → 转换为对象 - AOF: 直接解析命令文本 →
rmtRedisSlaveReadQueryFromMaster
→ 发送命令
- RDB: