Flink 自定义数据源Connector

概述

首先我们先来看一下自定义数据源,Flink系统提供的一些功能

我们可以从下面这个图看出来数据源的source和sink类的集成关系

当我们要实现自定义数据源的时候,我们需要先实现DynamicTableSourceFactory, DynamicTableSinkFactory这两个工厂类,在工厂类里面去实现参数定义和数据源的创建,然后再数据源DynamicTableSource和DynamicTableSink里面去初始化数据源的一些信息,最终在source类型的数据源的ScanRuntimeProvider或者LookupTableSource或者sink类型的数据源的SinkRuntimeProvider实现类里面去实现具体功能。

具体实现

第一步 实现工厂类

Dynamic Table Factories

动态表工厂用于根据目录和会话信息为外部存储系统配置动态表连接器。

org.apache.flink.table.factories.DynamicTableSourceFactory可以实现构造一个DynamicTableSource.

org.apache.flink.table.factories.DynamicTableSinkFactory可以实现构造一个DynamicTableSink.

默认情况下,使用connector选项的值作为工厂标识符和 Java 的服务提供者接口来发现工厂。

在 JAR 文件中,可以将对新实现的引用添加到服务文件中:

需要在resource目录下新建META-INF/services/目录,并且新建org.apache.flink.table.factories.Factory文件

META-INF/services/org.apache.flink.table.factories.Factory

然后在文件里面添加实现类的路径:com.flink.sql.connector.http.table.HttpDynamicTableFactory,只需要添加这个类路径就行,其他的不需要

如果没有这个文件个文件里面的内容,flink系统识别不到我们自定义的数据源信息

类文件的内容如下:HttpDynamicTableFactory.class

package com.flink.sql.connector.http.table;

import org.apache.flink.api.common.serialization.DeserializationSchema;
import org.apache.flink.api.common.serialization.SerializationSchema;
import org.apache.flink.configuration.ConfigOption;
import org.apache.flink.configuration.ConfigOptions;
import org.apache.flink.configuration.ReadableConfig;
import org.apache.flink.table.api.TableSchema;
import org.apache.flink.table.connector.format.DecodingFormat;
import org.apache.flink.table.connector.format.EncodingFormat;
import org.apache.flink.table.connector.sink.DynamicTableSink;
import org.apache.flink.table.connector.source.DynamicTableSource;
import org.apache.flink.table.data.RowData;
import org.apache.flink.table.factories.DeserializationFormatFactory;
import org.apache.flink.table.factories.DynamicTableSinkFactory;
import org.apache.flink.table.factories.DynamicTableSourceFactory;
import org.apache.flink.table.factories.FactoryUtil;
import org.apache.flink.table.factories.SerializationFormatFactory;
import org.apache.flink.table.types.DataType;
import org.apache.flink.util.Preconditions;

import java.util.HashSet;
import java.util.Optional;
import java.util.Set;

// 我这里是同时实现了source和sink,也可以单独去实现,写在一起可以减少很多重复代码
public class HttpDynamicTableFactory implements DynamicTableSourceFactory, DynamicTableSinkFactory {

/**
    首先定义一些数据源的参数信息,就是连接器的所有参数都需要先定义,这样才能在SQL里面去使用
*/
    public static final String IDENTIFIER = "http";
    public static final ConfigOption<String> URL = ConfigOptions.key("url")
            .stringType().noDefaultValue().withDescription("the jdbc database url.");
    public static final ConfigOption<String> HEADERS = ConfigOptions.key("headers")
            .stringType().noDefaultValue().withDescription("the http header.");
    private static final ConfigOption<String> BODY = ConfigOptions.key("body")
            .stringType().noDefaultValue().withDescription("the http body params.");
    private static final ConfigOption<String> TYPE = ConfigOptions.key("type")
            .stringType().noDefaultValue().withDescription("the http type.");
    private static final ConfigOption<String> FORMAT = ConfigOptions.key("format")
            .stringType().noDefaultValue().withDescription("the http type.");

    public HttpDynamicTableFactory() {
    }

// 构造source类型的数据源对象
    public DynamicTableSource createDynamicTableSource(Context context) {
        FactoryUtil.TableFactoryHelper helper = FactoryUtil.createTableFactoryHelper(this, context);
        ReadableConfig config = helper.getOptions();
        helper.validate();
        this.validateConfigOptions(config);
        HttpSourceInfo httpSourceInfo = this.getHttpSource(config);
        // discover a suitable decoding format
        final DecodingFormat<DeserializationSchema<RowData>> decodingFormat = helper.discoverDecodingFormat(
                DeserializationFormatFactory.class,
                FactoryUtil.FORMAT);

        // derive the produced data type (excluding computed columns) from the catalog table
        final DataType producedDataType = context.getCatalogTable().getSchema().toPhysicalRowDataType();


        return new HttpDynamicTableSource(httpSourceInfo, decodingFormat, producedDataType);
    }

// 构造sink类型的数据源对象
    @Override
    public DynamicTableSink createDynamicTableSink(Context context) {
        FactoryUtil.TableFactoryHelper helper = FactoryUtil.createTableFactoryHelper(this, context);
        ReadableConfig config = helper.getOptions();
        helper.validate();
        th
  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
FlinkSQL中的数据源可以通过使用connector来定义。在给出的引用中,有两个例子可以作为参考。 引用[1]中的例子展示了如何使用`datagen` connector来创建一个临时表,并通过`generateRowUdtf`函数生成新的行。具体步骤如下: 1. 创建一个临时表`test_insert`,并使用`datagen` connector作为数据源。可以通过设置参数来控制生成速率和字段的属性。 ```sql CREATE TEMPORARY table test_insert( id2 String ) WITH( 'connector' = 'datagen', 'rows-per-second'='100', 'fields.id2.kind'='random', 'fields.id2.length'='8' ); ``` 2. 创建一个系统函数`generateRowUdtf`,并将其指定为`lateral table`的参数。这个函数可以根据输入的参数生成新的行。 ```sql CREATE TEMPORARY SYSTEM FUNCTION generateRowUdtf AS 'udf2.generateRowUdtf'; ``` 3. 使用`lateral table`和`generateRowUdtf`函数来生成新的行,并将其与`test_insert`表进行连接操作。 ```sql insert into xxx SELECT T.id, T.data1, T.data2, T.data4 FROM test_insert AS S left join lateral table(generateRowUdtf(id2)) AS T(id,data1,data2,data4) on true; ``` 引用中的例子展示了如何使用自定义的UDF作为数据源。具体步骤如下: 1. 创建一个自定义connector,类似于`data-gen` connector。这个connector可以根据你的需求生成数据。 2. 创建一个UDF函数,该函数可以根据输入参数生成多列输出。 3. 使用自定义connector和UDF函数来生成数据。 以上是两个例子,你可以根据你的需求选择适合的方法来定义FlinkSQL中的数据源

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值