go-mysql-transfer 伪装从库实现 MySQL 到 Redis 数据同步(完整配置)
文章目录
- 一、go-mysql-transfer 安装与启动
- 1.1 Linux 下编译
- 1.2 Windows 下编译
- 1.3 配置 go-mysql-transfer
- 二、MySQL、Redis 环境准备
- 2.1 MySQL 配置(修改 mysqld.cnf 文件)
- 2.2 redis.conf 配置
- 三、MySQL 设置
- 3.1 测试表(SQL)
- 3.2 MySQL 主库状态查询与同步位置设置
- 四、数据同步测试
一、go-mysql-transfer 安装与启动
1.1 Linux 下编译
按照以下步骤编译并启动同步服务:
# 1. 开启 Go 模块支持(若未全局开启)
GO111MODULE=on
# 2. 克隆项目(备用仓库地址,确保可访问)
git clone https://gitee.com/mirrors/go-mysql-transfer.git
# 3. 设置 GOPROXY 加速依赖下载
go env -w GOPROXY=https://goproxy.cn,direct
# 4. 编译项目生成可执行文件
go build
# 5. 修改配置文件 app.yml(配置 MySQL、Redis 连接信息等,见下文)
# 6. 启动 go-mysql-transfer 同步服务
./go-mysql-transfer
本文用 windows 示范,Linux 下配置同理。
1.2 Windows 下编译
git clone https://gitee.com/mirrors/go-mysql-transfer.git
在 go-mysql-transfer 目录下,命令行编译:
cd go-mysql-transfer
go env -w GOPROXY=https://goproxy.cn,direct
go build
编译成功后,项目目录下会生成 go-mysql-transfer.exe 可执行文件(Windows 下默认带 .exe 后缀)。

1.3 配置 go-mysql-transfer
在 go-mysql-transfer 目录下,用编辑器打开 app.yml进行配置:

确保 MySQL 配置的 server_id 和 go-mysql-transfer 的 slave_id 不重复(如主库 server_id=1,从库 slave_id=1001)。

这里可以改为 false,避免加载 statics 文件(否则后面启动可能因文件缺失出错)

定义热点数据的规则(测试表user见下文):

同步策略用 lua 脚本写,这里开启:

在 go-mysql-transfer 目录下自行创建 lua 文件夹,以及 t_user.lua进行测试

t_user.lua 脚本内容如下:
local ops = require("redisOps") --加载redis操作模块local row = ops.rawRow() --当前数据库的一行数据,table类型
local action = ops.rawAction() --当前数据库事件,包括:insert、update、delete等if action == "insert" or action == "update" then -- 只处理插入和更新操作local id = row["id"] --获取ID列的值local key = "user:" .. idlocal name = row["name"] --获取name列的值local sex = row["sex"]local weight = row["weight"] --获取weight列的值local age = row["age"]ops.HSET(key, "id", id) -- 对应Redis的HSET命令ops.HSET(key, "name", name) -- 对应Redis的HSET命令ops.HSET(key, "sex", sex) -- 对应Redis的HSET命令ops.HSET(key, "weight", weight) -- 对应Redis的HSET命令ops.HSET(key, "age", age) -- 对应Redis的HSET命令-- ops.EXPIRE(key, 1800) -- 若需要设置过期时间可取消注释
elseif action == "delete" thenlocal id = row["id"]local key = "user:" .. idops.DEL(key)
end
二、MySQL、Redis 环境准备
2.1 MySQL 配置(修改 mysqld.cnf 文件)
进入 MySQL 配置文件的目录:
cd /etc/mysql/mysql.conf.d/

可以看到有两个MySQL配置文件,我们操作 mysqld.cnf
sudo vim mysqld.cnf
需要开启:

需开启二进制日志 binlog 并设置为 ROW 模式(保证行级变更同步的精准性),同时配置唯一 server_id(避免与 go-mysql-transfer 的 slave_id 冲突):
log-bin=/var/log/mysql/mysql-bin.log # 开启二进制日志
binlog-format=ROW # 选择 ROW 模式(记录行级数据变更)
server_id=1 # MySQL 复制所需的 server_id,需全局唯一

重启 MySQL:
sudo systemctl restart mysql.service
2.2 redis.conf 配置
允许远程机器连接 Redis,需调整 bind 配置:
# bind 127.0.0.1 -::1
# 注释掉原配置改为
bind 0.0.0.0
关闭保护模式(protected-mode 配置)
protected-mode no # 关闭保护模式,允许外部连接
保存配置然后启动 Redis:
redis-server redis.conf
三、MySQL 设置
3.1 测试表(SQL)
先创建 user 表,后面测试时再执行增删改操作(用于触发同步流程):
-- 若表已存在则删除
DROP TABLE IF EXISTS `user`;
-- 创建 user 表
CREATE TABLE `user` (`id` BIGINT,`name` VARCHAR (100),`weight` SMALLINT,`sex` VARCHAR (1),`age` INT8,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
3.2 MySQL 主库状态查询与同步位置设置
执行 SQL 查询 Master 状态(获取 binlog 文件名和偏移量):
show master status;

windows 命令行进入 go-mysql-transfer目录,快捷方式:文件资源管理器的地址栏中直接输入 cmd 或 powershell,然后按回车

假设查询结果为:日志名 mysql-bin.000002、偏移量 1350,则通过以下命令重置从数据库的同步起始位置:
go-mysql-transfer.exe -config app.yml -position mysql-bin.000002 1350
首次全量数据同步(将 MySQL 已有数据同步到 Redis):
go-mysql-transfer.exe -stock
如果是在 linux 下:
./go-mysql-transfer -config app.yml -position mysql-bin.000002 1350
./go-mysql-transfer -stock
此时表中还没有插入数据,所以导入数据0条。

四、数据同步测试
原理图:

Redis 和 MySQL 中都没有数据

运行 go-mysql-transfer:
go-mysql-transfer.exe

现在往 MySQL 中写入数据:
-- 插入、更新、删除测试数据
insert into `user` values (10001, 'gulu', 200, '0', 20);
update `user` set `age` = 21 where id = 10001;
delete from `user` where id = 10001;
Redis 中可以查到对应数据,说明数据已经通过伪装从库 go-mysql-transfer 同步到 Redis 中

