canal线上问题记录

本文讲述了项目中遇到的canal数据同步问题,通过排查发现是后端开发修改表结构导致的。解决过程包括配置tsdb存储、删除本地文件和切换到MySQL数据库存储。最终推荐使用时序数据库存储表结构更新。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.问题现象
由于我们的项目使用了canal进行数据同步,实时变更表数据变化。突然就出现了数据不能同步问题,查看客户端和服务端都是正常的。于是问题指向canal集群问题。
二.环境排查
1.我们的系统环境采用zooKeeper+canal 高可用集群部署方式,开始了逐一排查工作
zooKeeper部署在了三台不同的服务器上,所以依次查看是否正常工作
在这里插入图片描述
三台服务查看是否有zookeeper的线程服务,QuorumPeerMain如果有说明正常。
在查看canal服务CanalLauncher 都在说明服务正常运行。

2.查看canal example.log运行日志,发现问题所在
在这里插入图片描述
是因为后端开发人员在表里增加或者删除了字段导致的,和canal里面的本地存储信息不一致导致的。既然找到了问题,就开始解决问题:
(1)在canal.properties文件中添加配置信息 在这里插入图片描述
重启服务,然而发现并没有解决问题。
(2)找到canal本地存储信息,修改meta.dat的
timestamp时间戳改为最新的时间。在这里插入图片描述
重启服务,然而发现并没有解决问题。
(3)直接暴力删除h2.mv.db文件,这里存储着同步的表结构信息。在删除后,canal在重启后,会自动创建最新的信息和mysql的表结构信息达到一致。重启服务,不在报错,可以正常工作了。
在这里插入图片描述
(4)还有个最好的方式,就是不要让canal的同步信息存储在本地h2数据文件里。存储到mysql数据库中。
在canal.properties里面配置tsdb的mysql数据库,数据库连接换成你自己的。具体配置如下:
canal.instance.tsdb.enable = true
canal.instance.tsdb.dir = canal.file.data.dir:../conf/{canal.file.data.dir:../conf}/canal.file.data.dir:../conf/{canal.instance.destination:}
#canal.instance.tsdb.url = jdbc:h2:${canal.instance.tsdb.dir}/h2;CACHE_SIZE=1000;MODE=MYSQL;
canal.instance.tsdb.url=jdbc:mysql://XXXXX:3306/canal_tsdb
canal.instance.tsdb.dbUsername = root
canal.instance.tsdb.dbPassword = root

#canal.instance.tsdb.spring.xml = classpath:spring/tsdb/h2-tsdb.xml
canal.instance.tsdb.spring.xml = classpath:spring/tsdb/mysql-tsdb.xml

在数据库里面创建canal_tsdb数据库,数据库的用户需要有创建表的权限。
create database canal_tsdb;
(5)最后终极方案就是等待最新版的canal增加时序表结构的能力

### Canal MQ `dynamicTopic` 参数配置方法及最佳实践 #### 配置方法 Canal 的 `canal.mq.dynamicTopic` 参数用于动态指定消息队列的主题名称映射规则。该参数支持通过正则表达式匹配数据库表名,并将其转换为目标主题名称。以下是具体的配置方式: 在 Canal 部署目录下的 `conf/example/instance.properties` 文件中,可以找到如下配置项: ```properties canal.mq.dynamicTopic = ${db}.${table} ``` 上述默认配置表示目标主题由 `${db}` 和 `${table}` 组成,其中 `${db}` 是数据源中的库名,`${table}` 是对应的表名[^1]。 如果需要更复杂的主题命名规则,则可以通过自定义正则表达式实现。例如: ```properties canal.mq.dynamicTopic = topic_prefix_${db}_.*=target_topic,other_tables=general_topic ``` 此配置表示当表名符合正则表达式 `${db}_.` 时,对应的消息会被发送到名为 `topic_prefix_${db}_.*=target_topic` 的主题;其他不匹配的表会统一发送至 `general_topic` 主题。 #### 最佳实践 为了提高系统的可维护性和性能,在实际应用中建议遵循以下几点最佳实践: 1. **合理划分主题** 将不同业务逻辑的数据划分为不同的 Kafka 或 RocketMQ 主题,以便于下游消费者按需订阅特定主题的内容。这不仅有助于提升消费效率,还能减少不必要的网络传输开销。 2. **控制单个主题内的分区数量** 对于高并发场景下频繁更新的大规模表,应适当增加其关联主题的分区数(partitions),从而充分利用多线程处理能力来加速消息生产和消费过程。 3. **监控与告警机制建设** 建立健全的监控体系,实时跟踪各阶段延迟情况以及错误日志记录状态。一旦发现问题能够迅速定位原因并采取相应措施解决。 4. **定期优化配置文件** 根据线上运行状况不断调整相关参数设置(如batch size、timeout等),力求达到最优平衡点以满足具体需求环境的要求。 ```python # 示例 Python 脚本展示如何解析 canal 数据包并打印相关信息 import json def process_canal_message(message_body): try: message_dict = json.loads(message_body.decode('utf-8')) database_name = message_dict.get("database", None) table_name = message_dict.get("table", None) if not (database_name and table_name): raise ValueError("Missing required fields 'database' or 'table'") target_topic = f"{database_name}.{table_name}" print(f"Message will be sent to the topic: {target_topic}") except Exception as e: print(f"Error occurred while processing message: {str(e)}") if __name__ == "__main__": sample_message = b'{"database":"test_db","table":"sample_table"}' process_canal_message(sample_message) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值