Flink Sql 自定义实现 kudu connector

Flink自定义connector官方例子记录 Flink自定义connector官方例子Socket 文章目录Flink自定义connector官方例子Socket前言具体步骤1.整体概括运行时Planning 计划阶段Factory阶段2.以Test例子Debug记录2.02.12.22.42.52.62.72.82.9总结 前言 本次记录flinksql的官方记录的socket自定义连接器的实现。 具体步骤 1.整体概括 如图: 接触一个完整的connector的总共大概分为三个主要步骤 运行时 这里其实可以从这里先接入,我们需要在运行时提供出 阅读详情

Flink Sql 自定义实现 kudu connector


众所周知啊,flinksql 中与其他的存储做数据的传输连接的时候,是需要有独特的连接器的,mysql redis es hbase kudu ,不同的存储他们自己使用的协议与操作都不一样,所以需要相应的连接器来连接,这个帖子主要讲一下怎么实现自定义的flink sql connector ,不只局限于kudu ,其他的连接器都是这个原理

原理

其实原理跟从网上下载的 mysql连接器一样,打包编译,添加好pom文件,sql解析时,会根据程序中配置的connector 来做判断是那种解析器,然后与pom中引入的解析器做匹配。

那么具体要如何开发引入一个connector呢?

简单来说需要三个东西
sink类实例 : KuduDynamicTableSink
工厂类: KuduDynamicTableFactory
以及一个配置文件:org.apache.flink.table.factories.Factory

其实主要利用了java的SPI原理,用户需要在工程的resources中新建一个文件
在这里插入图片描述
这里放什么呢,放的是 用户开发的 工厂类的地址
com.datacenter.connectors.kudu.table.KuduDynamicTableFactory
原因就是,SPI会从这个文件中找到工厂类,然后由工厂类来构造出sink实例供sql解析出的对象使用

实现

KuduDynamicTableSink:

package com.datacenter.streaming.sql.connectors.kudu.table;

import com.datacenter.streaming.sql.connectors.kudu.KuduOptions;
import com.datacenter.streaming.sql.connectors.kudu.KuduOutputFormat;
import com.datacenter.streaming.sql.connectors.kudu.KuduSinkOptions;
import org.apache.flink.table.api.TableSchema;
import org.apache.flink.table.api.constraints.UniqueConstraint;
import org.apache.flink.table.connector.ChangelogMode;
import org.apache.flink.table.connector.sink.DynamicTableSink;
import org.apache.flink.table.connector.sink.OutputFormatProvider;
import org.apache.flink.types.RowKind;

import java.util.List;

import static org.apache.flink.util.Preconditions.checkState;

/**
 * KuduDynamicTableSink
 * @author loveyou
 */
public class KuduDynamicTableSink implements DynamicTableSink {

    private final KuduOptions kuduOptions;
    private final KuduSinkOptions kuduSinkOptions;
    private TableSchema physicalSchema;
    private int bufferFlushInterval;
    private int maxRetries;

    private List<String> keyFields;

    public KuduDynamicTableSink(KuduOptions kuduOptions, KuduSinkOptions kuduSinkOptions, TableSchema physicalSchema) {
        this.kuduOptions = kuduOptions;
        this.kuduSinkOptions = kuduSinkOptions;
        this.physicalSchema = physicalSchema;
        UniqueConstraint uniqueConstraint = physicalSchema.getPrimaryKey().orElse(null);
        if (uniqueConstraint != null) {
            this.keyFields = uniqueConstraint.getColumns();
        }
        this.bufferFlushInterval = (int) kuduSinkOptions.getBatchIntervalMs();
        this.maxRetries = kuduSinkOptions.getMaxRetries();
    }

    @Override
    public ChangelogMode getChangelogMode(ChangelogMode requestedMode) {
        validatePrimaryKey(requestedMode);
        return ChangelogMode.newBuilder()
                .addContainedKind(RowKind.INSERT)
                .addContainedKind(RowKind.UPDATE_AFTER)
                .build();
    }

    @Override
    public SinkRuntimeProvider getSinkRuntimeProvider(Context context) {
        KuduOutputFormat kuduOutputFormat = new KuduOutputFormat(
                kuduOptions.getMaster(),
                kuduOptions.getTable(),
                physicalSchema.getFieldNames(),
                physicalSchema.getFieldDataTypes(),
                bufferFlushInterval,
                maxRetries
        );

        return OutputFormatProvider.of(kuduOutputFormat);
    }

    @Override
    public DynamicTableSink copy() {
        return new KuduDynamicTableSink(
                kuduOptions,
                kuduSinkOptions,
                physicalSchema);
    }

    @Override
    public String asSummaryString() {
        return null;
    }

    private void validatePrimaryKey(ChangelogMode requestedMode) {
        checkState(ChangelogMode.insertOnly().equals(requestedMode) || keyFields == null,
                "please declare primary key for sink table when query contains update/delete record.");
    }
}

package com.datacenter.streaming.sql.connectors.kudu.table;

import com.datacenter.streaming.sql.connectors.kudu.KuduLookupOptions;
import com.datacenter.streaming.sql.connectors.kudu.KuduOptions;
import com.datacenter.streaming.sql.connectors.kudu.KuduSinkOptions;
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.sink.DynamicTableSink;
import org.apache.flink.table.connector.source.DynamicTableSource;
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.utils.TableSchemaUtils;
import org.apache.flink.util.Preconditions;

import java.time.Duration;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

/**
 * KuduDynamicTableFactory
 * @author loveyou
 */
public class KuduDynamicTableFactory implements DynamicTableSourceFactory, DynamicTableSinkFactory {

    // common options
    public static final String IDENTIFIER = "kudu";
    public static final ConfigOption<String> MASTER = ConfigOptions
            .key("master")
            .stringType()
            .noDefaultValue()
            .withDescription("the kudu master address.");
    public static final ConfigOption<String> TABLE = ConfigOptions
            .key("table")
            .stringType()
            .noDefaultValue()
            .withDescription("the jdbc table name.");
    public static final ConfigOption<String> USERNAME = ConfigOptions
            .key("username")
            .stringType()
            .noDefaultValue()
            .withDescription("the jdbc user name.");
    public static final ConfigOption<String> PASSWORD = ConfigOptions
            .key("password")
            .stringType()
            .noDefaultValue()
            .withDescription("the jdbc password.");


    // lookup options
    private static final ConfigOption<Long> LOOKUP_CACHE_MAX_ROWS = ConfigOptions
            .key("lookup.cache.max-rows")
            .longType()
            .defaultValue(-1L)
            .withDescription("the max number of rows of lookup cache, over this value, the oldest rows will " +
                    "be eliminated. \"cache.max-rows\" and \"cache.ttl\" options must all be specified if any of them is " +
                    "specified. Cache is not enabled as default.");
    private static final ConfigOption<Duration> LOOKUP_CACHE_TTL = ConfigOptions
            .key("lookup.cache.ttl")
            .durationType()
            .defaultValue(Duration.ofSeconds(-1))
            .withDescription("the cache time to live.");
    private static final ConfigOption<Integer> LOOKUP_MAX_RETRIES = ConfigOptions
            .key("lookup.max-retries")
            .intType()
            .defaultValue(3)
            .withDescription("the max retry times if lookup database failed.");

    // write options
    //private static final ConfigOption<Integer> SINK_BUFFER_FLUSH_MAX_ROWS = ConfigOptions
    //        .key("sink.buffer-flush.max-rows")
    //        .intType()
    //        .defaultValue(100)
    //        .withDescription("the flush max size (includes all append, upsert and delete records), over this number" +
    //                " of records, will flush data. The default value is 100.");
    private static final ConfigOption<Duration> SINK_BUFFER_FLUSH_INTERVAL = ConfigOptions
            .key("sink.buffer-flush.interval")
            .durationType()
            .defaultValue(Duration.ofSeconds(1))
            .withDescription("the flush interval mills, over this time, asynchronous threads will flush data. The " +
                    "default value is 1s.");
    private static final ConfigOption<Integer> SINK_MAX_RETRIES = ConfigOptions
            .key("sink.max-retries")
            .intType()
            .defaultValue(3)
            .withDescription("the max retry times if writing records to database failed.");

    /**
     * DynamicTableSource 实例
     *
     * @param context
     * @return
     */
    @Override
    public DynamicTableSource createDynamicTableSource(Context context) {
        final FactoryUtil.TableFactoryHelper helper = FactoryUtil.createTableFactoryHelper(this, context);
        final ReadableConfig config = helper.getOptions();
        helper.validate();
        validateConfigOptions(config);
        TableSchema physicalSchema = TableSchemaUtils.getPhysicalSchema(context.getCatalogTable().getSchema());
        return new KuduDynamicTableSource(
                getKuduOptions(helper.getOptions()),
                getKuduLookupOptions(helper.getOptions()),
                physicalSchema);
    }

    /**
     * DynamicTableSink 实例
     *
     * @param context
     * @return
     */
    @Override
    public DynamicTableSink createDynamicTableSink(Context context) {
        final FactoryUtil.TableFactoryHelper helper = FactoryUtil.createTableFactoryHelper(this, context);
        final ReadableConfig config = helper.getOptions();
        helper.validate();
        validateConfigOptions(config);
        TableSchema physicalSchema = TableSchemaUtils.getPhysicalSchema(context.getCatalogTable().getSchema());
        return new KuduDynamicTableSink(
                getKuduOptions(config),
                getKuduSinkOptions(config),
                physicalSchema);
    }

    private KuduOptions getKuduOptions(ReadableConfig readableConfig) {
        KuduOptions.KuduOptionsBuilder builder = KuduOptions.builder()
                .master(readableConfig.get(MASTER))
                .table(readableConfig.get(TABLE));
        readableConfig.getOptional(USERNAME).ifPresent(builder::username);
        readableConfig.getOptional(PASSWORD).ifPresent(builder::password);
        return builder.build();
    }

    private KuduLookupOptions getKuduLookupOptions(ReadableConfig readableConfig) {
        KuduLookupOptions.KuduLookupOptionsBuilder builder = KuduLookupOptions.builder();
        builder.cacheMaxSize(readableConfig.get(LOOKUP_CACHE_MAX_ROWS));
        builder.cacheExpireMs(readableConfig.get(LOOKUP_CACHE_TTL).toMillis());
        builder.maxRetryTimes(readableConfig.get(LOOKUP_MAX_RETRIES));

        return builder.build();
    }

    private KuduSinkOptions getKuduSinkOptions(ReadableConfig config) {
        KuduSinkOptions.KuduSinkOptionsBuilder builder = KuduSinkOptions.builder();
        //builder.batchSize(config.get(SINK_BUFFER_FLUSH_MAX_ROWS));
        builder.batchIntervalMs(config.get(SINK_BUFFER_FLUSH_INTERVAL).toMillis());
        builder.maxRetries(config.get(SINK_MAX_RETRIES));
        return builder.build();
    }


    /**
     * 工厂唯一标识符
     *
     * @return
     */
    @Override
    public String factoryIdentifier() {
        return IDENTIFIER;
    }

    /**
     * 必选项
     *
     * @return
     */
    @Override
    public Set<ConfigOption<?>> requiredOptions() {
        Set<ConfigOption<?>> requiredOptions = new HashSet<>();
        requiredOptions.add(MASTER);
        requiredOptions.add(TABLE);
        return requiredOptions;
    }

    /**
     * 可选项
     *
     * @return
     */
    @Override
    public Set<ConfigOption<?>> optionalOptions() {
        Set<ConfigOption<?>> optionalOptions = new HashSet<>();
        optionalOptions.add(USERNAME);
        optionalOptions.add(PASSWORD);

        optionalOptions.add(LOOKUP_CACHE_MAX_ROWS);
        optionalOptions.add(LOOKUP_CACHE_TTL);
        optionalOptions.add(LOOKUP_MAX_RETRIES);

        //optionalOptions.add(SINK_BUFFER_FLUSH_MAX_ROWS);
        optionalOptions.add(SINK_BUFFER_FLUSH_INTERVAL);
        optionalOptions.add(SINK_MAX_RETRIES);
        return optionalOptions;
    }


    /**
     * 验证配置
     *
     * @param config
     */
    private void validateConfigOptions(ReadableConfig config) {
        checkAllOrNone(config, new ConfigOption[]{
                USERNAME,
                PASSWORD
        });

        checkAllOrNone(config, new ConfigOption[]{
                LOOKUP_CACHE_MAX_ROWS,
                LOOKUP_CACHE_TTL
        });

        Preconditions.checkArgument(
                config.get(SINK_BUFFER_FLUSH_INTERVAL).compareTo(Duration.ofSeconds(1)) >= 0,
                SINK_BUFFER_FLUSH_INTERVAL.key() + " must >= 1000"
        );
    }

    /**
     * 要么一个都没有,要么都要有
     *
     * @param config
     * @param configOptions
     */
    private void checkAllOrNone(ReadableConfig config, ConfigOption<?>[] configOptions) {
        int presentCount = 0;
        for (ConfigOption configOption : configOptions) {
            if (config.getOptional(configOption).isPresent()) {
                presentCount++;
            }
        }
        String[] propertyNames = Arrays.stream(configOptions).map(ConfigOption::key).toArray(String[]::new);
        Preconditions.checkArgument(configOptions.length == presentCount || presentCount == 0,
                "Either all or none of the following options should be provided:\n" + String.join("\n", propertyNames));
    }
}

看代码中
调用工厂类,由工厂类实现的DynamicTableSinkFactory接口汇总的create方法,来返回一个KuduDynamicTableSink 方法实例。

完成后 可以把这个代码片段拷贝进你的java项目中 ,在 pom中 添加

<modules>
	<module>connector-kudu</module>
</modules>

或者直接打包成jar 用 idea 自带的 package 直接 打包
在这里插入图片描述

,将jar拷贝进你的本地仓库,像引入mysql connector一样的方式来引入文件

所有代码都在我的git上,需要的同学可以自取,如果找不到可以私信我

Hadoop生态全景解析:从HDFS/YARN到Spark/Flink的工程本质 分布式数据处理是现代大数据平台的核心能力,其底层依赖于可靠的分布式存储与智能资源调度。HDFS通过多副本与心跳机制实现统计级高可用,YARN解耦计算与存储资源,为Spark、Flink等引擎提供统一调度基础。MapReduce定义了‘移动计算而非数据’的范式,Spark以内存计算优化迭代任务,Flink则通过事件时间与状态管理实现真正流批一体。HBase弥补HDFS随机读写短板,Kafka承担高吞吐数据管道角色,Hive作为SQL翻译层降低使用门槛。这些组件并非孤立工具,而是围绕数据生命周期协同演进的有机系 阅读详情

相关推荐

Azure数据管道工程化实战:从脏数据处理到星型模型构建

数据管道是现代数据平台的核心基础设施,其本质是将原始、异构、不可信的数据,通过可编排、可监控、可回滚的批处理流程,转化为可信、一致、可分析的业务资产。核心原理在于分层治理(Bronze/Silver/Gold)、职责隔离与失败即状态的设计哲学。技术价值体现在提升数据可信度、降低运维成本、满足合规审计,并支撑下游BI与AI应用。典型应用场景包括零售销量预警、金融交易对账、IoT设备指标聚合等T+1分析需求。本项目以Azure Data Factory为编排中枢,结合Azure Functions做数据质量守门

weixin_30797199的博客 690

Flink SQL自定义connector

本文翻译自:Flink v1.11官方文档 动态表是Flink的Table&SQL API的核心概念,用于以统一方式处理有界和无界数据。 因为动态表只是一个逻辑概念,所以Flink并不拥有数据本身。 相反,动态表的内容存储在外部系统(例如数据库,键值存储,消息队列)或文件中。 动态源(Dynamic sources)和动态接收器(Dynamic sinks)可用于从外部系统读取和写入数据。 在文档中,源(sources)和接收器(sinks)通常可以统称为连接器(connector)。 Flink为Kafk

integrity 4753

空0026

26。

Direction_Wind的博客 2115

Flink SQL 自定义 Connector

flink sql 自定义 connector

lck_csdn的博客 3476

flink-connector-kudu:基于Apache-bahir-kudu-connector的flink-connector-kudu,支持Flink1.11.x DynamicTableSourceSink,支持范围分区等

Kudu连接器 基于Apache-Bahir-Kudu连接器改造而来的满足公司内部使用的Kudu连接器,支持特性范围分区,定义哈希分桶数,支持Flink1.11.x动态数据源等,改造后已贡献部分功能给社区。 使用姿势 clone代码后,改造pom项目坐标后上传公司私服使用 Kudu目录使用 创建目录 StreamExecutionEnvironment env = StreamExecutionEnvironment . getExecutionEnvironment(); catalog = new KuduCatalog ( " cdh01:7051,cdh02:7051,cdh03:7051 " ); tableEnv = KuduTableTestUtils . createTableEnvWithBlinkPlannerStreamingMode(env); tableEnv .

Bochs源码分析 - 26:8259中断控制器介绍

前言 现在我们跟着《x86/x64体系探索及编程》来分析17章内容 -- 8259中断控制器。这个是涉及硬件的,很遗憾,除了大学期间使用STM32搞过一个计算器,其余就没多少硬件编程经验,我在淘宝上找了下大概是这个东东。 https://pdos.csail.mit.edu/6.828/2010/readings/hardware/8259A.pdf 上面是8259A的芯片手册,里面讲的还是挺详细的,虽然里面很多东西还是看不太懂,但是结合着《x86/...

WriteAnything_的博客 971

Flink Sql 读写操作 Kudu 使用bahir 编译 Flink Kudu Connector

编译 Flink Kudu Connector 以支持使用 flink sql 操作读写KUDU

wrj_java的博客 1976

Xcelium XRUN实用指南:从入门到高效仿真

本文是Xcelium XRUN仿真工具的实用指南,从基础入门到高效应用全面解析。XRUN作为Cadence Xcelium的统一命令行入口,能自动化编译、精细和仿真流程,大幅提升数字芯片与FPGA验证效率。文章详细介绍了最简命令、波形调试、增量编译、多核并行仿真等核心功能,并提供了管理复杂项目、性能调优与深度调试的进阶技巧,帮助工程师快速上手并精通这一高效仿真工具。

weixin_29238147的博客 742

Flink SQL自定义TableSource读取Kudu数据

本文基于Flink1.9,之前文章基于Flink1.6。在Flink的官方文档中提供了很多connector用于连接外部系统数据源。如果提供的connector不能满足需要,还可以通过自定义方式定义读取外部数据源的逻辑。本文的背景就是使用SQL查询批量数据,但是批量数据存储在kudu中,由于没有提供connector所以需要自定义读取数据逻辑。 官方文档中给出了自定义批量数据读取的实现方式: ...

A coder of life 6546

看不懂分子动力学模拟的结果?一文读懂RMSD曲线

随后,将每一帧结构与初始模板进行叠合,计算对应原子的平均偏移量,即RMSD。总之,掌握 RMSD 的解读方法,就等于抓住了评估分子动力学模拟成败与质量的“总开关”。①在模拟初始阶段,RMSD会从0迅速上升,这是蛋白质从静态晶体或模型结构释放到溶液环境中并逐渐适应的正常过程。②经过一段时间后,曲线不再系统性上升或下降,而是围绕一个平均值,小幅度地上下波动,形成一个稳定的“平台”。这种情况下,RMSD 在初始快速上升后,并未进入平台,而是持续甚至加速上升,始终未见收敛。🔍 如何解读不同趋势的RMSD曲线。

weixin_46587777的博客 4901

【数据分析/商业分析】面试题整理——SQL专题

数据分析\商业分析—面试题整理 自己总结的SQL类的面试题 文章目录数据分析\商业分析—面试题整理1.新增用户2.活跃用户数量3.连续登录4.次(n)日留存5.每个科目下分数最高的两名学生

awater_17的博客 1859

大数据平台测试-elasticsearch、mysql、kudu、starrocks、print、hive、Datagen、hbase、tidb、hudi

最近在测试flink实时计算平台最近迭代增加了 elasticsearch 7的 Connector ,所以要把平台内所有的数据源实例类型测试一遍。flink中的数据源实例类型有elasticsearch、mysql、kudu、starrocks、print、hive、Datagen、hbase、tidb。。。证明新增的Connector对其他的Flink SQL 写入其他数据库无影响。或者说其他数据源的写入正常。这里写下job写入对应的表后该怎么查询1、elasticsearch 6 与 elastics

全村的希望的博客 1805

PVE启动卡在loading initial ramdisk

pve显卡直通导致的异常解决

学而时习之 6692

Flink从kafka读取数据写入到mysql中,然后任务提交到集群

1、maven依赖 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.o

bigdata_users的博客 616

k3s cpu load 和 cpu 使用率很高处理

在这期间还执行过缩减 sqlite3 数据库操作,不知道是哪个操作起了作用,亦或者两个操作有影响,删除 ns 促进了数据库缩减的执行(没删除之前数据库缩减不成功,db文件大小未减小,但不确定是不是执行完 VACUUM 之后需要时间 db 文件才会减小,或者是因为删除了 ns 才导致其减小),再或者是两个操作都起了作用。kubectl get ns 发现有很多卡在删除状态的 ns。k3s 官网关于这个问题的谈论。执行如下脚本删除掉这些 ns。有人详细说过这个问题。

weixin_40548182的博客 685

Python爬虫实战 | 拼多多商品评论采集与深度分析

本文从 API 调用、网页渲染到情感分析与关键词提取,全流程剖析了“拼多多商品评论采集与分析”项目。Scrapy + API 可快速抓取评论;Playwright 可突破 API 限制,抓取完整页面内容;数据清洗 + 分析揭示用户真实反馈;可持续部署、扩展至更多商品 & 时间段;

2201_76125261的博客 1696

低功耗小型化稳频激光系统:基于MTS与共腔方案的架构设计与实现

稳频激光系统在精密测量、量子传感等领域至关重要,但传统PDH方案功耗高、体积大,难以满足现场应用需求。调制转移光谱(MTS)技术利用原子跃迁谱线作为频率参考,无需超稳腔,从原理上降低了系统复杂度和功耗。通过选用DFB激光器、微型铷气室和低功耗微控制器,结合温控与解调算法优化,可实现秒级积分时间下10^-10量级的频率稳定度,整机功耗低于2瓦。该系统适用于便携式光谱仪、现场气体检测等场景,为稳频激光的嵌入式集成提供了可行路径。

weixin_34268753的博客 361

【OpenClaw从入门到精通】:Web控制台使用全解析——可视化配置与监控(2026实操版)

在OpenClaw的多种管理方式中,Web控制台提供了最直观、最友好的用户体验。通过图形化界面,用户可以轻松完成复杂的配置任务,实时监控系统状态,以及进行各种管理操作。对于不熟悉命令行的用户来说,Web控制台是最佳选择。

一键难忘的博客 1934

Apache SeaTunnel详解与部署(版本2.3.11)

Apache SeaTunnel是一款高性能的分布式数据集成平台,专注于实时海量数据同步。它具有丰富可扩展的连接器(支持100+数据源)、批流一体化、多引擎支持(Zeta/Flink/Spark)等特点,解决了数据源多样、同步场景复杂等技术难题。相比于DataX、Sqoop等工具,SeaTunnel在部署难度、资源占用、功能支持等方面都具有优势。部署方式支持Docker和发布包两种形式,发布包部署需配置Maven镜像、安装插件等步骤,同时提供Web管理界面便于作业监控。该平台已被近百家企业应用于生产环境,社

super_mochi1 6333

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

流式湖仓增强,Hologres + Flink构建企业级实时数仓

2023 年 12 月,由阿里云主办的实时计算闭门会在北京举行,阿里云实时数仓Hologres 研发负责人姜伟华现场分享 Hologres+Flink 构建的企业级实时数仓,实现全链路的数据实时计算、实时写入、实时更新、实时查询。同时,随着流式湖仓的兴起,Hologres 除了支持 Delta、Hudi 等通用湖格式,在今年新增了对 Paimon 的深度集成,不断拓展湖仓一体能力。

云布道师 1365

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

都在说实时数据架构,你了解多少?

作者:刘大龙@唯品会 随着互联网的发展进入下半场,数据的时效性对企业的精细化运营越来越重要, 商场如战场,在每天产生的海量数据中,如何能实时有效的挖掘出有价值的信息, 对企业的决策运营策略调整有很大帮助。此外,随着 5G 技术的成熟、广泛应用, 对于工业互联网、物联网等数据时效性要求非常高的行业,企业就更需要一套完整成熟的实时数据体系来提高自身的行业竞争力。 本文从上述现状及实时数据需求出发,结合工业界案例、笔者的实时数据开发经验, 梳理总结了实时数据体系建设的总体方案,本文主要分为三个部分: 第一

阿里云云栖号 1467

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Flink 自定义数据源Connector

flink自定义数据源

tianhouquan的专栏 5608

Flink自定义Connector

文章目录01 引言02 Connector概述2.1 Metadata - 元数据模块2.2 Planning - 规划模块2.3 Runtime - 运行时模块03 Connector相关API3.1 Dynamic Table Factories - 动态表工厂3.2 Dynamic Table Source - 动态表源3.2.1 Scan Table Source - 扫描表源3.2.2 Lookup Table Source - 查找表源3.3 Dynamic Table Sink - 动态表接

阿甘兄 4096

flink sql connector

fileSystem https://nightlies.apache.org/flink/flink-docs-release-1.14/zh/docs/connectors/table/filesystem/ CREATE TABLE MyUserTable ( column_name1 INT, column_name2 STRING, ... part_name1 INT, part_name2 STRING ) PARTITIONED BY (part_name1, part_

尤托匹亚的博客 2459

Flink使用指南: 教你Flink SQL自定义Connector开发,使用SQL入库更方便!

系列文章目录 Flink使用指南:Flink设置全局变量,并在函数中获取,让你的代码更加优雅! Flink使用指南:Checkpoint机制,完全搞懂了,你就是大佬! Flink使用指南: 面试必问内存管理模型,进大厂一定要知道! Flink使用指南: Kafka流表关联HBase维度表 Flink使用指南: Watermark新版本使用 Flink使用指南: Flink SQL自定义函数 前言 最近的工作主要是在向实时计算平台方向迁移,之前的实时计算任务都是用Flink Dat.

徐腾瑞的博客 4048

Flink系列六:Flink SQl 之常用的连接器(Connector)

动态表 & 连续查询,连接器(Connector),数据格式

weixin_52134189的博客 3587
上一篇: Flink Task退出流程与Failover机制
下一篇: flink分区与算子链
Direction_Wind
博客等级 码龄8年 6438粉丝 102原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Direction_Wind

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值