Flink实战之自定义flink sql connector

背景

最近工作中需要自定义开发一些flink sql的connector,因为官方提供的connector毕竟有限,在我们工作中可能会用到各种各样的中间件。所以官方没有提供的就需要我们自定义开发。
就是如:
CREATE TABLE XXX(
A STRING,
B BIGINT)
WITH(
‘connect.type’ = ‘kafka’,

)
所以开发一个自己的connector需要做哪些,本文就来总结一下开发的主要步骤,以及我遇到的问题怎么解决的。

开发

  1. 自定义Factory,根据需要实现StreamTableSourceFactory和StreamTableSinkFactory

  2. 根据需要继承ConnectorDescriptorValidator,定义自己的connector参数(with 后面跟的那些)

  3. Factory中的requiredContext、supportedProperties都比较重要,框架中对Factory的过滤和检查需要他们

  4. 需要自定义个TableSink,根据你需要连接的中间件选择是AppendStreamTableSink、Upsert、Retract

重写consumeDataStream方法

  1. 自定义一个SinkFunction,在invoke方法中实现将数据写入到外部中间件。

以上5步基本上可以写一个简单的sql-connector了

问题

  1. 异常信息:

    org.apache.flink.table.api.NoMatchingTableFactoryException: Could not find a suitable table factory for 'org.apache.flink.table.factories.TableSinkFactory' in
    the classpath.
    
    Reason: Required context properties mismatch.
    
    The following properties are requested:
    connector.address=localhost:9091
    connector.job=testJob
    connector.metrics=testMetrics
    connector.type=xxxx
    schema.0.data-type=ROW<`val` DOUBLE>
    schema.0.name=value
    

    有两个问题都导致上面的报错

    1. discoverFactory时找不到我自定义的Factory

    解决方法:

    添加如下目录及文件

在这里插入图片描述

  1. 根据properties过滤时过滤掉了我的Factory,代码在TableFactoryService#filterBySupportedProperties

​ 解决方法:在自定义Factory#supportedProperties方法中添加schema的配置

		// schema
		properties.add(SCHEMA + ".#." + SCHEMA_DATA_TYPE);
		properties.add(SCHEMA + ".#." + SCHEMA_NAME);

2.序列化问题

异常信息:

xxx类不能被序列化

原因:开始在我的sinkFunction中有个TableSchema属性,该属性不能被序列化,TableSchema我是用来获取字段信息的,后来直接改成了fieldName数组,从TableSchema.getFieldNames()获取。

改完后又报了我使用的Util类不能序列化,我把util实现了Serializable接口解决

3.sink类型不匹配问题

异常如下:

org.apache.flink.table.api.TableException: The StreamTableSink#consumeDataStream(DataStream) must be implemented and return the sink transformation DataStreamSink. However, org.apache.flink.connector.prometheus.xxxTableSink doesn't implement this method.

	at org.apache.flink.table.planner.plan.nodes.physical.stream.StreamExecSink.translateToPlanInternal(StreamExecSink.scala:142)
	at org.apache.flink.table.planner.plan.nodes.physical.stream.StreamExecSink.translateToPlanInternal(StreamExecSink.scala:48)
	at org.apache.flink.table.planner.plan.nodes.exec.ExecNode$class.translateToPlan(ExecNode.scala:58)
	at org.apache.flink.table.planner.plan.nodes.physical.stream.StreamExecSink.translateToPlan(StreamExecSi
  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
FlinkSQLFlink 中提供的一种 SQL 执行方式,它可以让用户使用 SQL 语句进行流式数据处理。在 FlinkSQL 中,自定义 Sink 可以用于将处理结果输出到外部存储介质,如 MySQL、ES 等。 首先,在自定义 Sink 之前,需要先定义一个类,继承 Flink 的 RichSinkFunction 接口。该接口包含 open、invoke 和 close 三个方法,分别用于 Sink 的初始化、数据输出和资源释放。自定义 Sink 类应该重写 invoke 方法,用于输出数据。 接下来,在 FlinkSQL 中,使用 CREATE TABLE 定义表时,可以指定表的输出方式为自定义 Sink。例如,定义一个输出流,并将结果输出到 MySQL 中,可以按以下方式定义表: ``` CREATE TABLE result ( word VARCHAR, count BIGINT ) WITH ( 'connector' = 'jdbc', 'url' = 'jdbc:mysql://localhost:3306/test', 'table-name' = 'result', 'username' = 'root', 'password' = 'root', 'sink.buffer-flush.max-rows' = '500', 'sink.buffer-flush.interval' = '2s', 'sink.max-retries' = '5' ) ``` 上述代码中,定义了一个名为 result 的表,其中 word 和 count 字段分别表示统计结果中的单词和出现次数。通过 WITH 关键字,在该表中定义了一个自定义 Sink,并指定了输出的目标地址为本地的 MySQL 数据库,配置了一些参数,如输出缓存刷写的条数、刷写的时间间隔以及重试次数等。 以上是 FlinkSQL 自定义 Sink 的简单介绍,通过自定义 Sink,在 FlinkSQL 中可以很方便地将处理结果输出到外部存储介质。同时,需要根据需求对自定义 Sink 进行优化,尽可能提高数据输出的效率和稳定性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值