让人
把table转换成为datastream的时候,做了哪些操作?
可以吧datastream API和tableAPI集合起来一起用。甚至可以一段代码的处理程序里面,前面做datastream的转换,转换成某个datastream的时候,然后再转换成表,然后调用table API做一些操作。哪种方式更容易实现需求就用哪种方式。
需要注意的是,表转换成流的时候,没有更新模式。流输出了,不可能在输出的结果基础上再修改。流之前的数据已经输出到了下游,已经溜过去了。所以upsert模式在流里面没哟办法直接做转换。
追加模式:流中数据一条一条的插入到表中。
撤回模式,追加了一个撤回的信息,并不是真正的撤回流中数据,流就像水,流出去就是收不回。
动态表
动态表是随着时间变化的。随着时间的到来而更新变化。 相当于在处理快照,不停的对快照进行做查询。
动态表和持续查询
持续查询,state储存的是之前流数据中的聚合值,而不是之前大量的数据。后来的流中来了之后,再与之进行聚合。
外部系统支持这个模式,我们才可以指定这个模式。
时间特性
处理时间
流转换成表的时候,定义时间特性,这种用的最广泛。
主要转换代码
//创建流执行环境。
val env = StreamExecutionEnvironment.getExecutionEnvironment
env.setParallelism(1)
//默认是处理时间,但是习惯性的写一下,事件时间的话就是需要设置。 env.setStreamTimeCharacteristic(TimeCharacteristic.ProcessingTime)
//创建流表环境
val tableEnv = StreamTableEnvironment.create(env)
// 从文件中读取数据。
val inpath = "D:\\code_put\\flink_tuturial\\src\\main\\resources\\Sensor.txt"
val inputStream: DataStream[String] = env.readTextFile(inpath)
val dataStream: DataStream[SensorReading_timeAndWindowTest] = inputStream.map(data => {
val strings = data.split(",")
SensorReading_timeAndWindowTest(strings(0), strings(1).toLong, strings(2).toDouble) //方法的返回值
})
val SensorTable = tableEnv.fromDataStream(dataStream,'id,'temperature,'timestamp,'pt.proctime)
这种就是得用blinplanner,引入的计算列的概念,计算出流中没有的列,并且添加进去。
事件时间
窗口
Group Windows
滚动窗口
参数是Tumble这个类,因为里面只有over这个方法,所以点省略了。同理后面的点也省略了。
滑动窗口
参数是Slide这个类,因为里面只有over这个方法,所以点省略了。同理后面的点也省略了。
会话窗口
代码中的应用
Group Windows细节
GroupwindowTable
点进去
Window方法有两个,先点进去看GroupWindowtTable的这个类。
点进去发现,里面只有一个同名的方法,也就是只能调用这个方法。
点进去这个类中。
点击ctrl +F12,就可以发现做很多操作,如下的方法。
关于window里面的参数
直接传这个类,这个类本身是一个final class
里面只有一个方法。over方法,类型是TumbleWithSize。
点进去,然后看见as方法。
继续点进去。这次终于继承了Groupwindow
代码
package com.atguigu.tableApiTests
import org.apache.flink.streaming.api.TimeCharacteristic
import org.apache.flink.streaming.api.functions.timestamps.BoundedOutOfOrdernessTimestampExtractor
import org.apache.flink.streaming.api.scala.{
DataStream, _}
import org.apache.flink.streaming.api.windowing.time.Time
import org.apache.flink.table.api.Tumble
import org.apache.flink.table.api.scala._
import org.apache.flink.table.sources.wmstrategies.BoundedOutOfOrderTimestamps
import org.apache.flink.types.Row
case class SensorReading_timeAndWindowTest (id :String, timestamp: Long, temperature:Double)
object timeAndWindowTest {
def main(args: Array[String]): Unit = {
//创建流执行环境。
val env = StreamExecutionEnvironment.getExecutionEnvironment
env.setParallelism(1)
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
//创建流表环境
val tableEnv = StreamTableEnvironment.create(env)
// 从文件中读取数据。
val inpath = "D:\\code_put\\flink_tuturial\\src\\main\\resources\\Sensor.txt"
val inputStream: DataStream[String] = env.readTextFile(inpath)
val dataStream: DataStream[SensorReading_timeAndWindowTest] = inputStream.map(data => {
val strings = data.split(",")
SensorReading_timeAndWindowTest(strings(0), strings(1).toLong, strings(2).toDouble) //方法的返回值
}).assignTimestampsAndWatermarks(new BoundedOutOfOrdernessTimestampExtractor[SensorReading_timeAndWindowTest](Time.seconds(1)) {
override def extractTimestamp(element: SensorReading_timeAndWindowTest): Long = element.timestamp *1000
} )
//将流中数据转换为---流表
val SensorTable = tableEnv.fromDataStream(dataStream,'id,'temperature,'timestamp.rowtime as 'ts) //起个别名,SQL中timestamp是关键字,防止冲突。
// 1、group window
// 1-1 table api
val resultTable = SensorTable
//每10秒统计一次滚动时间窗口
.window(Tumble.over(10.seconds).on('ts) as 'tw )
.groupBy('id, 'tw