flink动态表中的窗口
Flink Window | 作用 |
---|---|
GroupWindow | 对window中的数据按照字段进行分组 |
OverWindow | 在整个Window窗口的条件下,对数据进行统计操作等 |
Table API和SQL需要引入的依赖有两个:planner和bridge。
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-table-planner_2.12</artifactId>
<version>1.10.1</version>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-table-api-java-bridge_2.12</artifactId>
<version>1.10.1</version>
</dependency>
滚动窗口
TableAPI方式
滚动窗口(Tumbling windows)要用Tumble类来定义,另外还有三个方法:
over:定义窗口长度
on:用来分组(按时间间隔)或者排序(按行数)的时间字段
as:别名,必须出现在后面的groupBy中
// Tumbling Event-time Window
.window(Tumble.over("10.minutes").on("rowtime").as("w"))
// Tumbling Processing-time Window
.window(Tumble.over("10.minutes").on("proctime").as("w"))
// Tumbling Row-count Window
.window(Tumble.over("10.rows").on("proctime").as("w"))
滑动窗口
TableAPI方式
滑动窗口(Sliding windows)要用Slide类来定义,另外还有四个方法:
over:定义窗口长度
every:定义滑动步长
on:用来分组(按时间间隔)或者排序(按行数)的时间字段
as:别名,必须出现在后面的groupBy中
// Sliding Event-time Window
.window(Slide.over("10.minutes").every("5.minutes").on("rowtime").as("w"))
// Sliding Processing-time window
.window(Slide.over("10.minutes").every("5.minutes").on("proctime").as("w"))
// Sliding Row-count window
.window(Slide.over("10.rows").every("5.rows").on("proctime").as("w"))
会话窗口
TableAPI方式
会话窗口(Session windows)要用Session类来定义,另外还有三个方法:
withGap:会话时间间隔
on:用来分组(按时间间隔)或者排序(按行数)的时间字段
as:别名,必须出现在后面的groupBy中
// Session Event-time Window
.window(Session.withGap.("10.minutes").on("rowtime").as("w"))
// Session Processing-time Window
.window(Session.withGap.("10.minutes").on("proctime").as("w"))
FlinkSQL方式
我们已经了解了在Table API里window的调用方式,同样,我们也可以在SQL中直接加入窗口的定义和使用。Group Windows在SQL查询的Group BY子句中定义。与使用常规GROUP BY子句的查询一样,使用GROUP BY子句的查询会计算每个组的单个结果行。
SQL支持以下Group窗口函数:
TUMBLE(time_attr, interval)
定义一个滚动窗口,第一个参数是时间字段,第二个参数是窗口长度。
HOP(time_attr, interval, interval)
定义一个滑动窗口,第一个参数是时间字段,第二个参数是窗口滑动步长,第三个是窗口长度。
SESSION(time_attr, interval)
定义一个会话窗口,第一个参数是时间字段,第二个参数是窗口间隔(Gap)。
另外还有一些辅助函数,可以用来选择Group Window的开始和结束时间戳,以及时间属性。
这里只写TUMBLE_*,滑动和会话窗口是类似的(HOP_*,SESSION_*)。
TUMBLE_START(time_attr, interval)
TUMBLE_END(time_attr, interval)
TUMBLE_ROWTIME(time_attr, interval)
TUMBLE_PROCTIME(time_attr, interval)
接下来就是具体的例子
Group Windows
(1)ProcessTime
1)TimeWindow
1>Tumble
package day07;
import bean.SensorReading;
import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.table.api.Table;
import org.apache.flink.table.api.Tumble;
import org.apache.flink.table.api.java.StreamTableEnvironment;
import org.apache.flink.types.Row;
public class FlinkSQL09_ProcessTime_GroupWindow_Tumble {
public static void main(String[] args) throws Exception {
//1.获取执行环境
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.setParallelism(1);
//获取TableAPI执行环境
StreamTableEnvironment tableEnv = StreamTableEnvironment.create(env);
//2.读取端口数据转换为JavaBean
SingleOutputStreamOperator<SensorReading> sensorDS = env.socketTextStream("hadoop102", 9999)
.map(line -> {
String[] fields = line.split(",");
return new SensorReading(fields[0],
Long.parseLong(fields[1]),
Double.parseDouble(fields[2]));
});
//----TableApi的形式 -----------------------------------------------------
//3.将流转换为表并指定处理时间字段
Table table = tableEnv.fromDataStream(sensorDS, "id,ts,temp,pt.proctime");
//4.基于时间的滚动窗口TableAPI
// over("10.seconds").on("pt").as("tw"),
// over("10.seconds"),表示的是窗口的大小为10s,注意是seconds
// on("pt")基于时间字段pt,
// as("tw"),是一个别名,tw。
Table tableResult = table.window(Tumble.over("10.seconds").on("pt").as("tw"))
//根据处理时间和id进行分组
.groupBy("tw,id")
.select("id,id.count,tw.start"); //可以拿到当前事件的开始时间tw.start,。
//----sql的形式---------------------------------------------------------
//5.基于时间的滚动窗口SQL API
tableEnv.createTemporaryView("sensor", table); //这里只能从table中读取数据建表,因为table中有pt这个字段。
//这里是second,不是复数。可以获取窗口的开始时间或者是结束时间--tumble_end()、tumble_start()
//也就是窗口信息也是可以拿到的。
Table sqlResult = tableEnv.sqlQuery("select id,count(id),tumble_end(pt,interval '10' second) " +
"from sensor " +
"group by id,tumble(pt,interval '10' second)");
//6.转换为流进行输出
tableEnv.toAppendStream(tableResult, Row.class).print("Table");
tableEnv.toAppendStream(sqlResult, Row.class).print("SQL");
//7.执行任务
env.execute();
}
}
2>Slide
package day07;
import bean.SensorReading;
import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.table.api.Slide;
import org.apache.flink.table.api.Table;
import org.apache.flink.table.api.Tumble;
import org.apache.flink.table.api.java.StreamTableEnvironment;
import org.apache.flink.types.Row