FlinkSQL解析canal二进制数据

本文介绍了如何处理Canal发送到消息队列的二进制数据,通过自定义UDTF进行反序列化,将其转换为JSON并进行SQL解析。详细讲解了自定义UDTF的实现,包括引入canal依赖和编写过程,并提供了部署步骤以及本地模式下运行Flink SQL的Demo。
摘要由CSDN通过智能技术生成

背景

canal发送到消息队列存在两种数据格式,一种是json,一种是java的序列化对象二进制格式,
json解析比较简单,而二进制解析需要借助自定义UDTF,对二进制数据进行反序列化,解析成json后,再进行sql二次解析,使用行转列的方式,将数据进一步拆分成独立的行数据

自定义UDTF

引入canal依赖
<dependency>
  <groupId>com.alibaba.otter</groupId>
  <artifactId>canal.client</artifactId>
  <version>1.1.6</version>
</dependency>


<dependency>
  <groupId>com.alibaba.otter</groupId>
  <artifactId>canal.protocol</artifactId>
  <version>1.1.6</version>
</dependency>
编写自定义UDTF

此UDTF用于将canal 二进制msg转换成canal FlatMessage

import com.alibaba.otter.canal.client.CanalMessageDeserializer;
import com.alibaba.otter.canal.protocol.CanalEntry;
import com.alibaba.otter.canal.protocol.FlatMessage;
import com.alibaba.otter.canal.protocol.Message;
import com.google.protobuf.InvalidProtocolBufferException;
import org.apache.flink.table.annotation.DataTypeHint;
import org.apache.flink.table.annotation.FunctionHint;
import org.apache.flink.table.functions.TableFunction;
import org.apache.flink.types.Row;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

/**
 * canal msg解析 
 * 因为canal部分字段包含sql的关键字,所以字段名一定要加反引号
 */
@FunctionHint(output = @DataTypeHint("ROW<" +
        "`database` STRING," +
        "`table` STRING," +
        "`pkNames` ARRAY<STRING>," +
        "`isDdl` BOOLEAN," +
        "`type` STRING," +
        "`es` BIGINT," +
        "`ts` BIGINT," +
        "`sql` STRING," +
        "`sqlType` MAP<STRING,INTEGER>," +
        "`mysqlType` MAP<STRING,STRING>," +
        "`data` ARRAY<MAP<STRING,STRING>>," +
        "`old` ARRAY<MAP<STRING,STRING>>" +
        ">"))
public class CanalParse extends TableFunction<Row> {
   
    private static final Logger LOG = LoggerFactory.getLogger(CanalParseArray.class);

    public void eval(byte[] msg) {
   
        try {
   
            Message deserializer = CanalMessageDeserializer.deserializer(msg);
            List<FlatMessage> flatMessages = parseMessage(deserializer);
            
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值