从Binlog到消息队列:构建可靠的本地数据同步管道(macOS本地部署Canal & RocketMQ并打通全流程)

canal 需要使用 jdk1.8(即Java 8),RocketMQ 支持 jdk 1.8+

📌 canal 是什么?

GitHub地址

canal [kə'næl] ,译意为水道/管道/沟渠,主要用途是基于 MySQL 数据库增量日志解析,提供增量数据订阅和消费

基于日志增量订阅和消费的业务包括

  • 数据库镜像
  • 数据库实时备份
  • 索引构建和实时维护(拆分异构索引、倒排索引等)
  • 业务 cache 刷新
  • 带业务逻辑的增量数据处理

📌 canal 在本地如何启动?

Canal 的工作原理是基于 MySQL 数据库的,它通过模拟 MySQL 从库(slave)的交互协议,将自己伪装成一个 MySQL 从库。为了理解这一机制,我们有必要先了解 MySQL 主从复制的基本原理:

  1. 主库(master) 将数据变更记录到二进制日志(binary log)中,这些记录被称为二进制日志事件(binary log events)。可以通过 SHOW BINLOG EVENTS命令查看这些事件。
  2. 从库(slave) 将主库的二进制日志事件复制到自己的中继日志(relay log)中。
  3. 从库 再重放(replay)中继日志中的事件,将数据变更同步到自己的数据库中。

Canal 正是利用这一机制,通过模拟从库的行为,获取主库的二进制日志事件,进而实现数据的实时同步和订阅。

所以,在启动之前,我们需要让 MySQL 开启 BinLog 监听。

1. 首先启用 MySQL binLog

1.1. 找到 MySQL 配置文件(my.cnf)
bash 复制代码
# macOS Homebrew MySQL 默认配置路径
cd /opt/homebrew/etc

# 接着开始编辑 /opt/homebrew/etc/my.cnf(或 /etc/my.cnf)
vim my.cnf
ini 复制代码
# Default Homebrew MySQL server config
[mysqld]

# 必须设置 server-id,设置 MySQL 服务器的唯一标识符
server-id = 1

# 启用二进制日志功能并指定日志前缀为 mysql-bin
log-bin = mysql-bin

# 将二进制日志格式设置为 ROW 模式
binlog-format = ROW
ini 复制代码
# 重启 MySQL
brew services restart mysql
# 或者
sudo systemctl restart mysqld # Linux

# 验证 binlog 已开启
mysql -u root -p -e "
SHOW VARIABLES LIKE 'log_bin';
SHOW VARIABLES LIKE 'binlog_format';
SHOW BINARY LOGS;
"

✅输出应包含:

其中 Log_name 应至少有一条数据。

1.2. 创建 Canal 专用用户
sql 复制代码
CREATE USER 'canal'@'%' IDENTIFIED BY 'canal';
GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%';
FLUSH PRIVILEGES;

详细解释:

  • 'canal'@'%' :创建一个名为 canal 的用户,允许从任意主机连接;
  • IDENTIFIED BY 'canal' :密码为 canal;
  • GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT:授予该用户这些权限
  • ON . :作用于所有数据库所有表;
  • FLUSH PRIVILEGES:立即生效权限变更,无需重启 MySQL。

2. 下载并配置 Canal

  1. 下载 Canal(以1.1.8为例)

1.1 可以去GitHub上直接下载:github.com/alibaba/can...

1.2 通过命令行下载

bash 复制代码
wget https://github.com/alibaba/canal/releases/download/canal-1.1.8/canal.deployer-1.1.8.tar.gz
tar -zxvf canal.deployer-1.1.8.tar.gz
mv canal.deployer-1.1.8 canal
cd canal
  1. 配置环节

进入解压后的目录中,可以看到这些文件

我们进入 conf 目录中,修改 canal.properties 文件(可通过 VS code 之类的工具直接进行文本编辑)

bash 复制代码
vim conf/canal.properties

我们只需要修改 canal.serverMode 为 rocketMQ 即可,其余保持默认。

接着我继续进入 conf 目录下的 example 目录中,修改 instance.properties 文件

只需要将 topic 按照自己的业务来命名即可,此处可以选择默认 example,其余保持默认即可。

此处的 topic 作用为指定 canal 将数据变更信息发送到 RocketMQ 主题名称,用于区分不同实例或业务的数据流。

2.1. 启动 Canal

这里先做了解,我们稍后在成功启动本地 rocketMQ 时再启动。

因为 canal.serverMode 设置为 rocketMQ,此时我们还没有在本地启动rocketMQ,因此也很有可能会报连接错误等等

在终端中进入解压后的 canal 的根目录

bash 复制代码
# 启动命令
sh bin/startup.sh

# 停止命令
sh bin/stop.sh

输入启动命令,终端会出现这些内容:

接着查看当前目录下的 logs 目录中,可以发现出现了一个 canal 文件夹以及 example 文件夹,我们进入 example 文件夹,可以查看 example.log 文件中信息,来确认我们是否成功启动:

✅启动成功应当有这两个信息:

3. 下载并启动 RocketMQ

3.1. 下载 RocketMQ

前往官网下载 (rocketmq.apache.org/download

此处我们选择二进制版本进行下载,source 源码版需要进行编译,binary 二进制版开箱即用,快速上手。

下载完后进行解压,我们进入解压后的 rocketMQ 目录中,macOS26 系统使用访达可以右击解压后的文件夹,选择服务,选择新建位于文件夹位置的终端窗口,这样可以快速通过终端进入该目录。

3.2. 配置

鉴于是本地单机测试,我们无需关注配置集群、持久化路径、ACL 等特性,因此不需要编辑很多地方。

RocetMQ 默认的配置内存比较大(比如 NameServer 4G、Broker 8G),在本地运行会占用过多资源,导致卡顿甚至启动失败,因此需要调低内存。

需要调整 bin 目录下的 runserver.sh 以及 runbroker.sh

bash 复制代码
# 配置 runserver.sh
vim bin/runserver.sh

进入编辑页面后,可以先输入 /Xms,接着按下回车进行搜索,找到内存配置项

这里可以设置为-Xms512m -Xmx512m-Xms1g -Xmx1g

bash 复制代码
# 配置 runbroker.sh
vim bin/runbroker.sh

此处也是同理,这里我给上截图。

3.3. 启动 NameServer

NameServer是RocketMQ的服务注册中心, 所有Broker和客户端都必须先通过它来发现彼此的路由信息。没有NameServer先行启动,整个消息系统的网络寻址和协调功能将完全瘫痪。类似于微服务中的 nacos。需要先启动。

bash 复制代码
# 在项目根目录中输入命令
nohup sh bin/mqnamesrv > logs/namesrv.log 2>&1 &

✅成功启动(可以到当前目录下的 logs 目录中查看启动具体情况):

📌解释一下命令:

  • nohup :no hang up 的缩写,防止进程应用户退出终端而被终止;只要不主动关闭、不关机,就一直运行
  • sh bin/mqnamesrv: 执行启动脚本
  • > logs/namesrv.log: 重定向标准输出,将日志信息写入 logs/namesrv.log 中
  • 2>&1:重定向错误输出,将错误信息也重定向到同一个日志文件
  • & :让命令在后台运行,不阻塞当前终端
3.4. 启动 Broker

Broker 是 RocketMQ 的实际消息处理引擎 ,负责消息的存储、转发和投递等核心业务。 没有 Broker,NameServer 只是一个空壳的地址簿,整个消息系统将无法实际收发和处理任何消息。

新建一个终端窗口,保持位于 RocketMQ 的根目录下

bash 复制代码
# 执行启动命令
nohup sh bin/mqbroker -n localhost:9876 --enable-proxy > logs/broker.log 2>&1 &

✅成功启动(这里也是同理,具体信息可以到 logs/broker.log 中查找)

4. 开始测试

在成功启动 RocketMQ 后,启动 canal。

在自己的数据库中 add、update、delete 一下测试数据(canal 默认会监听所有 database、table,可以在 canal 目录下,conf/example/instance.properties中修改正则,来改变监听范围

4.1. canal 部分

此时我们可以通过命令进行查看日志,或者直接查看 canal 目录中 logs/example/example.log 文件

bash 复制代码
# 新建一个终端,保持位于canal 目录中
tail -f logs/example/example.log

只要这里成功解析到数据变更,position前进,ack successfully,说明就成功运行了。

4.2. rocketMQ 部分

在 rocketMQ 的目录下,我们进入 bin 目录

在我们操作数据库前后分别输入一次以下命令:

sql 复制代码
sh mqadmin statsAll -n 127.0.0.1:9876 -t example | column -t

✅可以分别看到以下内容:

  • InMsg24Hour = 1:产生了1条 RocketMQ 消息
  • InTPS > 0: 消息吞吐量正常

至此,足以证明我们的整个数据同步链路已经完全畅通。 Canal 1.1.8 已成功捕获 MySQL 的 binlog 日志,并将数据变更实时投递至 RocketMQ 5.3.1。这标志着从 MySQL 数据源到消息队列的核心数据管道已构建完毕且运行稳定

之后,便可在本地开发环境中,将已有业务系统接入此数据同步项目之中, 逐步实现:

  1. 实时数据消费:订阅 RocketMQ 中的 Canal 消息,实现业务逻辑的实时处理。
  2. 缓存更新:将数据库变更同步到 Redis 等缓存,保证缓存数据的一致性。
  3. 搜索引擎同步:将数据变更同步到 Elasticsearch 等搜索引擎,提升查询性能。
  4. 数据分析与归档:将实时数据流接入大数据平台,进行实时分析或离线归档。

这套基础设施为后续的微服务解耦、实时数仓搭建等场景奠定了可靠的数据同步基础。


如有任何疑问或发现疏漏,欢迎在评论区交流指正

相关推荐
ai安歌3 小时前
【Rust编程:从新手到大师】Rust概述
开发语言·后端·rust
百锦再3 小时前
国产数据库替代MongoDB的技术实践:金仓数据库赋能浙江省人民医院信息化建设新展望
java·开发语言·数据库·mongodb·架构·eclipse·maven
用户6120414922133 小时前
C语言做的智能家居控制模拟系统
c语言·后端·敏捷开发
豆苗学前端3 小时前
10分钟带你入门websocket,并实现一个在线多人聊天室
前端·javascript·后端
风霜不见闲沉月3 小时前
rust更新后编译的exe文件执行报错
开发语言·后端·rust
稚辉君.MCA_P8_Java3 小时前
Bash 括号:()、{}、[]、$()、$(() )、${}、[[]] 到底有什么区别?
开发语言·jvm·后端·容器·bash
东百牧码人4 小时前
C#后端接口返回小程序二维码
后端
摇滚侠4 小时前
Spring Boot3零基础教程,事件驱动开发,设计登录成功后增加积分记录信息功能,笔记61
java·spring boot·笔记·后端
三十_4 小时前
TypeORM 多对多关联篇:中间表、JoinTable 与复杂关系的建模
前端·后端