会话窗口
由一系列事件组合一个指定时间长度的timeout间隙组成,类似于web应用的session,也就是一段时间没有接收到新数据就会生成新的窗口。
session窗口分配器通过session活动来对元素进行分组,session窗口跟滚动窗口和滑动窗口相比,不会有重叠和固定的开始时间和结束时间的情况
session窗口在一个固定的时间周期内不再收到元素,即非活动间隔产生,那么这个窗口就会关闭。
一个session窗口通过一个session间隔来配置,这个session间隔定义了非活跃周期的长度,当这个非活跃周期产生,那么当前的session将关闭并且后续的元素将被分配到新的session窗口中去。
特点
- 会话窗口不重叠,没有固定的开始和结束时间
- 与翻滚窗口和滑动窗口相反, 当会话窗口在一段时间内没有接收到元素时会关闭会话窗口。
- 后续的元素将会被分配给新的会话窗口
<!--flink核心包-->
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-java</artifactId>
<version>1.7.2</version>
</dependency>
<!--flink流处理包-->
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-streaming-java_2.12</artifactId>
<version>1.7.2</version>
<scope>provided</scope>
</dependency>
发送
netcat下载:
nc -lk 7777
import org.apache.flink.api.common.functions.MapFunction;
import org.apache.flink.api.java.ExecutionEnvironment;
import org.apache.flink.api.java.tuple.Tuple;
import org.apache.flink.api.java.tuple.Tuple1;
import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.datastream.KeyedStream;
import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
import org.apache.flink.streaming.api.datastream.WindowedStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.functions.windowing.WindowFunction;
import org.apache.flink.streaming.api.windowing.assigners.ProcessingTimeSessionWindows;
import org.apache.flink.streaming.api.windowing.time.Time;
import org.apache.flink.streaming.api.windowing.windows.TimeWindow;
import org.apache.flink.util.Collector;
public class SessionWindowDemo {
public static void main(String[] args) throws Exception {
// 获取数据源
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
String hostname = "";
int port = 7777;
DataStreamSource<String> data = env.socketTextStream(hostname, port);
// 创建窗口(TimeWindow)
// 1.MapFunction第一个泛型表示输入的数据类型,第二个泛型表示输出的数据类型
SingleOutputStreamOperator<Tuple1<String>> tupled = data.map(new MapFunction<String, Tuple1<String>>() {
/**
* 键输入的字符串转成一元组
* @param s 输入的字符串
* @return 转化后的一元组
* @throws Exception
*/
public Tuple1<String> map(String s) throws Exception {
return new Tuple1<String>(s);
}
});
// 2.按照一元组第一个元素分组(只有一个元素只能写0)
KeyedStream<Tuple1<String>, Tuple> keyed = tupled.keyBy(0);
// 3.获取事件滑窗口
// 数据不断涌入,当停留时间超过5秒没有产生新数据,则会生成一个新窗口,新数据流入新窗口中
WindowedStream<Tuple1<String>, Tuple, TimeWindow> sessionWindow = keyed.window(ProcessingTimeSessionWindows.withGap(Time.seconds(5)));
// 利用时间滚动窗口对一个窗口内的数据进行处理
// WindowFunction第一个泛型就是输入数据的数据类型;第二个泛型就是输出数据的数据类型;
// 第三个就是key的数据类型;第四个就是窗口的数据类型
SingleOutputStreamOperator<String> result = sessionWindow.apply(new WindowFunction<Tuple1<String>, String, Tuple, TimeWindow>() {
/**
* 数据具体处理过程
* @param tuple key就是分组key
* @param timeWindow 时间滚动窗口
* @param iterable key组内的成员
* @param collector 数据处理后返回的结果的对象
* @throws Exception
*/
public void apply(Tuple tuple, TimeWindow timeWindow, Iterable<Tuple1<String>> iterable, Collector<String> collector) throws Exception {
for (Tuple1<String> t : iterable) {
collector.collect(t.getField(0).toString());
}
}
});
result.print();
env.execute();
}
}