十四 Flink table API

本文详细介绍了 Apache Flink 的 Table API,包括创建执行环境、Catalog 中注册表、表查询(Table API 和 SQL)以及 DataStream 与 Table 之间的转换。重点讨论了各种输出模式、时间特性和窗口操作,还涵盖了 UDF(用户定义函数)的使用,如标量函数、表函数、聚合函数等,帮助读者深入理解 Flink 的数据处理流程。
摘要由CSDN通过智能技术生成

1 需要的依赖pom文件

        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-table-api-scala-bridge_${
   scala.binary.version}</artifactId>
            <version>1.10.0</version>
            <!--			<scope>provided</scope>-->
        </dependency>

        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-table-planner_2.11</artifactId>
            <version>1.10.0</version>
            <!--			<scope>provided</scope>-->
        </dependency>

        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-table-planner-blink_2.11</artifactId>
            <version>1.10.0</version>
            <!--			<scope>provided</scope>-->
        </dependency>

        <dependency>
            <groupId>org.apache.flink</groupId>
            <artifactId>flink-table-common</artifactId>
            <version>1.10.0</version>
            <!--			<scope>provided</scope>-->
        </dependency>

注意:在程序中假如隐式转换

1.1 流程

val tableEnv = ... // 创建表的执行环境

// 创建一张表,用于读取数据
tableEnv.connect(...).createTemporaryTable("inputTable")
// 注册一张表,用于把计算结果输出
tableEnv.connect(...).createTemporaryTable("outputTable")
// 通过 Table API 查询算子,得到一张结果表
val result = tableEnv.from("inputTable").select(...)
// 通过 SQL 查询语句,得到一张结果表
val sqlResult = tableEnv.sqlQuery("SELECT ... FROM inputTable ...")

// 将结果表写入输出表中
result.insertInto("outputTable")

2 创建环境

2.1 基于流处理执行环境,调 create 方法直接创建

val tableEnv = StreamTableEnvironment.create(env)

表环境(TableEnvironment)是 flink 中集成 Table API & SQL 的核心概念。它负责:
• 注册 catalog
• 在内部 catalog 中注册表
• 执行 SQL 查询
• 注册用户自定义函数
• 将 DataStream 或 DataSet 转换为表
• 保存对 ExecutionEnvironment 或 StreamExecutionEnvironment 的引用

在创建 TableEnv 的时候,可以多传入一个 EnvironmentSettings 或者 TableConfig 参数,可以
用来配置 TableEnvironment 的一些特性。

2.2 配置老版本的流式查询(Flink-Streaming-Query)

val settings = EnvironmentSettings
.newInstance()
.useOldPlanner() // 使用老版本 planner
.inStreamingMode() // 流处理模式
.build()
val tableEnv = StreamTableEnvironment.create(env, settings)

2.3 基于老版本的批处理环境(Flink-Batch-Query)

val batchEnv = ExecutionEnvironment.getExecutionEnvironment
val batchTableEnv = BatchTableEnvironment.create(batchEnv)

2.4 基于 blink 版本的流处理环境(Blink-Streaming-Query)

val bsSettings = EnvironmentSettings
.newInstance()
.useBlinkPlanner()
.inStreamingMode()
.build()
val bsTableEnv = StreamTableEnvironment.create(env, bsSettings)

2.5 基于 blink 版本的批处理环境(Blink-Batch-Query)

val bbSettings = EnvironmentSettings
.newInstance()
.useBlinkPlanner()
.inBatchMode().build()
val bbTableEnv = TableEnvironment.create(bbSettings)

2.6 案例

package test7

import test2.{
   SensorReading, SensorSource}
import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
import org.apache.flink.table.api.scala._
import org.apache.flink.api.scala._
import org.apache.flink.table.api.{
   DataTypes, EnvironmentSettings, Table}
import org.apache.flink.table.descriptors.{
   Csv, FileSystem, Schema}

object FlinkTableExample {
   
  def main(args: Array[String]): Unit = {
   
    // 创建执行环境
    val env = StreamExecutionEnvironment.getExecutionEnvironment
    env.setParallelism(1)

    // 创建表环境, 使用blink planner

    val settings = EnvironmentSettings
      .newInstance()
      .useBlinkPlanner()
      .inStreamingMode()
      .build()

    val tableEnv = StreamTableEnvironment.create(env, settings)

    tableEnv
      .connect(new FileSystem().path("/Users/yuanzuo/Desktop/flink-tutorial/FlinkSZ1128/src/main/resources/sensor.txt"))
      .withFormat(new Csv()) // 按照csv文件格式解析文件
      .withSchema( // 定义表结构
        new Schema()
          .field("id", DataTypes.STRING())
          .field("timestamp", DataTypes.BIGINT())
          .field("temperature", DataTypes.DOUBLE())
      )
      .createTemporaryTable("inputTable")    // 创建临时表

    val sensorTable: Table = tableEnv.from("inputTable") // 将临时表inputTable赋值到sensorTable
    // 使用table api
    val resultTable: Table = sensorTable
      .select("id, temperature") // 查询`id`, `temperature` => (String, Double)
      .filter("id = 'sensor_1'") // 过滤

    resultTable
        .toAppendStream[(String, Double)] // 追加流
        .print()

    // 使用flink sql的方式查询
    val resultSqlTable: Table = tableEnv
      .sqlQuery("select id, temperature from inputTable where id ='sensor_1'")

    resultSqlTable
      .toAppendStream[(String, Double)] // 追加流
      .print()

    // 将DataStream转换成流表

    val stream = env.addSource(new SensorSource)

    // 将流转换成了动态表
    val table = tableEnv.fromDataStream(stream, 'id, 'timestamp as 'ts, 'temperature as 'temp)
    table
      .select('id, 'temp) // 生成了另一张动态表
      // 将表的每一行转换成`(String, Double)`元组类型
      .toAppendStream[(String, Double)] // 将动态表转换成了流
      .print()

    // 时间属性
    // 定义处理时间
    val tableProcessingTime = tableEnv
        // `'pt.proctime`:添加处理时间,字段名是`'pt`
        .fromDataStream(stream, 'id, 'timestamp as 'ts, 'temperature as 'temp, 'pt.proctime)

    // 定义事件时间
    val tableEventTime = tableEnv
        // 将timestamp指定为事件时间,并命名为ts
        .fromDataStream(stream, 'id, 'timestamp.rowtime as 'ts, 'temperature as 'temp)

    env.execute()
  }
}

3 在 Catalog 中注册表

表(Table)的概念 TableEnvironment 可以注册目录 Catalog,并可以基于 Catalog 注册表。它会维护一个 Catalog-Table 表之间的 map。
表(Table)是由一个 “标识符” 来指定的,由 3 部分组成: Catalog 名、数据库(database)名和对象名(表名)。如果没有指定目录或数据库,就使用当前的默认值。表可以是常规的(Table,表),或者虚拟的(View,视图)。常规表(Table)一般可以用来描述外部数据,比如文件、数据库表或消息队列的数据,也可以直接从 DataStream 转换而来。视图可以从现有的表中创建,通常是 table API 或者 SQL 查询的一个结果。

3.1 连接到文件系统(Csv 格式)

连接外部系统在 Catalog 中注册表,直接调用 tableEnv.connect()就可以,里面参数要传入一个 ConnectorDescriptor,也就是 connector 描述器。对于文件系统的 connector 而言, flink 内部已经提供了,就叫做 FileSystem()。
代码如下:

<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-csv</artifactId>
<version>1.10.0</version>
</dependency>
tableEnv
.connect(new FileSystem().path("sensor.txt")) // 定义表数据来源,外部连接
.withFormat(new Csv()) // 定义从外部系统读取数据之后的格式化方法
.withSchema(
new Schema()
.field("id", DataTypes.STRING())目录 169
.field("timestamp", DataTypes.BIGINT())
.field(
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值