MySQL数据库数据动态监控(canal+Kafka)

本文介绍了如何使用Canal监控MySQL数据库的binlog并借助Kafka进行实时推送。首先,你需要在MySQL服务器上开启binlog并创建Canal用户。接着,下载并安装Canal,配置相关参数,如设置serverMode为kafka,指定Kafka服务器地址等。完成配置后启动Canal,最后启动Kafka消费者以接收数据库变更消息。

参考资料:

参考文章https://gper.club/articles/7e7e7f7ff3g59gc6g6d

canal官网 https://github.com/alibaba/canal

canal教程 https://www.bilibili.com/video/BV1aL4y1E7Tb/?spm_id_from=333.337.search-card.all.click&vd_source=97411b9a8288d7869f5363f72b0d7613


环境准备:

  • 要有本服务器可访问的MySQL服务,远程的请检查是否已经开启了MySQL远程访问,如果没有,参考
  • 因为本文是canal结合Kafka,监控MySQL的binlog,并进行数据库变化的推送,所以必须有可使用的Kafka
  • 没有Kafka的参考:Kafka单节点(推荐),或者Kafka集群
  • 还需要Java8,及以上的JDK环境

canal安装及配置:

在基础环境部署好后,就开始安装canal

1. 在目标数据库上创建用户和数据库

  • 首先需要在数据库上开启binlog,且binlog-format必须是ROW
  • 找到MySQL的配置文件,默认路径是:/etc/my.cnf

 vim /etc/my.cnf

  • 在配置文件中添加下面语句

log-bin=/usr/local/mysql/data/mysql-bin
binlog-format=ROW
server_id=1

 

  •  然后进入到MySQL,mysql -u root -p,输入密码登录

  • 查看是否开启binlog

show variables like 'log_bin';

  • 然后启动或重启MySQL服务 ()

# 启动MySQL

sudo service mysqld start

# 重启MySQL

sudo service mysqld restart

# 查看MySQL状态 

sudo service mysqld status

  •  然后再进入到数据库中,mysql -u root -p ,创建用户和数据库

# 创建canal专用的用户,用于访问master获取binlog

CREATE USER canal IDENTIFIED BY '123456';

  •  给canal用户分配查询和复制的权限

先检查权限是否开启

#  查看已创建的数据库

show databases;


#  选择MySQL数据库

use mysql
 

# 查看root用户是否开启

select user,host,grant_priv from user;

 如果root显示是N,则需要开启

UPDATE user set Grant_priv='Y' where user='root' and `Host`='%';

刷新权限

 flush privileges;

 

给canal用户分配查询和复制的权限

GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO canal@'%';

  •  刷新权限

FLUSH PRIVILEGES;

  •  配置密码

ALTER USER 'canal'@'%' IDENTIFIED WITH mysql_native_password BY '123456';

  • 创建测试数据库

CREATE DATABASE `canaltest` CHARSET `utf8mb4` COLLATE `utf8mb4_unicode_ci`;

CTRL+Z进行退出 

 2. 下载安装canal

  • 以安装目录:/usr/local/soft/canal为例

用目前稳定版本1.1.4

cd /usr/local/soft/
mkdir canal
cd canal

  • 然后在canal目录中下载canal的安装包,有两种方式

(1).  本地下载好后再上传到服务器中的  /usr/local/soft/canal 目录(特别推荐)

访问网址

https://github.com/alibaba/canal/releases/download/canal-1.1.4/canal.deployer-1.1.4.tar.gz

将下载好的tar包上传至创建的目录 /usr/local/soft/canal

(2). 执行以下命令进行下载(不推荐,经常下载失败)

 wget https://github.com/alibaba/canal/releases/download/canal-1.1.4/canal.deployer-1.1.4.tar.gz

  • 下载好后,进行解压

tar -zxvf canal.deployer-1.1.4.tar.gz

  •  配置相应的配置项

在canal目录下,执行

vim conf/canal.properties

添加如下配置

canal.serverMode=kafka
canal.mq.servers = 192.168.44.160:9092

保存退出

在canal目录下执行

 vim /usr/local/soft/canal/conf/example/instance.properties

 修改或添加如下配置

canal.instance.master.address=192.168.44.121:3306
canal.instance.dbUsername=canal
canal.instance.dbPassword=123456
# 新增
canal.instance.defaultDatabaseName=canaltest
# 这个topic会自动创建
canal.mq.topic=canal-topic

 

 

  • 启动Kafka,如果不会参考
  •  进入到bin目录,启动canal

cd bin

sh startup.sh 
# 查看实例日志
tail -100f /usr/local/soft/canal/logs/canal/canal.log

3. 启动Kafka消费者,消费我们配置好的 canal-topic

 在Kafka服务器上的安装目录下的bin目录,执行以下语句,消费canal-topic

 4.在canaltest数据库随便建一张表,做增删改的操作,Kafka的canal-topic消费者就能接收到数据变化的消息

 

  •  我们可以利用这个技术,进行数据库的动态监测

<think>好的,我现在需要帮用户解决如何通过CanalKafka捕获数据库变更并将数据写入Hudi的问题。首先,我得回顾一下用户之前的问题和之前的回答。用户之前对比了Hudi和Hive的实时处理能力,现在想具体实现一个使用CanalKafka数据管道,将数据库变更同步到Hudi。 首先,用户提到了使用CanalKafka,所以需要明确这两个组件的作用。Canal用于监听数据库的binlog,将变更数据发送到Kafka。然后,需要一个处理层来消费Kafka数据并写入Hudi。根据之前的引用内容,用户可能参考了Flink作为处理引擎,因为引用中提到了Flink CDC和Hudi的结合。不过用户现在明确提到的是Canal+Kafka,所以可能需要调整方案,使用Flink消费Kafka数据,而不是直接使用Flink CDC。 接下来,我需要确定步骤。首先,配置Canal监听MySQL的binlog,并将变更发送到Kafka。然后,使用Flink作为流处理引擎,消费Kafka中的变更数据,处理后将数据写入Hudi。这里需要考虑数据格式转换、Hudi的类型(COW或MOR)、以及如何保证Exactly-Once语义。 用户可能关心如何确保数据的正确性和一致性,比如如何处理DDL变更,如何保证顺序,以及如何优化写入性能。根据之前的回答,Hudi支持ACID事务,可以通过时间线管理来处理并发写入,所以需要配置Flink作业正确使用这些特性。 另外,用户可能还需要考虑数据的分区策略、小文件合并、以及如何查询Hudi中的数据。例如,使用MOR进行实时查询,或者COW用于快速读取。同时,需要确保Flink作业能够处理全量和增量数据,可能在全量导入时使用批处理,增量阶段使用流处理。 还需要参考用户提供的引用内容,特别是引用4和5中提到Flink读取binlog,全量数据采集后发送到Kafka,然后由Spark写入Hudi。但用户现在想用Flink,所以可能需要调整流程,用Flink代替Spark。同时,引用5提到Enumerator监控状态,通知Binlog任务打标签,这可能涉及checkpoint机制,确保数据一致性。 最后,用户可能希望具体的代码示例和配置步骤,比如如何设置Canal,Flink作业的配置,Hudi的创建参数等。需要确保步骤清晰,并且考虑到可能的错误处理,比如Kafka消费偏移量的管理,Hudi的写入优化参数等。 总结一下,需要分步骤说明:配置CanalKafka,Flink消费Kafka数据,写入Hudi,以及优化和验证步骤。同时,要结合用户提供的引用内容,确保方案可行,并解决用户可能的隐藏需求,如数据延迟、一致性、系统扩展性等。</think>### 基于 Canal + Kafka + Flink 的 Hudi 实时入湖方案 以下是完整的实现流程,结合 CDC 技术栈与 Hudi 的增量处理能力: --- #### 一、整体架构设计 ```plaintext MySQL -> Canal (捕获binlog) -> Kafka (存储变更日志) -> Flink (流处理) -> Hudi (存储层) ``` **技术组件作用**: - **Canal**:伪装为 MySQL Slave,解析 binlog 生成 JSON 格式变更事件[^2][^3] - **Kafka**:缓冲变更数据,解耦生产与消费速率 - **Flink**:消费 Kafka 数据,处理 Schema 变更,写入 Hudi (支持 Exactly-Once 语义) - **Hudi**:存储层管理 ACID 事务、增量合并、时间旅行查询[^1] --- #### 二、具体实现步骤 ##### 1. **配置 Canal 捕获 MySQL 变更 ```yaml # canal.properties 核心配置 canal.serverMode = kafka # 输出到Kafka canal.mq.servers = kafka1:9092,kafka2:9092 canal.mq.topic = db_cdc canal.destination = example # 实例名称 canal.instance.filter.regex = .*\\..* # 监控所有库 ``` 启动 Canal 后,MySQL 的 INSERT/UPDATE/DELETE 操作会转为 JSON 写入 Kafka,格式示例: ```json { "type": "UPDATE", "database": "test_db", "table": "orders", "before": {"id": 1001, "amount": 50.0}, "after": {"id": 1001, "amount": 60.0}, "ts": 1698765432000 } ``` ##### 2. **Flink 消费 Kafka 数据 使用 Flink SQL 创建 Kafka Source : ```sql CREATE TABLE kafka_cdc ( `type` STRING, `database` STRING, `table` STRING, `before` ROW<id INT, amount DOUBLE>, `after` ROW<id INT, amount DOUBLE>, `ts` BIGINT ) WITH ( 'connector' = 'kafka', 'topic' = 'db_cdc', 'properties.bootstrap.servers' = 'kafka1:9092', 'format' = 'json' ); ``` ##### 3. **写入 Hudi 根据业务需求选择 **COW**(直接覆盖)或 **MOR**(日志合并)类型: ```sql -- 创建 Hudi MOR (支持增量合并) CREATE TABLE hudi_orders ( id INT PRIMARY KEY, amount DOUBLE, `ts` BIGINT ) WITH ( 'connector' = 'hudi', 'path' = 's3://data-lake/hudi/orders', 'table.type' = 'MERGE_ON_READ', 'write.operation' = 'upsert', 'hoodie.datasource.write.recordkey.field' = 'id', 'hoodie.datasource.write.precombine.field' = 'ts' ); -- 将 Kafka 数据写入 Hudi INSERT INTO hudi_orders SELECT after.id AS id, after.amount AS amount, ts FROM kafka_cdc WHERE `table` = 'orders' AND `type` IN ('INSERT', 'UPDATE'); ``` ##### 4. **处理 DELETE 操作 Hudi 支持软删除和硬删除,需在 Flink 中转换 DELETE 事件: ```sql -- 添加删除标记字段 ALTER TABLE hudi_orders ADD `_hoodie_is_deleted` BOOLEAN; -- 处理删除逻辑 INSERT INTO hudi_orders SELECT before.id AS id, NULL AS amount, ts, TRUE AS _hoodie_is_deleted -- 标记为删除 FROM kafka_cdc WHERE `type` = 'DELETE' AND `table` = 'orders'; ``` --- #### 三、高级优化策略 ##### 1. **Schema 变更自动同步 - **Canal 配置**:开启 DDL 事件采集[^3] - **Flink 处理**:解析 DDL 并动态更新 Hudi 结构 ```java // 示例:Flink 动态解析 DDL(需自定义逻辑) public class DDLEventProcessFunction extends ProcessFunction<String, String> { @Override public void processElement(String ddl, Context ctx, Collector<String> out) { if (ddl.contains("ALTER TABLE")) { // 调用 Hudi 的 Schema Evolution API HoodieTableMetaClient metaClient = ...; metaClient.getTableConfig().setSchema(...); } } } ``` ##### 2. **小文件合并 Hudi 自动合并策略配置: ```properties # Flink Hudi 配置 hoodie.cleaner.commits.retained=20 hoodie.parquet.max.file.size=128 # 单位MB hoodie.logfile.max.size=64 # 单位MB ``` ##### 3. **Exactly-Once 保障 - **Flink Checkpoint**:开启并设置 1 分钟间隔 - **Hudi 异步压缩**:避免阻塞主写入流程 ```sql SET execution.checkpointing.interval = 60s; SET execution.checkpointing.mode = EXACTLY_ONCE; ``` --- #### 四、验证与监控 1. **数据一致性检查** ```sql -- 查询 Hudi 最新快照 SELECT COUNT(*) FROM hudi_orders TIMESTAMP AS OF '2023-11-01 12:00:00'; -- 对比源库与 Hudi SELECT MAX(ts) FROM mysql.orders; SELECT MAX(ts) FROM hudi_orders; ``` 2. **监控指标** - **Kafka Lag**:Flink 消费延迟(Grafana 展示) - **Hudi Commit Frequency**:写入频率(Hudi Timeline API) - **Compaction Duration**:MOR 合并耗时(Hudi Metrics) --- ### 关键问题解答 1. **如何保证顺序性?** - Canal 按 binlog 顺序写入 Kafka 分区 - Flink 按主键分区写入 Hudi(`hoodie.datasource.write.keygenerator.class` 配置) 2. **如何处理大事务?** - 调整 Canal 的 `canal.instance.transaction.size` 参数 - Flink 开启缓冲(`table.exec.mini-batch.enabled=true`) 3. **与 Flink CDC 对比优势?** - Canal 支持更灵活的 DDL 解析和过滤规则[^3] - 已有 Canal 集群可复用,降低迁移成本[^2] --- ### 扩展方案:整库同步工具 若需同步整个 MySQL 数据库,可使用 **Canal-Adapter** 自动生成 Flink 作业: ```bash # 启动 Canal-Adapter bin/startup.sh -config conf/application.yml \ -hudi.conf.path conf/hudi-template.yaml ``` 模板配置参考: ```yaml # hudi-template.yaml target: type: hudi path: "s3://data-lake/hudi/{database}/{table}" write: operation: upsert precombine.field: "ts" ``` --- [^1]: Hudi 的事务管理通过时间轴(Timeline)实现,保障 ACID 特性。 [^2]: Canal 的 DDL 解析能力使其适合复杂 Schema 变更场景。 [^3]: Flink 的流批一体能力在此架构中实现增量与全量数据统一处理。 [^4]: 异步压缩策略可平衡实时写入性能与查询效率。 [^5]: 通过 Kafka 的分区策略可优化数据分布,避免写入热点。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

PH = 7

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值