Flink-将DataStream 转换成表 | 创建临时视图 | 输出到文件 | 输出到Kafka | 更新模式

GitHub

https://github.com/SmallScorpion/flink-tutorial.git

将 DataStream 转换成表

Flink允许我们把Table和DataStream做转换:我们可以基于一个DataStream,先流式地读取数据源,然后map成样例类,再把它转成Table。Table的列字段(column fields),就是样例类里的字段,这样就不用再麻烦地定义schema了。

import com.atguigu.bean.SensorReading
import org.apache.flink.streaming.api.scala._
import org.apache.flink.table.api.{DataTypes, Table}
import org.apache.flink.table.api.scala._

object DataStreamToTableTest {
  def main(args: Array[String]): Unit = {

    val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
    env.setParallelism(1)

    // 创建表环境
    val tableEnv: StreamTableEnvironment = StreamTableEnvironment.create(env)

    val inputDStream: DataStream[String] = env.readTextFile("D:\\MyWork\\WorkSpaceIDEA\\flink-tutorial\\src\\main\\resources\\SensorReading.txt")

    val dataDstream: DataStream[SensorReading] = inputDStream.map(
      data => {
        val dataArray: Array[String] = data.split(",")
        SensorReading(dataArray(0), dataArray(1).toLong, dataArray(2).toDouble)
      })

    // 常规创建
    val dataTable: Table = tableEnv.fromDataStream(dataDstream)
    // Schema基于名称
    val sensorTable = tableEnv.fromDataStream(dataDstream,
      'timestamp as 'ts, 'id as 'myId, 'temperature)
    // Schema基于位置 一一对应
    val sensorTable_lo = tableEnv.fromDataStream(dataDstream, 'myId, 'ts)


    // 测试输出
    val resultTable: Table = dataTable
      .select('id, 'temperature) // 查询id和temperature字段
      .filter('id === "sensor_1") // 输出sensor_1得数据

    resultTable.toAppendStream[ (String, Double) ].print( "data" )


    env.execute(" table DS test job")
  }
}

在这里插入图片描述
在这里插入图片描述

创建临时视图(Temporary View)

View和Table的Schema完全相同。事实上,在Table API中,可以认为View和Table是等价的。

创建临时视图的第一种方式,就是直接从DataStream转换而来。同样,可以直接对应字段转换;也可以在转换的时候,指定相应的字段。

tableEnv.createTemporaryView("sensorView", dataStream)
tableEnv.createTemporaryView("sensorView", dataStream, 'id, 'temperature, 'timestamp as 'ts)

还可以基于Table创建视图:

tableEnv.createTemporaryView("sensorView", sensorTable)

输出表

  1. 表的输出,是通过将数据写入 TableSink 来实现的
  2. TableSink 是一个通用接口,可以支持不同的文件格式、存储数据库和消息队列
  3. 输出表最直接的方法,就是通过 Table.insertInto() 方法将一个 Table 写入注册过的 TableSink 中
tableEnv.connect(...)     
	.createTemporaryTable("outputTable")
val resultSqlTable: Table = ...
resultTable.insertInto("outputTable")

输出到文件

import org.apache.flink.streaming.api.scala._
import org.apache.flink.table.api.{DataTypes, Table}
import org.apache.flink.table.api.scala._
import org.apache.flink.table.descriptors.{FileSystem, OldCsv, Schema}

object SinkToFileSystemTest {
  def main(args: Array[String]): Unit = {

    val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
    env.setParallelism(1)

    // 创建表环境
    val tableEnv: StreamTableEnvironment = StreamTableEnvironment.create(env)

    // --------------------- 读取文件数据 ---------------------------
    val filePath = "D:\\MyWork\\WorkSpaceIDEA\\flink-tutorial\\src\\main\\resources\\SensorReading.txt"

    tableEnv.connect( new FileSystem().path(filePath) ) // 定义表的数据来源,和外部系统建立连接
      .withFormat( new OldCsv() ) // 定义从外部文件读取数据之后的格式化方法
      .withSchema( new Schema() // 定义表结构
        .field("id", DataTypes.STRING())
        .field("timestamp", DataTypes.BIGINT())
        .field("temperature", DataTypes.DOUBLE())
      )
      .createTemporaryTable( "fileInputTable" ) // 在表环境中注册一张表(创建)


    val sensorTable: Table = tableEnv.from( "fileInputTable" )
    val resultTable: Table = sensorTable
      .select('id, 'temperature) // 查询id和temperature字段
      .filter('id === "sensor_1") // 输出sensor_1得数据

    resultTable.toAppendStream[ (String, Double) ].print( "FileSystem" )


    env.execute(" table connect fileSystem test job")
  }
}

在这里插入图片描述

输出到Kafka

除了输出到文件,也可以输出到Kafka。我们可以结合前面Kafka作为输入数据,构建数据管道,kafka进,kafka出。

import org.apache.flink.streaming.api.scala._
import org.apache.flink.table.api.{DataTypes, Table}
import org.apache.flink.table.api.scala._
import org.apache.flink.table.descriptors.{Csv, Kafka, Schema}

object SinkToKafkaTest {
  def main(args: Array[String]): Unit = {

    val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
    env.setParallelism(1)

    // 创建表环境
    val tableEnv: StreamTableEnvironment = StreamTableEnvironment.create(env)

    // --------------------- 消费Kafka数据 ---------------------------

    tableEnv.connect( new Kafka()
      .version( "0.11" ) // 版本
      .topic( "sensor" ) // 主题
      .property("zookeeper.connect", "hadoop102:2181")
      .property("bootstrap.servers", "hadoop102:9092")
    )
      .withFormat( new Csv() ) // 新版本得Csv
      .withSchema( new Schema()
        .field("id", DataTypes.STRING())
        .field("timestamp", DataTypes.BIGINT())
        .field("temperature", DataTypes.DOUBLE())
      )
      .createTemporaryTable( "kafkaInputTable" )

    // 查询
    val sensorTable: Table = tableEnv.from( "kafkaInputTable" )
    val resultTable: Table = sensorTable
      .select('id, 'temperature) // 查询id和temperature字段
      .filter('id === "sensor_1") // 输出sensor_1得数据

    // 定义输出的Kafka结构
    tableEnv.connect( new Kafka()
      .version( "0.11" ) // 版本
      .topic( "sensor_out" ) // 主题
      .property("zookeeper.connect", "hadoop102:2181")
      .property("bootstrap.servers", "hadoop102:9092")
    )
      .withFormat( new Csv() ) // 新版本得Csv
      .withSchema( new Schema()
        .field("id", DataTypes.STRING())
        .field("temperature", DataTypes.DOUBLE())
      )
      .createTemporaryTable( "kafkaOutputTable" )

    // 查询结果输出到Kafka中
    resultTable.insertInto("kafkaOutputTable")

    env.execute(" kafka pipeline test job")
  }
}

更新模式(Update Mode)

在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章