Canal 1.1.5全量同步MySQL数据到ES7的日期问题

owfi6suc  于 4个月前  发布在  Mysql
关注(0)|答案(3)|浏览(122)

Question

Canal 1.1.5同步MySQL数据到ES7会报下面的日期格式转换异常,网上找到的解决方案两种都有一定的侵入性不够灵活,一种是改ES的索引结构增加日期字段支持的格式,另一种是修改canal adapter的源代码中ESSyncUtil.java类对日期的处理,除此之外不知道是否还有更简单的处理方式,最好可以灵活的选择写入ES的日期格式,Issue中看类似问题至少提出有2-3年了依旧没有很好的解决方案吗?

另外canal adapter 1.1.5二进制下载包里,client-adapter.es7x-1.1.5-jar-with-dependencies.jar存在druid冲突的问题,也是改的源码重新编译的,网上看都是陈年老问题了,这种修改太不及时了,各种踩坑😭

Caused by: java.lang.RuntimeException: java.lang.RuntimeException: 全量数据 etl 异常 ElasticsearchException[Elasticsearch exception [type=mapper_parsing_exception, reason=failed to parse field [createTime] of type [date] in document with id '3'. Preview of field's value: '2022-01-24T11:50:04+08:00']]; nested: ElasticsearchException[Elasticsearch exception [type=illegal_argument_exception, reason=failed to parse date field [2022-01-24T11:50:04+08:00] with format [yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis]]]; nested: ElasticsearchException[Elasticsearch exception [type=date_time_parse_exception, reason=Failed to parse with all enclosed parsers]];
        at com.alibaba.otter.canal.client.adapter.es7x.etl.ESEtlService.lambda$executeSqlImport$1(ESEtlService.java:191) [client-adapter.es7x-1.1.5-jar-with-dependencies.jar:na]
        at com.alibaba.otter.canal.client.adapter.support.Util.sqlRS(Util.java:60) ~[client-adapter.common-1.1.5.jar:na]
        ... 60 common frames omitted
Caused by: java.lang.RuntimeException: 全量数据 etl 异常 ElasticsearchException[Elasticsearch exception [type=mapper_parsing_exception, reason=failed to parse field [createTime] of type [date] in document with id '3'. Preview of field's value: '2022-01-24T11:50:04+08:00']]; nested: ElasticsearchException[Elasticsearch exception [type=illegal_argument_exception, reason=failed to parse date field [2022-01-24T11:50:04+08:00] with format [yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis]]]; nested: ElasticsearchException[Elasticsearch exception [type=date_time_parse_exception, reason=Failed to parse with all enclosed parsers]];
        at com.alibaba.otter.canal.client.adapter.es7x.support.ESConnection$ES7xBulkResponse.processFailBulkResponse(ESConnection.java:470) ~[na:na]
        at com.alibaba.otter.canal.client.adapter.es7x.etl.ESEtlService.lambda$executeSqlImport$1(ESEtlService.java:178) [client-adapter.es7x-1.1.5-jar-with-dependencies.jar:na]
        ... 61 common frames omitted
2022-01-24 17:09:19.047 [http-nio-8081-exec-4] INFO  c.a.otter.canal.client.adapter.es7x.etl.ESEtlService - 数据全量导入完成, 一共导入 2 条数据, 耗时: 28
i86rm4rw

i86rm4rw1#

创建索引的时候加上格式化试试,我自己搭建成功的案例: https://github.com/caipeishen/Learning-Note/blob/master/Canal/Canal%E5%90%8C%E6%AD%A5MySQL%E5%88%B0ES7.md
例如:
"create_date": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
},

vmdwslir

vmdwslir2#

就像我之前描述的解决方案,一种方式是创建索引格式时format增加 strict_date_optional_time 才行,adapter代码里写死了日期格式 "yyyy-MM-dd'T'HH:mm:ss.SSS" + Util.timeZone ,另一种办法就是改代码重新编译,类似下面截图里的方式。其实我是希望官方可以有一种简单的方式可以支持配置方式的,开发者自己选择日期格式

@caipeishen 感谢你的回复,有空看看你的demo可以一起交流,adapter感觉还是有点弱,对于复杂数据结构的同步支持还不好,网上看到各种隐藏的坑,我改设计方案了,直接使用Canal Java Client写代码同步数据了,代码量相较adapter大些,但比较灵活能实现我们一些特殊的需求

方案一

"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||strict_date_optional_time||epoch_millis"

方案二

mfuanj7w

mfuanj7w3#

我的解决方案:

  1. Es中date类型字段不手动指定格式, ESSyncUtils.typeConvert(...) 中硬编码的格式是可以适配Es的
  2. 若Es中date类型一定要指定格式,则修改 ESSyncUtils.typeConvert(...) 中的日期格式

Es7中date类型格式说明: https://www.elastic.co/guide/en/elasticsearch/reference/current/date.html

相关问题