flink kafka写入jdbc数据库mysql,JdbcSink源码

Flink之JDBC Sink 这里介绍一下Flink Sink中jdbc sink的使用方法。 阅读详情

1. 概述

  关系型数据库是企业中业务数据存储的主要形式。MySQL 就是典型代表,尽管在大数据处理中直接与 MySQL 交互的场景不多,但最终处理的计算结果是要给外部应用消费使用的,而外部应用读取的数据存储往往就是 MySQL

2. 使用

2.1 添加依赖(注意引入的驱动版本)

    <dependency>
      <groupId>org.apache.flink</groupId>
      <artifactId>flink-connector-jdbc_${scala.binary.version}</artifactId>
      <version>${flink.version}</version>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.47</version>
    </dependency>

2.2 源码

按照批次的处理数据,需要提供的参数:

  sql:DML query (e.g. insert, update, upsert)
  statementBuilder: 设置占位符参数值
  executionOptions: 设置 batch size 和 maximum retries参数值等
  connectionOptions: 设置连接 参数, JDBC URL等
  
数据核心处理逻辑:
GenericJdbcSinkFunction类

    @Override
    public void invoke(T value, Context context) throws IOException {
        outputFormat.writeRecord(value);
    }

JdbcBatchingOutputFormat类 判断batchCount是否大于设置的批次大小,决定调用flush方法

    @Override
    public final synchronized void writeRecord(In record) throws IOException {
        checkFlushException();

        try {
            addToBatch(record, jdbcRecordExtractor.apply(record));
            batchCount++;
            if (executionOptions.getBatchSize() > 0
                    && batchCount >= executionOptions.getBatchSize()) {
                flush();
            }
        } catch (Exception e) {
            throw new IOException("Writing records to JDBC failed.", e);
        }
    }

除了按照batch大小写入数据,在JdbcBatchingOutputFormat类的open()方法中,设置有按BatchInterval定时调度,flush数据

 @Override
    public void open(int taskNumber, int numTasks) throws IOException {
        super.open(taskNumber, numTasks);
        jdbcStatementExecutor = createAndOpenStatementExecutor(statementExecutorFactory);
        if (executionOptions.getBatchIntervalMs() != 0 && executionOptions.getBatchSize() != 1) {
            this.scheduler =
                    Executors.newScheduledThreadPool(
                            1, new ExecutorThreadFactory("jdbc-upsert-output-format"));
            this.scheduledFuture =
                    this.scheduler.scheduleWithFixedDelay(
                            () -> {
                                synchronized (JdbcBatchingOutputFormat.this) {
                                    if (!closed) {
                                        try {
                                            flush();
                                        } catch (Exception e) {
                                            flushException = e;
                                        }
                                    }
                                }
                            },
                            executionOptions.getBatchIntervalMs(),
                            executionOptions.getBatchIntervalMs(),
                            TimeUnit.MILLISECONDS);
        }
    }

2.3 代码

pojo对象

public class Event {
    public String user;
    public String url;
    public long timestamp;

    public Event() {
    }

    public Event(String user, String url, Long timestamp) {
        this.user = user;
        this.url = url;
        this.timestamp = timestamp;
    }

    @Override
    public int hashCode() {
        return super.hashCode();
    }

    public String getUser() {
        return user;
    }

    public void setUser(String user) {
        this.user = user;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public Long getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(Long timestamp) {
        this.timestamp = timestamp;
    }

    @Override
    public String toString() {
        return "Event{" +
                "user='" + user + '\'' +
                ", url='" + url + '\'' +
                ", timestamp=" + new Timestamp(timestamp) +
                '}';
    }
}

flink写入mysql
  (1) 读取kafka
  (2) flatmap扁平映射
  (3) sink写入mysql

public static void main(String[] args) throws Exception {
        StreamExecutionEnvironment env =
                StreamExecutionEnvironment.getExecutionEnvironment();

        Properties properties = new Properties();
        properties.setProperty("bootstrap.servers", "192.168.42.102:9092,192.168.42.103:9092,192.168.42.104:9092");
        properties.setProperty("group.id", "consumer-group");
        properties.setProperty("key.deserializer",
                "org.apache.kafka.common.serialization.StringDeserializer");
        properties.setProperty("value.deserializer",
                "org.apache.kafka.common.serialization.StringDeserializer");
        properties.setProperty("auto.offset.reset", "latest");
        DataStreamSource<String> stream = env.addSource(new
                FlinkKafkaConsumer<String>(
                "clicks",
                new SimpleStringSchema(),
                properties
        ));

        SingleOutputStreamOperator<Event> flatMap = stream.flatMap(new FlatMapFunction<String, Event>() {
            @Override
            public void flatMap(String s, Collector<Event> collector) throws Exception {
                String[] split = s.split(",");
                collector.collect(new Event(split[0], split[1], Long.parseLong(split[2])));
            }
        });

        JdbcStatementBuilder<Event> jdbcStatementBuilder = new JdbcStatementBuilder<Event>() {
            @Override
            public void accept(PreparedStatement preparedStatement, Event event) throws SQLException {
                preparedStatement.setString(1, event.getUser());
                preparedStatement.setString(2, event.getUrl());
                preparedStatement.setLong(3,event.getTimestamp());
            }
        };
        JdbcConnectionOptions jdbcConnectionOptions = new JdbcConnectionOptions.JdbcConnectionOptionsBuilder().withUrl("jdbc:mysql://192.168.0.23/demo")
                // 对于 MySQL 5.7,用"com.mysql.jdbc.Driver"
                .withDriverName("com.mysql.jdbc.Driver")
                .withUsername("root")
                .withPassword("C/hEz8ygYA4g459j/TsQHg==htdata")
                .build();

        JdbcExecutionOptions executionOptions = JdbcExecutionOptions.builder()
                .withBatchSize(1000)
                .withBatchIntervalMs(200)
                .withMaxRetries(5)
                .build();
        flatMap.addSink(JdbcSink.sink(" insert into event (user,url,timestamp)values (?,?,?)", jdbcStatementBuilder, executionOptions, jdbcConnectionOptions));

        env.execute();
    }

结果

./kafka-console-producer.sh  --broker-list 192.168.42.102:9092,192.168.42.103:9092,192.168.42.104:9092 --topic clicks

在这里插入图片描述

在这里插入图片描述

Flink中的JDBC SQL Connector Flink中的JDBC SQL Connector JDBC 连接器允许使用 JDBC 驱动程序从任何关系数据库读取数据并将数据写入数据。 本文档介绍如何设置 JDBC 连接器以针对关系数据库运行 SQL 查询。 如果在 DDL 上定义了主键,则 JDBC sink 以 upsert 模式与外部系统交换 UPDATE/DELETE 消息,否则,它以 append 模式运行,不支持消费 UPDATE/DELETE 消息。 引入依赖 为了使用 JDBC 连接器,使用构建自动化工具(例如 Maven 或 SBT) 阅读详情

相关推荐

Flink-Connectors(连接器)(1)JDBC

什么是连接器 预定义的源和接收器 ​ Flink内置了一些基本数据源和接收器,这些数据源和接收器始终可用。该预定义的数据源包括文件、Mysql、RabbitMq、Kafka、ES 等,同时也支持数据输出到文件、Mysql、RabbitMq、Kafka、ES等。 ​ 简单的说:flink连接器就是将某些数据源加载与数据输出做了封装(连接器),我们只要引入对应的连接器依赖,即可快速的完成对数据源的加载以及数据的输出。 ​ 例如我们使用JDBC 连接器,即可快速的使用JDBC从数据库中加载数据源并支持数据通

胖虎儿的博客 8546

【Flink系列】JDBC写入调优

使用Flink开发的应用常见实时写入,即更新每一条流水的统计结果至数据库。在生产环境下,数据库为多个应用共用,那随着Flink应用的不断新增部署,数据库的写入压力越来越大,直至Flink应用出现阻塞等待、背压的情况出现,情况更严重的情况下会导致任务checkpoint超时、重启。从以上角度出发,考虑针对一些特定场景优化Flink应用,降低写入频次,减轻对数据库的压力。

马路上开飞机 2268

Flink JDBC Connector:Flink 与数据库集成最佳实践

Dialect (方言)对各个数据库来说,Dialect 体现各个数据库的特性,比如语法、数据类型等。如果需要查看详细的差异,可以点击这里[6]查看详细差异。下面通过对比 MySQL 和 Postgres 的一些常见场景举例:在数据类型上面,Flink SQL 的数据类型目前映射规则如下:Flink 目前支持三种 Dialect: Derby、MySQL、PostgreSQL,Derby 主要用于测试,更多的类型映射可以点击下方链接前往官方文档查看。......

SmartSi 3241

Scala进行的JDBC操作

Scala的操作和Java的操作大同小异: import java.sql.{Connection, DriverManager, PreparedStatement, ResultSet} object JdbcHelper { // 此处不建议使用硬编码,最好是写在专门的常量接口中或者配置文件中,此处是为了方便 val sqlUrl = "jdbc:mysql://localhost:3306/test" val user = "root" val password = "12345

鲜橙多的博客 1446

C++ 类

本文介绍了C++中类的核心概念和使用方法。

weixin_54859557的博客 1016

SAP BTP开发入门:从PaaS到CAP/UI5的30天学习路线

在云计算与数字化转型的大背景下,企业系统集成与云端扩展需求激增,传统的单点开发模式正面临深刻变革。PaaS(平台即服务)作为云原生的核心概念,将基础设施、开发环境与应用服务统一封装,为企业提供了灵活的扩展能力。SAP BTP正是SAP生态中的PaaS平台,它承载着系统集成、低代码开发、AI服务与数据管理,成为连接S/4HANA等核心业务系统与创新应用的桥梁。对于ABAP开发者而言,掌握BTP不仅是技能升级,更是应对从传统部署向云端订阅模式转型的必由之路。本文从平台基础出发,梳理BTP的核心服务与开发模型(如

weixin_31766003的博客 285

flink sink jdbc没有数据_Flink的sink实战之四:自定义

Flink官方提供的sink服务可能满足不了我们的需要,此时可以开发自定义的sink,文本就来一起实战;前文链接《Flink的sink实战之一:初探》《Flink的sink实战之二:kafka》《Flink的sink实战之三:cassandra3》继承关系在正式编码前,要先弄清楚对sink能力是如何实现的,前面我们实战过的print、kafka、cassandra等sink操作,核心类的继承关系如...

weixin_28764823的博客 490

Win10系统下Protel 99 SE元件库导入报错?3步搞定File is not recognized问题

本文详细介绍了在Win10系统下解决Protel 99 SE元件库导入报错'File is not recognized'的3步终极方案。通过手动修改配置文件、使用专用工具和优化系统兼容性设置,帮助用户快速解决这一经典PCB设计软件的兼容性问题,提升工作效率。

m3n5b7v8c9x的博客 797

【源码改造】Flink-jdbc-connector源码简析+改造支持谓词下推

flink sql在维表关联时,会有一个场景:当右表的数据量比较大且有些数据虽然符合join条件,但其实对于下游来说数据可能没用,这样就浪费了flink的计算资源,且拉低了数据处理能力。如果在join前就把维表的数据进一步过滤,然后再join,这样就会使减轻“无用数据”对flink内存的占用,提高计算能力,进而优化数据处理的能力。...............

hiliang521的博客 3492

设置Solidworks导出文件的坐标系,stl坐标系平移

使用solidworks输出的模型坐标不再原点,怎么平行坐标系,这个方法很简单

weixin_45650767的博客 1万+

使用mid360运行lio-livox对比fast-lio2

msg_type为激光雷达发出的数据格式,有livox自定义数据类型格式CustomMsg和ros标准的PointCloud2格式,因此首先需要确定激光雷达端配置的是哪种格式。可以从激光雷达的ros驱动中看到驱动端有三种格式可以选,驱动端的数字2对应lio-livox中的1,驱动端的0对应lio-livox的格式0。如果使用的是Ubuntu18.04编译完成后运行直接成功,如果使用20.04运行会报错,需要修改以下源代码。针对livox-mid360 运行lio-livox的一些问题。

z1872385的博客 1231

Flink1.11 Jdcb方式写mysql测试用例

本demo是计算窗口内wordCount然后写入mysql //数据通过jdbc方式sink到mysql windowCounts.addSink(JdbcSink.sink("replace into flink_test(words,nums) values(?,?)", new JdbcStatementBuilder<Tuple2<String, Integer>>() { @Ove.

qq_34864753的博客 1197

【研发日记】Matlab/Simulink自动生成代码(二)——五种选择结构实现方法

相比C文本类编程语言,Simulink图形化编程语言的优势是逻辑思路和数据流清晰了很多,劣势是程序执行的时序不明确,而且各个模块的配置使编程的灵活度下降了不少,在使用习惯上面总感觉有各种限制。本文就是拆解Simulink中最基础的几个编程模块,发扬它的优势,避开劣势。

Mr.Cssust的博客 3852

FlinkCDC第三部分-同步mysql到mysql,ctrl就完事~(flink版本1.16.2)

需要注意的是,BEGIN STATEMENT SET 和 COMMIT 语句是 Flink SQL 的扩展语法,它们可能在某些特定的 Flink 版本或环境中才可用。通过设置适当的检查点间隔,可以在容忍一定故障的同时,控制检查点的频率和资源使用。如果在 BEGIN STATEMENT SET 和 COMMIT 之间的任何一条语句执行失败,整个事务将回滚,即已经执行的语句会被撤销。使用这个语句的好处是可以根据作业的需求和资源情况调整这些属性,以获得最佳的性能和资源利用率。

qq_43511677的博客 9125

微信小程序 - {errCode: 10008, errno: 1500104, errMsg: “writeBLECharacteristicValue:fail write characteris

微信小程序errCode: 10008, errno: 1500104, errMsg: "writeBLECharacteristicValue:fail write characteristics error. 10008, errMsg=The value's length is invalid.",uni-app微信小程序报错,uniApp小程序调用蓝牙api报错,向低功耗蓝牙设备的某个特征写入数据时错误,UniApp微信小程序蓝牙API调用报错10008解决方案,蓝牙设备进行通信时,向设备写入数据

🏆 前端领域优质创作者 4431

瑞芯微RV1126部署YOLOv8全流程:环境搭建、pt-onnx-rknn模型转换、C++推理代码、错误解决、优化、交叉编译第三方库

瑞芯微RV1126部署YOLOv8全流程:环境搭建、pt-onnx-rknn模型转换、C++推理代码、错误解决、优化、交叉编译第三方库

C/C++、嵌入式开发、深度学习算法、模型部署与推理优化 3107

在flink-connector-jdbc中增加对国产数据库达梦(V8)的支持

本文将展示如何在flink-connector-jdbc中增加对国产数据库达梦(V8)的支持。演示基于Java语言,使用Maven。

u010782920的博客 6613

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

DataStream API(输出算子)

在上面的示例中,我们首先创建了一个 StreamExecutionEnvironment,然后创建了一个数据流。在 MyOutputFormat 类中,我们实现了 open() 方法来打开文件并设置文件名、字段分隔符等参数,writeRecord() 方法来写入数据到文件,以及 close() 方法来关闭文件。在上面的示例中,我们首先创建了一个 StreamExecutionEnvironment,然后创建了一个数据流。这样,开发人员可以更加灵活地处理数据流,并将处理后的结果存储在所需的位置。

2301_77578187的博客 1086

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Flink:JDBC Sink

Flink:JDBC Sink 使用JDBC Sink需要先导入依赖(我的Flink为1.12) <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-connector-jdbc_2.11</artifactId> <version>1.12.0</version> </dependency> 编码: 创建JDBCSi

默存的博客 2915

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Flink 将数据写入MySQL(JDBC)

在实际的生产环境中,我们经常会把Flink处理的数据写入MySQL、Doris等数据库中,下面以MySQL为例,使用JDBC的方式将Flink的数据实时数据写入MySQL。

文文x的博客 4017

JDBC(Statement & PreparedStatement)

Statement: 创建数据库: 创建表: 插入数据: 查询数据: Statement 会引入 SQL 注入问题: PreparedStatement: 通常我们执行一条 SQL 语句,得经过下面三个过程。 1. 词法和语义解析 2. 优化 SQL 语句,制定执行计划 3. 执行并返回结果 编译: 执行: 删除: SQL代码: # 预编译语句 # 编译 prepare ps from 'select * from t_us

薄荷糖 323

flink部署使用(flink-connector-jdbc)连接达梦数据库并写入读取数据

id INT,age INT) WITH (## 在 Flink SQL CLI 中查询数据## 筛选数据,比如 查询年龄大于 30 的用户:## 插入数据id INT,age INT) WITH (

飞奔的屎壳郎 3037

Flink JDBCSink使用及源码解析

以下所有都是基于Flink 1.12.0版本 Flink JDBCSink的使用 flink提供了JDBCSink方便我们写入数据库,以下是使用案例: pom依赖 需要引入flink-connector-jdbc的依赖。另外,我这里是写入mysql,所以还引入了mysql的驱动包 <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-connector-jdbc_2

upupfeng的博客 1万+

Flink SQL --JDBC connector

一、Table API & SQL 二、SQL Client 2.1、配置 1、添加依赖jar flink-connector-jdbc_2.11-1.12.3.jar mysql-connector-java-5.1.48.jar 2、重启flink stop-cluster.sh start-cluster.sh 注意: 如果不重启的话,无法加载到上面的依赖jar java.lang.ClassNotFoundException: org.apache.flink.connector.j

chbxw 5495
上一篇: Flink sink算子,kafka数据写入redis
下一篇: flink 处理迟到数据(Trigger、设置水位线延迟时间、允许窗口处理迟到数据、将迟到数据放入侧输出流、代码示例、迟到数据触发窗口计算重复结果处理)
但行益事莫问前程
但行益事莫问前程 新星创作者: 数据库技术领域 新星创作者: 数据库技术领域
博客等级 码龄7年 8490粉丝 225原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

打赏作者

但行益事莫问前程

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

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

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

打赏作者

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

抵扣说明:

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

余额充值