1 基于时间的双流join
基于间隔的 Join 会对两条流中拥有相同键值以及彼此之间时间戳不超过某一指定间隔的事件进行 Join。
基于时间间隔的 Join 目前只支持事件时间以及 INNER JOIN 语义
1.1 用法:
input1
.keyBy(...)
.between(<lower-bound>, <upper-bound>) // 相对于 input1 的上下界
.process(ProcessJoinFunction) // 处理匹配的事件对
between(Time.minute(50), Time.minute(5))
下图展示了两条流(A 和 B)上基于间隔的 Join,如果 B 中事件的时间戳相较于 A 中事件的时间戳不早于 50 分钟且不晚于 5 分钟,则会将两个事件 Join 起来。 Join 间隔具有对称性,因此上面的条件也可以表示为 A 中事件的时间戳相较 B 中事件的时间戳不早于 5 分钟且不晚于 50 分钟。
比如:stream A 为12:10:00 的时间戳会和stream B 中的时间范围 11:20:00~12:15:00 的数据进行join
计算公式:stream B的范围 = stream A timestamp - lower-bound 到 stream A timestamp - upper-bound
那相对于stream B 12:15:00 的时间戳会和stream A 中的时间范围 12:10:00~13:15:00 的数据进行join
计算公式:stream A的范围 = stream B timestamp - upper-bound 到 stream A timestamp - lower-bound
1.2 案例
package org.example.join
import org.apache.flink.streaming.api.TimeCharacteristic
import org.apache.flink.streaming.api.functions.co.ProcessJoinFunction
import org.apache.flink.streaming.api.scala._
import org.apache.flink.streaming.api.windowing.time.Time
import org.apache.flink.util.Collector
/**
* 实现两个流的join
*/
object IntervalJoinExample {
// 用户点击日志
case class UserClickLog(userID: String,
eventTime: String,
eventType: String,
pageID: String)
// 用户浏览日志
case class UserBrowseLog(userID: String,
eventTime: String,
eventType: String,
productID: String,
productPrice: String)
def main(args: Array[String]): Unit = {
val env = StreamExecutionEnvironment.getExecutionEnvironment
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
env.setParallelism(1)
/**
* 产生用户数据流
*/
val clickStream = env
.fromElements(
UserClickLog("user_2", "1500", "click", "page_1"), // (900, 1500)
UserClickLog("user_2", "2000", "click",