log4j.properties
log4j.rootLogger=warn, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.atguigu</groupId>
<artifactId>bigdata230201</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>Flink</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<flink.version>1.17.0</flink.version>
</properties>
<!--
依赖范围:
1. compile(默认的) : 主程序和测试程序都可以用。 打包时会包含在内。
2. test : 测试程序可用。打包时会排除掉。
3. provided : 主程序和测试程序都可以用。 打包时会排除掉
只在编译期生效, 运行时不可用。
-->
<dependencies>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-streaming-java</artifactId>
<version>${flink.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-clients</artifactId>
<version>${flink.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
<scope>provided</scope>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.26</version>
</dependency>
<!-- WEB UI -->
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-runtime-web</artifactId>
<version>${flink.version}</version>
<scope>provided</scope>
</dependency>
<!-- DataGen connector-->
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-connector-datagen</artifactId>
<version>${flink.version}</version>
</dependency>
<!-- file connector -->
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-connector-files</artifactId>
<version>${flink.version}</version>
<scope>provided</scope>
</dependency>
<!-- hadoop client -->
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>3.3.4</version>
<scope>provided</scope>
</dependency>
<!-- kafka connector -->
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-connector-kafka</artifactId>
<version>${flink.version}</version>
<scope>provided</scope>
</dependency>
<!-- fastJson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
<!-- jdbc connector -->
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-connector-jdbc</artifactId>
<version>3.1.0-1.17</version>
<scope>provided</scope>
</dependency>
<!-- mysql connector -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.0.32</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<excludes>
<exclude>com.google.code.findbugs:jsr305</exclude>
<exclude>org.slf4j:*</exclude>
<exclude>log4j:*</exclude>
</excludes>
</artifactSet>
<filters>
<filter>
<!-- Do not copy the signatures in the META-INF folder.
Otherwise, this might cause SecurityExceptions when using the JAR. -->
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
<transformers combine.children="append">
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer">
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
package com.atguigu.flink.func;
import com.atguigu.flink.pojo.Event;
import org.apache.flink.streaming.api.functions.source.SourceFunction;
import java.util.Random;
import java.util.concurrent.TimeUnit;
/**
* @author WEIYUNHUI
* @date 2023/6/13 10:39
* <p>
* 自定义Source , 需要实现SourceFunction
*/
public class ClickSource implements SourceFunction<Event> {
private static Boolean isRunning = true;
/**
* 每秒生成一条Event数据
*/
@Override
public void run(SourceContext<Event> ctx) throws Exception {
String[] users = {"Zhangs", "Lisi", "Tom", "Jerry", "Peiqi"};
String[] urls = {"/home", "/cart", "detail", "pay"};
Random random = new Random();
while (isRunning) {
Event event =
new Event(users[random.nextInt(users.length)], urls[random.nextInt(urls.length)], System.currentTimeMillis());//System.currentTimeMillis()
ctx.collect(event);
//休眠1秒钟
TimeUnit.SECONDS.sleep(1);
}
}
@Override
public void cancel() {
isRunning = false;
}
}
package com.atguigu.flink.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author WEIYUNHUI
* @date 2023/6/13 10:40
*
* 封装用户点击事件(点击数据)
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Event {
private String user ; // 用户
private String url ; //点击的url
private Long ts ; // 点击事件发生的时间
}
package com.atguigu.flink.timeAndwindow;
import com.atguigu.flink.func.ClickSource;
import com.atguigu.flink.pojo.Event;
import com.google.common.collect.Lists;
import org.apache.flink.api.common.eventtime.WatermarkStrategy;
import org.apache.flink.api.common.typeinfo.Types;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.functions.windowing.ProcessWindowFunction;
import org.apache.flink.streaming.api.windowing.assigners.SlidingEventTimeWindows;
import org.apache.flink.streaming.api.windowing.assigners.TumblingEventTimeWindows;
import org.apache.flink.streaming.api.windowing.time.Time;
import org.apache.flink.streaming.api.windowing.windows.TimeWindow;
import org.apache.flink.util.Collector;
import java.time.Duration;
/**
* Created by on 2023/6/18 0018 15:03
*
* @author
* 永远相信美好的事情总会发生.
* <p>
* 全窗口函数: 收集齐所有的数据后,统一计算一次输出结果。 可以获取到一些窗口相关的信息(窗口的起始和结束时间)
* * 1. WindowFunction(过时)
* * 2. ProcessWindowFunction
*/
public class Flink09_ProcessWindowFunction {
public static void main(String[] args) throws Exception {
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.setParallelism(1);
SingleOutputStreamOperator<Event> ds = env.addSource(new ClickSource())
.assignTimestampsAndWatermarks(
WatermarkStrategy.<Event>forBoundedOutOfOrderness(Duration.ZERO)
.withTimestampAssigner(
(event, ts) -> event.getTs()
)
);
ds.print("input");
//需求: 每10秒统计每个user的点击次数 需要包含窗口信息
//需求: 统计10秒内每个user的点击次数, 5秒输出一次结果。
ds.map(
event -> Tuple2.of(event.getUser(), 1)
).returns(
Types.TUPLE(Types.STRING, Types.INT)
).keyBy(
t -> t.f0
).window(
// TumblingEventTimeWindows.of(Time.seconds(10))
SlidingEventTimeWindows.of(Time.seconds(10),Time.seconds(5))
).process(
new ProcessWindowFunction<Tuple2<String, Integer>, String, String, TimeWindow>() {
@Override
public void process(String key, ProcessWindowFunction<Tuple2<String, Integer>, String, String, TimeWindow>.Context context, Iterable<Tuple2<String, Integer>> elements, Collector<String> out) throws Exception {
//汇总每个user的点击次数
int count = Lists.newArrayList(elements).size();
//获取窗口的信息
long start = context.window().getStart();
long end = context.window().getEnd();
//输出
out.collect("窗口[ " + start + " ~ " + end + " ) , 用户 " + key + " 的点击次数为: " + count);
}
}
).print();
env.execute();
}
}
input> Event(user=Zhangs, url=detail, ts=1687073571212)
input> Event(user=Jerry, url=/home, ts=1687073572217)
input> Event(user=Tom, url=detail, ts=1687073573218)
input> Event(user=Lisi, url=/cart, ts=1687073574218)
input> Event(user=Lisi, url=/home, ts=1687073575218)
窗口[ 1687073565000 ~ 1687073575000 ) , 用户 Zhangs 的点击次数为: 1
窗口[ 1687073565000 ~ 1687073575000 ) , 用户 Jerry 的点击次数为: 1
窗口[ 1687073565000 ~ 1687073575000 ) , 用户 Lisi 的点击次数为: 1
窗口[ 1687073565000 ~ 1687073575000 ) , 用户 Tom 的点击次数为: 1
input> Event(user=Zhangs, url=pay, ts=1687073576219)
input> Event(user=Tom, url=/home, ts=1687073577219)
input> Event(user=Peiqi, url=pay, ts=1687073578220)
input> Event(user=Zhangs, url=/cart, ts=1687073579220)
input> Event(user=Lisi, url=/cart, ts=1687073580220)
窗口[ 1687073570000 ~ 1687073580000 ) , 用户 Jerry 的点击次数为: 1
窗口[ 1687073570000 ~ 1687073580000 ) , 用户 Zhangs 的点击次数为: 3
窗口[ 1687073570000 ~ 1687073580000 ) , 用户 Peiqi 的点击次数为: 1
窗口[ 1687073570000 ~ 1687073580000 ) , 用户 Tom 的点击次数为: 2
窗口[ 1687073570000 ~ 1687073580000 ) , 用户 Lisi 的点击次数为: 2
input> Event(user=Jerry, url=pay, ts=1687073581220)
input> Event(user=Peiqi, url=/home, ts=1687073582220)
input> Event(user=Tom, url=pay, ts=1687073583220)
input> Event(user=Peiqi, url=detail, ts=1687073584221)
input> Event(user=Jerry, url=pay, ts=1687073585221)
窗口[ 1687073575000 ~ 1687073585000 ) , 用户 Zhangs 的点击次数为: 2
窗口[ 1687073575000 ~ 1687073585000 ) , 用户 Peiqi 的点击次数为: 3
窗口[ 1687073575000 ~ 1687073585000 ) , 用户 Lisi 的点击次数为: 2
窗口[ 1687073575000 ~ 1687073585000 ) , 用户 Tom 的点击次数为: 2
窗口[ 1687073575000 ~ 1687073585000 ) , 用户 Jerry 的点击次数为: 1
input> Event(user=Lisi, url=pay, ts=1687073586221)
input> Event(user=Tom, url=/cart, ts=1687073587222)
input> Event(user=Jerry, url=/home, ts=1687073588222)
input> Event(user=Jerry, url=/cart, ts=1687073589223)
input> Event(user=Peiqi, url=pay, ts=1687073590223)
窗口[ 1687073580000 ~ 1687073590000 ) , 用户 Jerry 的点击次数为: 4
窗口[ 1687073580000 ~ 1687073590000 ) , 用户 Tom 的点击次数为: 2
窗口[ 1687073580000 ~ 1687073590000 ) , 用户 Lisi 的点击次数为: 2
窗口[ 1687073580000 ~ 1687073590000 ) , 用户 Peiqi 的点击次数为: 2
input> Event(user=Zhangs, url=detail, ts=1687073591223)
input> Event(user=Peiqi, url=/cart, ts=1687073592224)
input> Event(user=Peiqi, url=detail, ts=1687073593225)
input> Event(user=Peiqi, url=/home, ts=1687073594226)
input> Event(user=Peiqi, url=/home, ts=1687073595226)
窗口[ 1687073585000 ~ 1687073595000 ) , 用户 Lisi 的点击次数为: 1
窗口[ 1687073585000 ~ 1687073595000 ) , 用户 Peiqi 的点击次数为: 4
窗口[ 1687073585000 ~ 1687073595000 ) , 用户 Zhangs 的点击次数为: 1
窗口[ 1687073585000 ~ 1687073595000 ) , 用户 Jerry 的点击次数为: 3
窗口[ 1687073585000 ~ 1687073595000 ) , 用户 Tom 的点击次数为: 1
input> Event(user=Jerry, url=/cart, ts=1687073596227)
input> Event(user=Tom, url=pay, ts=1687073597227)
input> Event(user=Jerry, url=pay, ts=1687073598227)
input> Event(user=Lisi, url=/cart, ts=1687073599227)
input> Event(user=Lisi, url=detail, ts=1687073600228)
窗口[ 1687073590000 ~ 1687073600000 ) , 用户 Peiqi 的点击次数为: 5
窗口[ 1687073590000 ~ 1687073600000 ) , 用户 Zhangs 的点击次数为: 1
窗口[ 1687073590000 ~ 1687073600000 ) , 用户 Lisi 的点击次数为: 1
窗口[ 1687073590000 ~ 1687073600000 ) , 用户 Jerry 的点击次数为: 2
窗口[ 1687073590000 ~ 1687073600000 ) , 用户 Tom 的点击次数为: 1
input> Event(user=Lisi, url=pay, ts=1687073601229)
input> Event(user=Zhangs, url=detail, ts=1687073602229)
input> Event(user=Tom, url=pay, ts=1687073603230)
input> Event(user=Lisi, url=/cart, ts=1687073604231)
input> Event(user=Zhangs, url=/cart, ts=1687073605232)
窗口[ 1687073595000 ~ 1687073605000 ) , 用户 Tom 的点击次数为: 2
窗口[ 1687073595000 ~ 1687073605000 ) , 用户 Lisi 的点击次数为: 4
窗口[ 1687073595000 ~ 1687073605000 ) , 用户 Jerry 的点击次数为: 2
窗口[ 1687073595000 ~ 1687073605000 ) , 用户 Zhangs 的点击次数为: 1
窗口[ 1687073595000 ~ 1687073605000 ) , 用户 Peiqi 的点击次数为: 1
input> Event(user=Jerry, url=/home, ts=1687073606232)
input> Event(user=Jerry, url=/cart, ts=1687073607232)
input> Event(user=Peiqi, url=detail, ts=1687073608232)
input> Event(user=Zhangs, url=/home, ts=1687073609232)
input> Event(user=Jerry, url=detail, ts=1687073610234)
窗口[ 1687073600000 ~ 1687073610000 ) , 用户 Tom 的点击次数为: 1
窗口[ 1687073600000 ~ 1687073610000 ) , 用户 Lisi 的点击次数为: 3
窗口[ 1687073600000 ~ 1687073610000 ) , 用户 Peiqi 的点击次数为: 1
窗口[ 1687073600000 ~ 1687073610000 ) , 用户 Zhangs 的点击次数为: 3
窗口[ 1687073600000 ~ 1687073610000 ) , 用户 Jerry 的点击次数为: 2
input> Event(user=Peiqi, url=/cart, ts=1687073611234)
input> Event(user=Peiqi, url=pay, ts=1687073612235)
input> Event(user=Peiqi, url=detail, ts=1687073613235)
input> Event(user=Tom, url=/home, ts=1687073614236)
input> Event(user=Zhangs, url=/cart, ts=1687073615237)
窗口[ 1687073605000 ~ 1687073615000 ) , 用户 Jerry 的点击次数为: 3
窗口[ 1687073605000 ~ 1687073615000 ) , 用户 Zhangs 的点击次数为: 2
窗口[ 1687073605000 ~ 1687073615000 ) , 用户 Peiqi 的点击次数为: 4
窗口[ 1687073605000 ~ 1687073615000 ) , 用户 Tom 的点击次数为: 1
input> Event(user=Jerry, url=detail, ts=1687073616237)
input> Event(user=Peiqi, url=detail, ts=1687073617238)
input> Event(user=Zhangs, url=/home, ts=1687073618238)
input> Event(user=Zhangs, url=detail, ts=1687073619239)
input> Event(user=Lisi, url=/home, ts=1687073620239)
窗口[ 1687073610000 ~ 1687073620000 ) , 用户 Zhangs 的点击次数为: 3
窗口[ 1687073610000 ~ 1687073620000 ) , 用户 Jerry 的点击次数为: 2
窗口[ 1687073610000 ~ 1687073620000 ) , 用户 Peiqi 的点击次数为: 4
窗口[ 1687073610000 ~ 1687073620000 ) , 用户 Tom 的点击次数为: 1
input> Event(user=Tom, url=/cart, ts=1687073621239)
input> Event(user=Peiqi, url=/home, ts=1687073622239)
input> Event(user=Tom, url=/cart, ts=1687073623240)
input> Event(user=Jerry, url=pay, ts=1687073624240)
input> Event(user=Jerry, url=detail, ts=1687073625240)
窗口[ 1687073615000 ~ 1687073625000 ) , 用户 Jerry 的点击次数为: 2
窗口[ 1687073615000 ~ 1687073625000 ) , 用户 Zhangs 的点击次数为: 3
窗口[ 1687073615000 ~ 1687073625000 ) , 用户 Lisi 的点击次数为: 1
窗口[ 1687073615000 ~ 1687073625000 ) , 用户 Peiqi 的点击次数为: 2
窗口[ 1687073615000 ~ 1687073625000 ) , 用户 Tom 的点击次数为: 2
input> Event(user=Lisi, url=detail, ts=1687073626240)
input> Event(user=Zhangs, url=/home, ts=1687073627241)
input> Event(user=Zhangs, url=/cart, ts=1687073628241)
input> Event(user=Lisi, url=/home, ts=1687073629241)
input> Event(user=Zhangs, url=/cart, ts=1687073630241)
窗口[ 1687073620000 ~ 1687073630000 ) , 用户 Tom 的点击次数为: 2
窗口[ 1687073620000 ~ 1687073630000 ) , 用户 Jerry 的点击次数为: 2
窗口[ 1687073620000 ~ 1687073630000 ) , 用户 Lisi 的点击次数为: 3
窗口[ 1687073620000 ~ 1687073630000 ) , 用户 Zhangs 的点击次数为: 2
窗口[ 1687073620000 ~ 1687073630000 ) , 用户 Peiqi 的点击次数为: 1
input> Event(user=Jerry, url=detail, ts=1687073631242)
input> Event(user=Tom, url=/home, ts=1687073632242)
input> Event(user=Tom, url=/home, ts=1687073633243)
input> Event(user=Peiqi, url=/home, ts=1687073634243)
input> Event(user=Lisi, url=detail, ts=1687073635243)
窗口[ 1687073625000 ~ 1687073635000 ) , 用户 Jerry 的点击次数为: 2
窗口[ 1687073625000 ~ 1687073635000 ) , 用户 Zhangs 的点击次数为: 3
窗口[ 1687073625000 ~ 1687073635000 ) , 用户 Peiqi 的点击次数为: 1
窗口[ 1687073625000 ~ 1687073635000 ) , 用户 Lisi 的点击次数为: 2
窗口[ 1687073625000 ~ 1687073635000 ) , 用户 Tom 的点击次数为: 2
input> Event(user=Peiqi, url=/cart, ts=1687073636243)
input> Event(user=Jerry, url=detail, ts=1687073637244)
input> Event(user=Jerry, url=pay, ts=1687073638244)
input> Event(user=Lisi, url=/cart, ts=1687073639245)
input> Event(user=Tom, url=/cart, ts=1687073640246)
窗口[ 1687073630000 ~ 1687073640000 ) , 用户 Zhangs 的点击次数为: 1
窗口[ 1687073630000 ~ 1687073640000 ) , 用户 Lisi 的点击次数为: 2
窗口[ 1687073630000 ~ 1687073640000 ) , 用户 Peiqi 的点击次数为: 2
窗口[ 1687073630000 ~ 1687073640000 ) , 用户 Jerry 的点击次数为: 3
窗口[ 1687073630000 ~ 1687073640000 ) , 用户 Tom 的点击次数为: 2
input> Event(user=Zhangs, url=/home, ts=1687073641246)
input> Event(user=Tom, url=pay, ts=1687073642246)
input> Event(user=Tom, url=pay, ts=1687073643247)
input> Event(user=Peiqi, url=detail, ts=1687073644247)
input> Event(user=Peiqi, url=/cart, ts=1687073645247)
窗口[ 1687073635000 ~ 1687073645000 ) , 用户 Lisi 的点击次数为: 2
窗口[ 1687073635000 ~ 1687073645000 ) , 用户 Jerry 的点击次数为: 2
窗口[ 1687073635000 ~ 1687073645000 ) , 用户 Tom 的点击次数为: 3
窗口[ 1687073635000 ~ 1687073645000 ) , 用户 Zhangs 的点击次数为: 1
窗口[ 1687073635000 ~ 1687073645000 ) , 用户 Peiqi 的点击次数为: 2
input> Event(user=Lisi, url=/cart, ts=1687073646247)
input> Event(user=Jerry, url=pay, ts=1687073647247)
input> Event(user=Tom, url=pay, ts=1687073648247)
input> Event(user=Jerry, url=pay, ts=1687073649247)
input> Event(user=Peiqi, url=detail, ts=1687073650248)
窗口[ 1687073640000 ~ 1687073650000 ) , 用户 Tom 的点击次数为: 4
窗口[ 1687073640000 ~ 1687073650000 ) , 用户 Peiqi 的点击次数为: 2
窗口[ 1687073640000 ~ 1687073650000 ) , 用户 Jerry 的点击次数为: 2
窗口[ 1687073640000 ~ 1687073650000 ) , 用户 Zhangs 的点击次数为: 1
窗口[ 1687073640000 ~ 1687073650000 ) , 用户 Lisi 的点击次数为: 1
input> Event(user=Peiqi, url=/home, ts=1687073651248)
input> Event(user=Zhangs, url=/cart, ts=1687073652249)
input> Event(user=Tom, url=pay, ts=1687073653249)
input> Event(user=Lisi, url=detail, ts=1687073654250)
input> Event(user=Lisi, url=/cart, ts=1687073655250)
窗口[ 1687073645000 ~ 1687073655000 ) , 用户 Tom 的点击次数为: 2
窗口[ 1687073645000 ~ 1687073655000 ) , 用户 Peiqi 的点击次数为: 3
窗口[ 1687073645000 ~ 1687073655000 ) , 用户 Lisi 的点击次数为: 2
窗口[ 1687073645000 ~ 1687073655000 ) , 用户 Jerry 的点击次数为: 2
窗口[ 1687073645000 ~ 1687073655000 ) , 用户 Zhangs 的点击次数为: 1
input> Event(user=Jerry, url=pay, ts=1687073656250)
input> Event(user=Zhangs, url=/home, ts=1687073657250)
input> Event(user=Zhangs, url=/cart, ts=1687073658250)
input> Event(user=Lisi, url=pay, ts=1687073659251)
input> Event(user=Jerry, url=/home, ts=1687073660251)
窗口[ 1687073650000 ~ 1687073660000 ) , 用户 Zhangs 的点击次数为: 3
窗口[ 1687073650000 ~ 1687073660000 ) , 用户 Lisi 的点击次数为: 3
窗口[ 1687073650000 ~ 1687073660000 ) , 用户 Peiqi 的点击次数为: 2
窗口[ 1687073650000 ~ 1687073660000 ) , 用户 Jerry 的点击次数为: 1
窗口[ 1687073650000 ~ 1687073660000 ) , 用户 Tom 的点击次数为: 1
input> Event(user=Tom, url=pay, ts=1687073661252)
input> Event(user=Peiqi, url=/cart, ts=1687073662252)
input> Event(user=Jerry, url=pay, ts=1687073663252)
input> Event(user=Jerry, url=/cart, ts=1687073664252)
input> Event(user=Zhangs, url=/home, ts=1687073665252)
窗口[ 1687073655000 ~ 1687073665000 ) , 用户 Lisi 的点击次数为: 2
窗口[ 1687073655000 ~ 1687073665000 ) , 用户 Zhangs 的点击次数为: 2
窗口[ 1687073655000 ~ 1687073665000 ) , 用户 Peiqi 的点击次数为: 1
窗口[ 1687073655000 ~ 1687073665000 ) , 用户 Jerry 的点击次数为: 4
窗口[ 1687073655000 ~ 1687073665000 ) , 用户 Tom 的点击次数为: 1
input> Event(user=Peiqi, url=detail, ts=1687073666253)
input> Event(user=Jerry, url=/home, ts=1687073667253)
input> Event(user=Zhangs, url=/home, ts=1687073668253)
input> Event(user=Jerry, url=/cart, ts=1687073669253)
input> Event(user=Tom, url=/home, ts=1687073670253)
窗口[ 1687073660000 ~ 1687073670000 ) , 用户 Zhangs 的点击次数为: 2
窗口[ 1687073660000 ~ 1687073670000 ) , 用户 Jerry 的点击次数为: 5
窗口[ 1687073660000 ~ 1687073670000 ) , 用户 Tom 的点击次数为: 1
窗口[ 1687073660000 ~ 1687073670000 ) , 用户 Peiqi 的点击次数为: 2
input> Event(user=Tom, url=/cart, ts=1687073671253)
input> Event(user=Lisi, url=/cart, ts=1687073672254)
input> Event(user=Jerry, url=/cart, ts=1687073673254)
input> Event(user=Tom, url=detail, ts=1687073674254)
input> Event(user=Peiqi, url=detail, ts=1687073675255)
窗口[ 1687073665000 ~ 1687073675000 ) , 用户 Peiqi 的点击次数为: 1
窗口[ 1687073665000 ~ 1687073675000 ) , 用户 Zhangs 的点击次数为: 2
窗口[ 1687073665000 ~ 1687073675000 ) , 用户 Tom 的点击次数为: 3
窗口[ 1687073665000 ~ 1687073675000 ) , 用户 Jerry 的点击次数为: 3
窗口[ 1687073665000 ~ 1687073675000 ) , 用户 Lisi 的点击次数为: 1
input> Event(user=Peiqi, url=pay, ts=1687073676255)
input> Event(user=Jerry, url=detail, ts=1687073677255)
input> Event(user=Tom, url=/cart, ts=1687073678256)
input> Event(user=Peiqi, url=detail, ts=1687073679257)
input> Event(user=Lisi, url=detail, ts=1687073680257)
窗口[ 1687073670000 ~ 1687073680000 ) , 用户 Tom 的点击次数为: 4
窗口[ 1687073670000 ~ 1687073680000 ) , 用户 Jerry 的点击次数为: 2
窗口[ 1687073670000 ~ 1687073680000 ) , 用户 Peiqi 的点击次数为: 3
窗口[ 1687073670000 ~ 1687073680000 ) , 用户 Lisi 的点击次数为: 1
input> Event(user=Jerry, url=/home, ts=1687073681257)
input> Event(user=Jerry, url=detail, ts=1687073682258)
input> Event(user=Jerry, url=pay, ts=1687073683258)
input> Event(user=Zhangs, url=detail, ts=1687073684259)
input> Event(user=Zhangs, url=detail, ts=1687073685259)
窗口[ 1687073675000 ~ 1687073685000 ) , 用户 Jerry 的点击次数为: 4
窗口[ 1687073675000 ~ 1687073685000 ) , 用户 Peiqi 的点击次数为: 3
窗口[ 1687073675000 ~ 1687073685000 ) , 用户 Zhangs 的点击次数为: 1
窗口[ 1687073675000 ~ 1687073685000 ) , 用户 Lisi 的点击次数为: 1
窗口[ 1687073675000 ~ 1687073685000 ) , 用户 Tom 的点击次数为: 1
input> Event(user=Zhangs, url=/home, ts=1687073686259)
input> Event(user=Peiqi, url=/cart, ts=1687073687259)
input> Event(user=Zhangs, url=pay, ts=1687073688259)
input> Event(user=Zhangs, url=/home, ts=1687073689260)
input> Event(user=Lisi, url=/home, ts=1687073690260)
窗口[ 1687073680000 ~ 1687073690000 ) , 用户 Zhangs 的点击次数为: 5
窗口[ 1687073680000 ~ 1687073690000 ) , 用户 Lisi 的点击次数为: 1
窗口[ 1687073680000 ~ 1687073690000 ) , 用户 Jerry 的点击次数为: 3
窗口[ 1687073680000 ~ 1687073690000 ) , 用户 Peiqi 的点击次数为: 1
input> Event(user=Zhangs, url=pay, ts=1687073691261)
input> Event(user=Jerry, url=/home, ts=1687073692262)
input> Event(user=Lisi, url=detail, ts=1687073693263)
input> Event(user=Zhangs, url=/cart, ts=1687073694263)
input> Event(user=Lisi, url=detail, ts=1687073695263)
窗口[ 1687073685000 ~ 1687073695000 ) , 用户 Peiqi 的点击次数为: 1
窗口[ 1687073685000 ~ 1687073695000 ) , 用户 Lisi 的点击次数为: 2
窗口[ 1687073685000 ~ 1687073695000 ) , 用户 Zhangs 的点击次数为: 6
窗口[ 1687073685000 ~ 1687073695000 ) , 用户 Jerry 的点击次数为: 1
input> Event(user=Jerry, url=detail, ts=1687073696263)
input> Event(user=Peiqi, url=/home, ts=1687073697263)
input> Event(user=Lisi, url=/cart, ts=1687073698264)
input> Event(user=Peiqi, url=pay, ts=1687073699264)
input> Event(user=Jerry, url=/home, ts=1687073700265)
窗口[ 1687073690000 ~ 1687073700000 ) , 用户 Zhangs 的点击次数为: 2
窗口[ 1687073690000 ~ 1687073700000 ) , 用户 Lisi 的点击次数为: 4
窗口[ 1687073690000 ~ 1687073700000 ) , 用户 Peiqi 的点击次数为: 2
窗口[ 1687073690000 ~ 1687073700000 ) , 用户 Jerry 的点击次数为: 2
input> Event(user=Tom, url=detail, ts=1687073701265)
input> Event(user=Jerry, url=/cart, ts=1687073702265)
input> Event(user=Jerry, url=pay, ts=1687073703266)
input> Event(user=Zhangs, url=/home, ts=1687073704266)
input> Event(user=Tom, url=/cart, ts=1687073705267)
窗口[ 1687073695000 ~ 1687073705000 ) , 用户 Jerry 的点击次数为: 4
窗口[ 1687073695000 ~ 1687073705000 ) , 用户 Lisi 的点击次数为: 2
窗口[ 1687073695000 ~ 1687073705000 ) , 用户 Zhangs 的点击次数为: 1
窗口[ 1687073695000 ~ 1687073705000 ) , 用户 Peiqi 的点击次数为: 2
窗口[ 1687073695000 ~ 1687073705000 ) , 用户 Tom 的点击次数为: 1
input> Event(user=Jerry, url=pay, ts=1687073706267)
input> Event(user=Lisi, url=detail, ts=1687073707267)
input> Event(user=Tom, url=/home, ts=1687073708268)
input> Event(user=Zhangs, url=/home, ts=1687073709268)
input> Event(user=Jerry, url=pay, ts=1687073710269)
窗口[ 1687073700000 ~ 1687073710000 ) , 用户 Tom 的点击次数为: 3
窗口[ 1687073700000 ~ 1687073710000 ) , 用户 Jerry 的点击次数为: 4
窗口[ 1687073700000 ~ 1687073710000 ) , 用户 Zhangs 的点击次数为: 2
窗口[ 1687073700000 ~ 1687073710000 ) , 用户 Lisi 的点击次数为: 1
input> Event(user=Lisi, url=/home, ts=1687073711269)
input> Event(user=Zhangs, url=/home, ts=1687073712270)
input> Event(user=Tom, url=/home, ts=1687073713271)
input> Event(user=Peiqi, url=/home, ts=1687073714272)
input> Event(user=Jerry, url=/home, ts=1687073715272)
窗口[ 1687073705000 ~ 1687073715000 ) , 用户 Tom 的点击次数为: 3
窗口[ 1687073705000 ~ 1687073715000 ) , 用户 Zhangs 的点击次数为: 2
窗口[ 1687073705000 ~ 1687073715000 ) , 用户 Jerry 的点击次数为: 2
窗口[ 1687073705000 ~ 1687073715000 ) , 用户 Peiqi 的点击次数为: 1
窗口[ 1687073705000 ~ 1687073715000 ) , 用户 Lisi 的点击次数为: 2
input> Event(user=Lisi, url=detail, ts=1687073716273)
input> Event(user=Zhangs, url=/home, ts=1687073717273)
input> Event(user=Peiqi, url=pay, ts=1687073718273)
input> Event(user=Tom, url=/home, ts=1687073719274)
input> Event(user=Tom, url=/home, ts=1687073720274)
窗口[ 1687073710000 ~ 1687073720000 ) , 用户 Zhangs 的点击次数为: 2
窗口[ 1687073710000 ~ 1687073720000 ) , 用户 Peiqi 的点击次数为: 2
窗口[ 1687073710000 ~ 1687073720000 ) , 用户 Jerry 的点击次数为: 2
窗口[ 1687073710000 ~ 1687073720000 ) , 用户 Tom 的点击次数为: 2
窗口[ 1687073710000 ~ 1687073720000 ) , 用户 Lisi 的点击次数为: 2
input> Event(user=Peiqi, url=pay, ts=1687073721275)
input> Event(user=Jerry, url=detail, ts=1687073722276)
input> Event(user=Tom, url=/home, ts=1687073723276)
input> Event(user=Lisi, url=/home, ts=1687073724276)
input> Event(user=Zhangs, url=/cart, ts=1687073725277)
窗口[ 1687073715000 ~ 1687073725000 ) , 用户 Lisi 的点击次数为: 2
窗口[ 1687073715000 ~ 1687073725000 ) , 用户 Tom 的点击次数为: 3
窗口[ 1687073715000 ~ 1687073725000 ) , 用户 Zhangs 的点击次数为: 1
窗口[ 1687073715000 ~ 1687073725000 ) , 用户 Jerry 的点击次数为: 2
窗口[ 1687073715000 ~ 1687073725000 ) , 用户 Peiqi 的点击次数为: 2
input> Event(user=Peiqi, url=detail, ts=1687073726278)
input> Event(user=Peiqi, url=pay, ts=1687073727278)
input> Event(user=Lisi, url=/home, ts=1687073728278)
input> Event(user=Tom, url=detail, ts=1687073729278)
input> Event(user=Lisi, url=detail, ts=1687073730280)
窗口[ 1687073720000 ~ 1687073730000 ) , 用户 Peiqi 的点击次数为: 3
窗口[ 1687073720000 ~ 1687073730000 ) , 用户 Lisi 的点击次数为: 2
窗口[ 1687073720000 ~ 1687073730000 ) , 用户 Zhangs 的点击次数为: 1
窗口[ 1687073720000 ~ 1687073730000 ) , 用户 Jerry 的点击次数为: 1
窗口[ 1687073720000 ~ 1687073730000 ) , 用户 Tom 的点击次数为: 3
input> Event(user=Zhangs, url=/cart, ts=1687073731280)
input> Event(user=Peiqi, url=/home, ts=1687073732280)
input> Event(user=Zhangs, url=pay, ts=1687073733281)
input> Event(user=Zhangs, url=/cart, ts=1687073734281)
input> Event(user=Tom, url=detail, ts=1687073735281)
窗口[ 1687073725000 ~ 1687073735000 ) , 用户 Tom 的点击次数为: 1
窗口[ 1687073725000 ~ 1687073735000 ) , 用户 Lisi 的点击次数为: 2
窗口[ 1687073725000 ~ 1687073735000 ) , 用户 Zhangs 的点击次数为: 4
窗口[ 1687073725000 ~ 1687073735000 ) , 用户 Peiqi 的点击次数为: 3
input> Event(user=Zhangs, url=detail, ts=1687073736282)
input> Event(user=Zhangs, url=/home, ts=1687073737283)
input> Event(user=Lisi, url=pay, ts=1687073738283)
input> Event(user=Jerry, url=pay, ts=1687073739283)
input> Event(user=Peiqi, url=pay, ts=1687073740284)
窗口[ 1687073730000 ~ 1687073740000 ) , 用户 Zhangs 的点击次数为: 5
窗口[ 1687073730000 ~ 1687073740000 ) , 用户 Lisi 的点击次数为: 2
窗口[ 1687073730000 ~ 1687073740000 ) , 用户 Jerry 的点击次数为: 1
窗口[ 1687073730000 ~ 1687073740000 ) , 用户 Tom 的点击次数为: 1
窗口[ 1687073730000 ~ 1687073740000 ) , 用户 Peiqi 的点击次数为: 1
input> Event(user=Peiqi, url=detail, ts=1687073741284)
input> Event(user=Jerry, url=pay, ts=1687073742284)
input> Event(user=Lisi, url=/cart, ts=1687073743284)
input> Event(user=Jerry, url=detail, ts=1687073744284)
input> Event(user=Peiqi, url=detail, ts=1687073745285)
窗口[ 1687073735000 ~ 1687073745000 ) , 用户 Lisi 的点击次数为: 2
窗口[ 1687073735000 ~ 1687073745000 ) , 用户 Tom 的点击次数为: 1
窗口[ 1687073735000 ~ 1687073745000 ) , 用户 Peiqi 的点击次数为: 2
窗口[ 1687073735000 ~ 1687073745000 ) , 用户 Jerry 的点击次数为: 3
窗口[ 1687073735000 ~ 1687073745000 ) , 用户 Zhangs 的点击次数为: 2
input> Event(user=Zhangs, url=/cart, ts=1687073746285)
input> Event(user=Jerry, url=detail, ts=1687073747286)
input> Event(user=Peiqi, url=detail, ts=1687073748286)
input> Event(user=Tom, url=pay, ts=1687073749287)
input> Event(user=Zhangs, url=detail, ts=1687073750287)
窗口[ 1687073740000 ~ 1687073750000 ) , 用户 Peiqi 的点击次数为: 4
窗口[ 1687073740000 ~ 1687073750000 ) , 用户 Lisi 的点击次数为: 1
窗口[ 1687073740000 ~ 1687073750000 ) , 用户 Tom 的点击次数为: 1
窗口[ 1687073740000 ~ 1687073750000 ) , 用户 Jerry 的点击次数为: 3
窗口[ 1687073740000 ~ 1687073750000 ) , 用户 Zhangs 的点击次数为: 1
input> Event(user=Lisi, url=detail, ts=1687073751287)
input> Event(user=Peiqi, url=/home, ts=1687073752288)
input> Event(user=Tom, url=/home, ts=1687073753288)
input> Event(user=Tom, url=/home, ts=1687073754288)
input> Event(user=Zhangs, url=detail, ts=1687073755289)
窗口[ 1687073745000 ~ 1687073755000 ) , 用户 Peiqi 的点击次数为: 3
窗口[ 1687073745000 ~ 1687073755000 ) , 用户 Tom 的点击次数为: 3
窗口[ 1687073745000 ~ 1687073755000 ) , 用户 Zhangs 的点击次数为: 2
窗口[ 1687073745000 ~ 1687073755000 ) , 用户 Jerry 的点击次数为: 1
窗口[ 1687073745000 ~ 1687073755000 ) , 用户 Lisi 的点击次数为: 1
input> Event(user=Zhangs, url=/home, ts=1687073756290)
input> Event(user=Tom, url=pay, ts=1687073757290)
input> Event(user=Zhangs, url=/cart, ts=1687073758290)
input> Event(user=Lisi, url=detail, ts=1687073759290)
input> Event(user=Tom, url=detail, ts=1687073760290)
窗口[ 1687073750000 ~ 1687073760000 ) , 用户 Lisi 的点击次数为: 2
窗口[ 1687073750000 ~ 1687073760000 ) , 用户 Tom 的点击次数为: 3
窗口[ 1687073750000 ~ 1687073760000 ) , 用户 Zhangs 的点击次数为: 4
窗口[ 1687073750000 ~ 1687073760000 ) , 用户 Peiqi 的点击次数为: 1
数据第一次来,5秒滑动一次,底层源码经过计算,571+5=576,取整得575,所以第一次的窗口为565-575,当事件时间到575的时候,触发计算,计算565-575窗口的数据;
5秒滑动一次,下一个窗口是570-580,当事件时间到580的时候,触发计算,计算570-580窗口的数据;
依次类推。。。
可以看到,第一个窗口计算的时候,565到570是没有数据的,所以第一个窗口只计算了571到575的数据;
第二个窗口虽然是570-580,但是只计算了571到580的数据;
之后的窗口就可以计算完整的数据了
Flink-滑动窗口-时间
Flink-滑动窗口-计数
事实上“触发计算”和“窗口关闭”两个行为也可以分开