Flink Table 将Stream直接写入MySQL数据库

本文介绍如何使用FlinkTable的JDBCAppendTableSink将实时流数据写入MySQL数据库的具体实现过程,包括添加Maven依赖、配置数据源、定义表结构及数据处理逻辑等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Flink Table 将Stream直接写入MySQL数据库

Flink Table提供了一个JDBCAppendTableSink,可以直接往可靠地数据库中Sink数据,下面以MySQL为例:

添加Maven的pom.xml依赖

<dependency>
    <groupId>org.apache.flink</groupId>
    <artifactId>flink-jdbc_2.11</artifactId>
    <version>1.8.0</version>
</dependency>

代码如下:

public class SqlSinkJdbcStream {
    public static void main(String[] args) throws Exception {

        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        env.setParallelism(1);
        // 必须设置checkpoint的间隔时间,不然不会写入jdbc
        env.enableCheckpointing(5000L);
        StreamTableEnvironment tableEnv = StreamTableEnvironment.create(env);

        Schema schema = new Schema()
                .field("userId", Types.STRING)
                .field("name", Types.STRING)
                .field("age", Types.STRING)
                .field("sex", Types.STRING)
                .field("createTime", Types.BIG_DEC)
                .field("updateTime", Types.BIG_DEC);

        tableEnv
                .connect(
                        new Kafka().version("0.10").topic("user").property("bootstrap.servers", "localhost:9092")
                )
                .withSchema(schema)
                .withFormat(new Json().deriveSchema())
                .inAppendMode()
                .registerTableSource("Users");

        Table table = tableEnv.sqlQuery("select userId,name,age,sex,createTime,updateTime from Users");
        DataStream<Row> result = tableEnv.toAppendStream(table, TypeInformation.of(Row.class));
        result.print();

        JDBCAppendTableSink sink = new JDBCAppendTableSinkBuilder()
                .setDBUrl("jdbc:mysql://localhost:3306/test?useSSL=false")
                .setDrivername("com.mysql.jdbc.Driver")
                .setUsername("root")
                .setPassword("root")
                .setBatchSize(1000)
                .setQuery("REPLACE INTO user(userId,name,age,sex,createTime,updateTime) values(?,?,?,?,?,?)")
                .setParameterTypes(new TypeInformation[]{Types.STRING, Types.STRING, Types.STRING, Types.STRING, Types.BIG_DEC, Types.BIG_DEC})
                .build();

        tableEnv.registerTableSink("Result",
                new String[]{"userId", "name", "age", "sex", "createTime", "updateTime"},
                new TypeInformation[]{Types.STRING, Types.STRING, Types.STRING, Types.STRING, Types.BIG_DEC, Types.BIG_DEC},
                sink);

        tableEnv.insertInto(table, "Result", new StreamQueryConfig());

        env.execute("SqlSinkJdbcStream");
    }
}
// mysql的建表语句
/*
CREATE TABLE `user` (
    `userId` varchar(10) NOT NULL,
    `name` varchar(10) DEFAULT NULL,
    `age` varchar(3) DEFAULT NULL,
    `sex` varchar(10) DEFAULT NULL,
    `createTime` varchar(20) DEFAULT NULL,
    `updateTime` varchar(20) DEFAULT NULL,
    PRIMARY KEY (`userId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
*/

注意:需要设置checkpoint的true,设置checkpoint间隔时间。

### 实现Flink从Kafka读取数据并进行窗口计算后写入MySQL 为了完成这一目标,需要构建一个完整的流处理应用程序。该程序会利用Apache Flink框架来连接作为消息队列的Kafka以及关系型数据库MySQL。 #### 创建Flink项目结构 首先,在开发环境中设置一个新的Maven或Gradle项目,并引入必要的依赖项以支持Flink、Kafka连接器和JDBC驱动程序[^1]。 对于Maven配置文件pom.xml中的部分如下所示: ```xml <dependencies> <!-- Apache Flink dependencies --> <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-streaming-java_2.12</artifactId> <version>${flink.version}</version> </dependency> <!-- Kafka connector for Flink --> <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-connector-kafka_2.12</artifactId> <version>${flink.version}</version> </dependency> <!-- MySQL JDBC driver --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.30</version> </dependency> </dependencies> ``` #### 定义输入源与输出目的地 接下来定义用于接收来自Kafka的数据源以及向MySQL发送查询的目标位置。这里假设已经有一个名为`user`的表存在于MySQL中,其模式如下面SQL语句所描述[^2]: ```sql CREATE TABLE `user` ( `id` mediumint NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `age` int(11), `createDate` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; ``` #### 构建Flink作业逻辑 现在可以编写主要的应用业务逻辑了。这通常涉及到创建一个入口类(Main Class),其中包含了启动整个流程的方法。以下是简化版的例子说明如何实现这一点: ```java import org.apache.flink.api.common.serialization.SimpleStringSchema; import org.apache.flink.streaming.api.datastream.DataStreamSource; import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment; import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer; public class Main { public static void main(String[] args) throws Exception { final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); Properties properties = new Properties(); properties.setProperty("bootstrap.servers", "localhost:9092"); properties.setProperty("group.id", "test"); DataStreamSource<String> stream = env.addSource(new FlinkKafkaConsumer<>("topic-name", new SimpleStringSchema(), properties)); // 进行窗口聚合或其他变换操作... // 将结果保存至MySQL stream.map(/* 转换函数 */).addSink(/* JdbcSink 配置 */); env.execute("Flink Job Name"); } } ``` 在这个例子中,`FlinkKafkaConsumer`被用来订阅特定主题的消息;而通过调用`.map()`方法可以根据实际需求对每条记录做进一步加工处理。最后一步则是使用自定义的sink将最终的结果集持久化到外部存储系统——这里是MySQL实例上预先准备好的表格内。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值