一、FlinkSQL接入Kafka数据 插入到MySQL

1、概述
1)版本说明
名称版本
flink-connector-jdbc_2.121.13.6
flink-connector-kafka_2.121.13.6
mysql-connector-java8.0.25
2)实现

1.从 Kafka 接入数据,设置水位线

2.分别使用窗口、自定义函数、业务逻辑处理对数据进行加工

3.插入数据到 MySQL

2、代码实现
import org.apache.flink.table.annotation.DataTypeHint;
import org.apache.flink.table.api.*;
import org.apache.flink.table.expressions.TimeIntervalUnit;
import org.apache.flink.table.functions.ScalarFunction;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;

import static org.apache.flink.table.api.Expressions.*;

public class KafkaSourceToMysqlSink implements Serializable {
    public static void main(String[] args) throws Exception {
        EnvironmentSettings settings = EnvironmentSettings.newInstance()
                .inStreamingMode()
                .build();

        TableEnvironment tEnv = TableEnvironment.create(settings);

        tEnv.executeSql("CREATE TABLE transactions (\n" +
                "    account_id  BIGINT,\n" +
                "    amount      BIGINT,\n" +
                "    transaction_time TIMESTAMP(3),\n" +
                "    WATERMARK FOR transaction_time AS transaction_time - INTERVAL '5' SECOND\n" +
                ") WITH (\n" +
                "    'connector' = 'kafka',\n" +
                "    'topic'     = 'transactions',\n" +
                "    'properties.bootstrap.servers' = 'xxx.xxx.xxx.x:9092',\n" +
                "    'properties.group.id' = 'test' ,\n" +
                "    'format'    = 'csv'\n" +
                ")");

        tEnv.executeSql("CREATE TABLE spend_report (\n" +
                "    account_id BIGINT,\n" +
                "    log_ts     TIMESTAMP(3),\n" +
                "    amount     BIGINT\n," +
                "    PRIMARY KEY (account_id, log_ts) NOT ENFORCED" +
                ") WITH (\n" +
                "   'connector'  = 'jdbc',\n" +
                "   'url'        = 'jdbc:mysql://localhost:3306/flink-sql?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false',\n" +
                "   'table-name' = 'spend_report',\n" +
                "   'driver'     = 'com.mysql.jdbc.Driver',\n" +
                "   'username'   = 'root',\n" +
                "   'password'   = 'root'\n" +
                ")");

        Table transactions = tEnv.from("transactions");

        report(transactions).executeInsert("spend_report");

        reportWithUdf(transactions).executeInsert("spend_report");

        reportWithWindow(transactions).executeInsert("spend_report");
    }

    /**
     * 添加业务处理逻辑
     */
    public static Table report(Table transactions) {
        return transactions.select(
                        $("account_id"),
                        $("transaction_time").floor(TimeIntervalUnit.HOUR).as("log_ts"),
                        $("amount"))
                .groupBy($("account_id"), $("log_ts"))
                .select(
                        $("account_id"),
                        $("log_ts"),
                        $("amount").sum().as("amount"));
    }

    /**
     * 添加窗口处理逻辑
     */
    public static Table reportWithWindow(Table transactions) {
        return transactions
                .window(Tumble.over(lit(1).hour()).on($("transaction_time")).as("log_ts"))
                .groupBy($("account_id"), $("log_ts"))
                .select(
                        $("account_id"),
                        $("log_ts").start().as("log_ts"),
                        $("amount").sum().as("amount"));

    }

    /**
     * 添加自定义函数处理逻辑
     */
    public static Table reportWithUdf(Table transactions) {
        return transactions.select(
                        $("account_id"),
                        call(MyFloor.class, $("transaction_time")).as("log_ts"),
                        $("amount"))
                .groupBy($("account_id"), $("log_ts"))
                .select(
                        $("account_id"),
                        $("log_ts"),
                        $("amount").sum().as("amount"));
    }
}

/**
 * 添加用户自定义函数
 */
class MyFloor extends ScalarFunction implements Serializable {
    public @DataTypeHint("TIMESTAMP(3)") LocalDateTime eval(
            @DataTypeHint("TIMESTAMP(3)") LocalDateTime timestamp) {
        return timestamp.truncatedTo(ChronoUnit.HOURS);
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Apache Flink 提供了与 Kafka 进行无缝集成的功能。使用 Flink SQL 连接 Kafka 可以轻松地将流处理和数据分析应用程序与 Kafka 集成。 以下是在 Flink SQL 中连接 Kafka 的步骤: 1. 首先,需要在 Flink 中导入 Kafka 的依赖项。可以在 pom.xml 文件中添加以下依赖项: ``` <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-connector-kafka_{scala.binary.version}</artifactId> <version>${flink.version}</version> </dependency> ``` 2. 在 Flink SQL 中,需要使用 CREATE TABLE 语句来创建与 Kafka 主题的连接。以下是一个示例 CREATE TABLE 语句: ``` CREATE TABLE myKafkaTable ( kafka_key STRING, kafka_value STRING, kafka_timestamp TIMESTAMP(3), kafka_topic STRING, kafka_partition INT, kafka_offset BIGINT ) WITH ( 'connector' = 'kafka', 'topic' = 'myKafkaTopic', 'properties.bootstrap.servers' = 'localhost:9092', 'properties.group.id' = 'myKafkaConsumerGroup', 'format' = 'json', 'scan.startup.mode' = 'earliest-offset' ) ``` 3. 在上面的示例中,`myKafkaTable` 是要创建的表的名称,`kafka_key`、`kafka_value`、`kafka_timestamp`、`kafka_topic`、`kafka_partition` 和 `kafka_offset` 是表中的列名。`'connector' = 'kafka'` 表示连接到 Kafka,`'topic' = 'myKafkaTopic'` 表示要连接的 Kafka 主题的名称,`'properties.bootstrap.servers' = 'localhost:9092'` 表示 Kafka 服务器的地址,`'properties.group.id' = 'myKafkaConsumerGroup'` 表示使用的消费者组的名称,`'format' = 'json'` 表示消息格式为 JSON,`'scan.startup.mode' = 'earliest-offset'` 表示从最早的可用偏移量开始读取消息。 4. 通过使用 Flink SQL 中的 SELECT 语句,可以从 Kafka 主题中读取和查询数据。以下是一个示例 SELECT 语句: ``` SELECT kafka_key, COUNT(*) as count FROM myKafkaTable GROUP BY kafka_key ``` 5. 最后,可以使用 Flink 中的 DataStream API 或 Table API 来处理从 Kafka 中读取的数据。 这就是在 Flink SQL 中连接 Kafka 的基本步骤。通过使用 Flink SQLKafka,可以轻松地构建流处理和数据分析应用程序。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

猫猫爱吃小鱼粮

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

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

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

打赏作者

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

抵扣说明:

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

余额充值