目录
package table
import api.SensorReading
import org.apache.flink.streaming.api.scala._
import org.apache.flink.table.api.scala._
/**
*
* @PROJECT_NAME: Flink
* @PACKAGE_NAME: table
* @author: 赵嘉盟-HONOR
* @data: 2025-05-15 13:38
* @DESCRIPTION
*
*/
object Example {
def main(args: Array[String]): Unit = {
val env=StreamExecutionEnvironment.getExecutionEnvironment
val stream=env.readTextFile("Flink/src/main/resources/source.txt")
//先转换样例类(简单转换操作)
val dataStream=stream
.map(data=>{
val arr=data.split(",")
SensorReading(arr(0),arr(1).toLong,arr(2).toDouble)
})
dataStream.print()
//首先创建表执行环境
val tableEnv=StreamTableEnvironment.create(env)
//基于流创建一张表
val dataTable=tableEnv.fromDataStream(dataStream)
//调用table api 进行转换
val resultTable=dataTable
.select("id,temperature")
.filter("id='sensor_1'")
//直接用SQL实现
tableEnv.createTemporaryView("dataTable",dataTable)
val sql="select id,temperature from dataTAble where id='sensor_1'"
val resultSqlTable=tableEnv.sqlQuery(sql)
resultTable.toAppendStream[(String,Double)].print("result")
resultSqlTable.toAppendStream[(String,Double)].print("result sql")
env.execute("table api example")
}
}
这段代码展示了如何使用 Apache Flink 的 Table API 和 SQL 对流数据进行处理。以下是代码的详细解释和背景知识拓展。
代码解释
1. 环境设置
val env = StreamExecutionEnvironment.getExecutionEnvironment
val stream = env.readTextFile("Flink/src/main/resources/source.txt")
StreamExecutionEnvironment.getExecutionEnvironment
:获取流处理执行环境。env.readTextFile
:从本地文件读取数据流。
2. 数据转换
val dataStream = stream
.map(data => {
val arr = data.split(",")
SensorReading(arr(0), arr(1).toLong, arr(2).toDouble)
})
dataStream.print()
map
:将每行数据转换为SensorReading
对象,包含id
、timestamp
和temperature
字段。dataStream.print()
:打印转换后的数据流。
3. Table 环境设置
val tableEnv = StreamTableEnvironment.create(env)
StreamTableEnvironment.create
:创建 Table 执行环境,用于将流数据转换为表并进行操作。
4. 基于流创建表
val dataTable = tableEnv.fromDataStream(dataStream)
tableEnv.fromDataStream
:将dataStream
转换为 Table。
5. Table API 操作
val resultTable = dataTable
.select("id, temperature")
.filter("id = 'sensor_1'")
select
:选择id
和temperature
字段。filter
:过滤出id
为sensor_1
的数据。
6. SQL 操作
tableEnv.createTemporaryView("dataTable", dataTable)
val sql = "select id, temperature from dataTable where id = 'sensor_1'"
val resultSqlTable = tableEnv.sqlQuery(sql)
createTemporaryView
:将dataTable
注册为临时视图dataTable
。sqlQuery
:执行 SQL 查询,筛选出id
为sensor_1
的数据。
7. 结果输出
resultTable.toAppendStream[(String, Double)].print("result")
resultSqlTable.toAppendStream[(String, Double)].print("result sql")
env.execute("table api example")
toAppendStream
:将 Table 转换回数据流。print
:打印结果。env.execute
:启动流处理任务。
背景知识拓展
1. Flink Table API 和 SQL
- Table API:Flink 提供的一种声明式 API,用于处理结构化数据。它类似于 SQL,但以编程方式实现。
- SQL:Flink 支持标准 SQL 查询,可以直接对表执行 SQL 操作。
- 优势:Table API 和 SQL 提供了更简洁、直观的方式来处理数据,特别适合处理结构化数据。
2. 流与表的转换
- 流转表:通过
tableEnv.fromDataStream
将数据流转换为表。 - 表转流:通过
toAppendStream
或toRetractStream
将表转换回数据流。 - Append 模式:适用于只有插入操作的表。
- Retract 模式:适用于有更新或删除操作的表。
3. 临时视图
- 作用:将表注册为临时视图,以便在 SQL 查询中使用。
- 生命周期:临时视图的生命周期与 Flink 任务的执行周期一致。
4. Flink 的流处理与批处理
- 流处理:处理无界数据流,适用于实时场景。
- 批处理:处理有界数据集,适用于离线场景。
- 统一 API:Flink 提供了统一的 API,可以同时处理流和批数据。
5. 结构化数据处理
- 结构化数据:具有固定模式的数据,如关系型数据库中的表。
- 半结构化数据:如 JSON、XML 等。
- 非结构化数据:如文本、图像等。
6. Flink 的应用场景
- 实时数据分析:如日志分析、用户行为分析。
- 实时 ETL:将数据从源系统提取、转换并加载到目标系统。
- 事件驱动应用:如实时推荐、实时风控。
7. Flink 的生态系统
- Connectors:支持 Kafka、HDFS、JDBC 等多种数据源和目标。
- State & Checkpoint:提供状态管理和容错机制。
- CEP(Complex Event Processing):用于处理复杂事件模式。
进一步学习
- Flink 官方文档
https://flink.apache.org/docs/stable/
- Table API & SQL 教程
https://ci.apache.org/projects/flink/flink-docs-stable/dev/table/
- 流处理与批处理:了解流处理与批处理的区别与应用场景。
- SQL 语法:学习标准 SQL 语法,以便更好地使用 Flink SQL。
- Scala 编程
https://docs.scala-lang.org/
通过这段代码的学习,你可以掌握如何使用 Flink 的 Table API 和 SQL 处理流数据,并了解流与表的转换、临时视图等核心概念。