Canal v1.1.4版本避坑指南

本文涉及的产品
对象存储 OSS,20GB 3个月
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
对象存储 OSS,恶意文件检测 1000次 1年
简介: 在忍耐了很久之后,忍不住爆发了,在掘金发了条沸点(下班时发的)

微信截图_20220513163654.png


前提



在忍耐了很久之后,忍不住爆发了,在掘金发了条沸点(下班时发的):


微信截图_20220513163703.png


这是一个令人悲伤的故事,这条情感爆发的沸点好像被屏蔽了,另外小水渠(Canal意为水道、管道)上线一段时间,不出坑的时候风平浪静,一旦出坑令人想屎。重点吐槽几点:


  • 目前最新的RELEASE版本为v1.1.4,发布于2019-9-2,快一年没更新了。
  • Issue里面堆积了十分多未处理或者没有回应的问题,有不少问题的年纪比较大。
  • master分支经常提交异常的代码,构建不友好,因为v1.1.4比较多问题,也曾经想过用master代码手动构建,导入项目之后决定放弃,谁试试谁知道,可以尝试对比导入和构建MyBatis的源码。


这些都只是表象,下面聊聊踩过的坑。


解析线程阻塞问题



这个基本是每个使用Canal的开发者的必踩之坑。$CANAL_HOME/conf/canal.properties配置文件中存在一行注释掉的配置:canal.instance.parser.parallelThreadSize = 16。该配置用于指定解析器实例并发线程数,如果注释了会导致解析线程阻塞,得到的结果就是什么都不会发生。


微信截图_20220513163711.png


注释解除即可,建议使用默认值16


表结构缓存异常阻塞问题



微信截图_20220513163719.png


这是Issue里面很大部分提问者提到但是久未解决的问题,也就是表结构元数据的存储问题(配置项里面使用了tsdb也就是时序数据库的字眼,下面就称为tsdb功能)。


微信截图_20220513163726.png


默认开启tsdb功能,也就是会通过h2数据库缓存解析的表结构,但是实际情况下,如果上游变更了表结构,h2数据库对应的缓存是不会更新的,这个时候一般会出现神奇的解析异常,异常的信息一般如下:


Caused by: com.alibaba.otter.canal.parse.exception.CanalParseException: column size is not match for table:数据库名称.表名称,新表结构的字段数量 vs 缓存表结构的字段数量;
复制代码


该异常还会导致一个可怕的后果:解析线程被阻塞,也就是binlog事件不会再接收和解析。这个问题笔者也查看过很多Issue,大家都认为是一个严重的BUG,目前认为比较可行的解决方案是:禁用tsdb功能(真的够粗暴),也就是canal.instance.tsdb.enable设置为false。如果不禁用tsdb功能,一旦出现了该问题,必须要先停止Canal服务,接着删除$CANAL_HOME/conf/目标数据库实例标识/h2.mv.db文件,然后启动Canal服务。


因为这个比较坑的问题,笔者在生产禁用了tsdb功能,并且添加了DDL语句的处理逻辑,直接打到钉钉预警上并且@整个群的人。


微信截图_20220513163735.png


每次看到这个预警都心惊胆战。


日志问题



如果刚好需要定位的binlog位点处于比较靠后的文件,文件数量比较多,会疯狂打印寻位的日志。之前尝试过重启一下子打印了几GB日志,超过99%是定位binlog文件和position的日志行。可以考虑通过修改$CANAL_HOME/conf/logback.xml(并不建议,不清楚源码容易造成其他新的问题)配置或者指定$CANAL_HOME/conf/目标数据库实例标识/instance.properties的下面几个属性手动定位解析的起点:


canal.instance.master.journal.name=binlog的文件名
canal.instance.master.position=binlog的文件中的位点
canal.instance.master.timestamp=时间戳
canal.instance.master.gtid=gtid的值
复制代码


以上的手动定位解析的起点的属性需要在下次重启Canal之前更新或者注释掉,否则会造成重新解析或者找不到文件的严重后果!!!


反正每次重启Canal服务都惊心动魄,没有一个开源软件可以让人有这种感觉。因为生产的服务器磁盘不是很充足,选配的时候只买了100GB,而且考虑到这些日志本质上没有太大意义,于是只能定期上去删日志,前期是手动删,后来觉得麻烦写了个Shell脚本定时删除久远的日志文件。


云RDS MySQL的使用问题



如果刚好使用了阿里云的RDS MySQL,那么有可能会遭遇更大的坑。主要问题是:


  • RDS MySQL有磁盘空间优化规则,触发了规则会把binlog文件上传到OSS,然后删除本地的binlog文件。
  • Canal的文档来看,会自动拉取OSS上的binlog文件进行解析,让使用者无感知,但是此功能有BUG,一直无法正常使用。
  • RDS MySQL是一个暗箱,出了问题只能通过MySQL的相关查询去定位问题,没有办法进去服务器查看真实的现场。


微信截图_20220513163743.png


命中了这个问题,一般出现的异常是:


.................. sqlstate = HY000 errmsg = Could not find first log file name in binary log index file
复制代码


可以基本确认这个功能是存在缺陷的,例如这里有个Issue-2596


微信截图_20220513163753.png


目前笔者的做法如下:

  • 完全弃用Canal拉取OSS上的binlog文件的功能。
  • RDS MySQL尽可能扩容一下磁盘,调整策略让尽可能多的binlog文件尽可能久地保留在本地,让它们被完全解析后再手动上传或者命中了过期规则后自动上传,这期间有很多东西需要额外收取费用,具体需要自行权衡。


读取和解析OSS上的binlog文件在目前(2020-08-05)的master分支上依然有BUG,想手动构建master分支的伙伴建议放弃幻想。


这个问题的严重后果是:有比较大的可能性导致某段binlog文件解析完全缺失,除非可以把binlog文件重新塞回去RDS MySQL里面,否则需要做上下游手动同步功能。


to be continue



除此之外,要注意Canal最好做主备部署,提交位点和集群管理建议使用Zookeeper,而服务模式(canal.serverMode,目前支持tcpkafkarocketmq)建议选用Kafkamaster分支上有RabbitMQ的连接器支持,如果想尝鲜可以手动构建一下),并且每个节点的资源要求比较高,笔者生产上每个节点使用了2C8G低主频的ECS,感觉有点压不住,特别时重启实例的时候如果需要重新定位binlog位点,CPU在一段时间内使用率会飙高。


笔者发现了阿里云的DTS就是使用了Canal作为基础中间件进行数据同步的,说明它有被投产到实际应用场景中,真不希望它最终演变成废弃的KPI任务项目。不知道往后还会遇到多少问题,如果碰到了也会持续更新本避坑指南。


(本文完 c-2-d e-a-20200805)

相关文章
|
人工智能 JavaScript 前端开发
【Vue2从入门到精通】详解Vue数据双向绑定原理及手动实现双向绑定
Vue是采用数据劫持结合发布者-订阅者模式的方式,通过使用ES5中的Object.defineProperty()方法来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调来渲染视图。
765 0
【Vue2从入门到精通】详解Vue数据双向绑定原理及手动实现双向绑定
|
监控 关系型数据库 PostgreSQL
两阶段提交(2PC, Two-Phase Commit)
【8月更文挑战第24天】
847 9
|
存储 算法 C语言
"揭秘C语言中的王者之树——红黑树:一场数据结构与算法的华丽舞蹈,让你的程序效率飙升,直击性能巅峰!"
【8月更文挑战第20天】红黑树是自平衡二叉查找树,通过旋转和重着色保持平衡,确保高效执行插入、删除和查找操作,时间复杂度为O(log n)。本文介绍红黑树的基本属性、存储结构及其C语言实现。红黑树遵循五项基本规则以保持平衡状态。在C语言中,节点包含数据、颜色、父节点和子节点指针。文章提供了一个示例代码框架,用于创建节点、插入节点并执行必要的修复操作以维护红黑树的特性。
273 1
|
9月前
|
人工智能 分布式计算 大数据
MaxFrame 产品评测:大数据与AI融合的Python分布式计算框架
MaxFrame是阿里云MaxCompute推出的自研Python分布式计算框架,支持大规模数据处理与AI应用。它提供类似Pandas的API,简化开发流程,并兼容多种机器学习库,加速模型训练前的数据准备。MaxFrame融合大数据和AI,提升效率、促进协作、增强创新能力。尽管初次配置稍显复杂,但其强大的功能集、性能优化及开放性使其成为现代企业与研究机构的理想选择。未来有望进一步简化使用门槛并加强社区建设。
411 8
|
11月前
什么是快照读和当前读
*快照读(一致性非锁定读)读取的是当前数据的可见版本,可能是会过期数据,不加锁的select就是快照读 *当前读(一致性锁定读)读取的是数据的最新版本,并且当前读返回的记录都会上锁,保证其他事务不会并发修改这条记录。如update、insert、delete、select for undate(排他锁)、select lockin share mode(共享锁) 都是当前读
|
Java 关系型数据库 MySQL
create connection error, url: jdbc:mysql://localhost:3306/ssm, errorCode 1045, state 28000 java.sql.
create connection error, url: jdbc:mysql://localhost:3306/ssm, errorCode 1045, state 28000 java.sql.
378 0
|
Java 数据格式 Spring
SpringBoot中@Value注解注入List或Map数据格式出现异常
在做一个小demo的时候、做的例子是我想在程序运行时将一些数据放入到配置类中的属性中、我想到可以通过yaml配置的数据映射到实体类中的属性中、我在想通过这种形式能不能映射。
|
弹性计算 JavaScript Java
阿里云服务器搭建部署宝塔详细流程
以下是内容的摘要: 本文主要介绍了在阿里云上创建和配置服务器环境的步骤,包括注册阿里云账号、实名认证、购买和设置服务器、域名的获取与备案、以及使用宝塔面板安装和配置环境。首先,用户需要注册阿里云账号并进行实名认证,选择合适的服务器配置。接着,购买服务器后,要准备并备案域名,以便通过友好的网址访问网站。在服务器上安装宝塔面板,可以方便地管理和配置LAMP/LNMP/Tomcat/Node.js等应用环境。完成这些步骤后,用户还需要在宝塔面板中安装MySQL、Redis等数据库,部署Java或Vue项目,并配置相关端口。最后,将前端项目打包上传至服务器,并设置站点,即可实现网站的上线。
|
canal 关系型数据库 MySQL
Canal 中启用了 GTID 功能
Canal 中启用了 GTID 功能
2212 1