flink canal-format 解析多表binlog的bug解决方案

版本flink1.12.0

基于flink1.13 master版本进行修改编译 因为1.13 尚未正式发布

前置问题
在使用时候 配置’canal-json.table.include’ 并不能正确的过滤掉指定表的binlog ,在解析那步会报错,比如 我想读取 canal-json.table.include = ‘a’ 表的binlog,a表有一个source字段为int类型, 但是这个时候如果b表也有source字段,但是source字段是string类型,这个时候b的source存了一个非int的数据,这个时候会报错。

向flink社区提交的issues
https://issues.apache.org/jira/browse/FLINK-20385%3E
https://issues.apache.org/jira/browse/FLINK-20385

1 功能点 : 支持canal-json.database.include 正则匹配
2 解决 :多表binlog导致的报错
3 解决:解决ddl binlog报错

具体代码修改
1 修改 flink-json包的CanalJsonDeserializationSchema.deserialize()方法

             @Override
    public void deserialize(byte[] message, Collector<RowData> out) throws IOException {
        try {
            //先解析出json 防止走下一步报错
            final JsonNode root = jsonDeserializer.deserializeJsonNode(message);
            //这里使用java正则表达 来做通配功能
            if (this.table != null) {
                if (!Pattern.matches(this.table, String.valueOf(root.get("table")))) {
                    return;
                }
            }
            //这里过滤掉isDdl:true的binlog
            String isDdl = String.valueOf(root.get("isDdl"));
            if (StringUtils.isBlank(isDdl)) {
                if ("true".equals(isDdl)) {
                    return;
                }
            }
            //因为不需要去做匹配database 所以这里没有去做
            if (database != null) {
                if (!database.equals(String.valueOf(root.get("database")))) {
                    return;
                }
            }
            //在这一步 才去调用转换为flink RowData 防止因为数据类型导致的错误
            GenericRowData row = (GenericRowData) jsonDeserializer.deserializeRowData(root);
            String type = row.getString(2).toString(); // "type" field

2 添加flink-json包JsonRowDataDeserializationSchema 2个方法

/**
 * 先解析获取json对象
 * @param message
 * @return
 * @throws IOException
 */
public JsonNode deserializeJsonNode(byte[]  message) throws IOException {
    try {
        final JsonNode root = objectMapper.readTree(message);
        return root;
    } catch (Throwable t) {
        if (ignoreParseErrors) {
            return null;
        }
        throw new IOException(
                format("Failed to deserialize JsonNode '%s'.", message), t);
    }
}

/**
 * 然后再映射成RowData对象
 * @param message
 * @return
 * @throws IOException
 */
public RowData deserializeRowData(JsonNode message) throws IOException {
    try {
        return (RowData) runtimeConverter.convert(message);
    } catch (Throwable t) {
        if (ignoreParseErrors) {
            return null;
        }
        throw new IOException(
                format("Failed to deserialize RowData '%s'.", message), t);
    }
}

3 编译修改的代码,替换你本地flink lib下的flink-json包
如果本地idea运行 需要去掉pom.xml的flink-json依赖,并且把编译的flink-json包添加到你的idea 项目libraries。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值