本文来自官网翻译: Joining

Window Join

窗口join 连接两个共享公共key 并位于同一窗口中的流的元素。可以使用窗口分配器定义这些窗口,两个流的元素都会触发。

然后将来自双方的元素传递给用户定义的 JoinFunction或者FlatJoinFunction,用户可以发出满足连接条件的结果。

一般用法可归纳如下:

stream.join(otherStream)
.where(<KeySelector>)
.equalTo(<KeySelector>)
.window(<WindowAssigner>)
.apply(<JoinFunction>)

关于语义的一些注释:

  • 两个流的元素的成对组合的表现像内连接,意味着如果它们没有来自要连接的另一个流的对应元素,则不会发出来当前流的元素。
  • 那些加入的元素将在其时间戳包含于相应窗口中的最大时间戳中。例如,[5, 10)具有其边界的窗口将导致连接的元素具有9作为其时间戳。

在下一节中,我们将使用一些示例性场景概述不同类型的窗口连接的行为。

Tumbling Window Join

当执行翻滚窗口join时,具有相同key和相同翻滚窗口的所有元素作为成对组合被连接并传递给JoinFunctionFlatJoinFunction。因为它的行为类似于内连接,所以一个流的元素在其翻滚窗口中没有来自另一个流的元素是不会发出的。

如图所示,我们定义了一个大小为2毫秒的翻滚窗口,这导致了窗体的窗口[0,1], [2,3], ... 图像显示了每个窗口中所有元素的成对组合,这些元素将被传递给JoinFunction。请注意,在翻滚窗口中[6,7]没有任何物体被发出,因为绿色流中不存在与橙色元素⑥和⑦连接的元素。

import org.apache.flink.streaming.api.windowing.assigners.SlidingEventTimeWindows;
import org.apache.flink.streaming.api.windowing.time.Time; ... val orangeStream: DataStream[Integer] = ...
val greenStream: DataStream[Integer] = ... orangeStream.join(greenStream)
.where(elem => /* select key */)
.equalTo(elem => /* select key */)
.window(TumblingEventTimeWindows.of(Time.milliseconds(2)))
.apply { (e1, e2) => e1 + "," + e2 }

Sliding Window Join

执行滑动窗口连接时,具有相同key和相同滑动窗口的所有元素将作为成对组合连接并传递给JoinFunctionFlatJoinFunction。当前滑动窗口中没有来自对应流的元素时,流元素不会发出!请注意,某些元素可能在一个滑动窗口中连接而在另一个滑块窗口中不连接。

在这个例子中,我们使用大小为2毫秒的滑动窗口并将它们滑动一毫秒,从而产生滑动窗口[-1, 0],[0,1],[1,2],[2,3], …。x轴下方的连接元素是传递给JoinFunction每个滑动窗口的元素。在这里,您还可以看到橙色②与窗口中的绿色③  在窗口[2,3]连接,但未与任何内容在窗口[1,2] 连接

import org.apache.flink.streaming.api.windowing.assigners.SlidingEventTimeWindows;
import org.apache.flink.streaming.api.windowing.time.Time; ... val orangeStream: DataStream[Integer] = ...
val greenStream: DataStream[Integer] = ... orangeStream.join(greenStream)
.where(elem => /* select key */)
.equalTo(elem => /* select key */)
.window(SlidingEventTimeWindows.of(Time.milliseconds(2) /* size */, Time.milliseconds(1) /* slide */))
.apply { (e1, e2) => e1 + "," + e2 }

Session Window Join

在执行会话窗口连接时,具有相同键的所有元素“组合”满足会话条件时以成对组合方式连接并传递给JoinFunctionFlatJoinFunction。同样,这会执行内连接,因此如果存在仅包含来自一个流的元素的会话窗口,则不会发出任何输出!

这里我们定义一个会话窗口连接,其中每个会话除以至少1ms的间隙。有三个会话,在前两个会话中,两个流的连接元素都传递给JoinFunction。在第三阶段,绿色流中没有元素,所以⑧和⑨没有连接!

import org.apache.flink.streaming.api.windowing.assigners.EventTimeSessionWindows;
import org.apache.flink.streaming.api.windowing.time.Time; ... val orangeStream: DataStream[Integer] = ...
val greenStream: DataStream[Integer] = ... orangeStream.join(greenStream)
.where(elem => /* select key */)
.equalTo(elem => /* select key */)
.window(EventTimeSessionWindows.withGap(Time.milliseconds(1)))
.apply { (e1, e2) => e1 + "," + e2 }

Interval Join

(时间)间隔连接使用公共密钥连接两个流的元素(我们现在称它们为A和B),并且流B的元素具有时间戳,该时间戳位于流A中元素的时间戳的相对时间间隔中。

这也可以更正式地表达为

b.timestamp ∈ [a.timestamp + lowerBound; a.timestamp + upperBound]

a.timestamp + lowerBound <= b.timestamp <= a.timestamp + upperBound

其中a和b是共享相同key 的A和B的元素。只要下限总是小于或等于上限,下限和上限都可以是负数或正数。间隔连接当前仅支持内连接。

当一对元素传递给ProcessJoinFunction它们时,它们将被赋予ProcessJoinFunction.Context两个元素较大的时间戳(可以通过它访问)。

注意:时间间隔连接当前仅支持事件时间。

在上面的例子中,我们连接两个流'orange'和'green',下限为-2毫秒,上限为+1毫秒。缺省情况下,这些界限是包容性的(包含上下界),方法lowerBoundExclusive()和upperBoundExclusive可以改变应用行为。

再次使用更正式的符号,这将转化为

orangeElem.ts + lowerBound <= greenElem.ts <= orangeElem.ts + upperBound

如上图三角形所示。

import org.apache.flink.streaming.api.functions.co.ProcessJoinFunction;
import org.apache.flink.streaming.api.windowing.time.Time; ... val orangeStream: DataStream[Integer] = ...
val greenStream: DataStream[Integer] = ... orangeStream
.keyBy(elem => /* select key */)
.intervalJoin(greenStream.keyBy(elem => /* select key */))
.between(Time.milliseconds(-2), Time.milliseconds(1))
.process(new ProcessJoinFunction[Integer, Integer, String] {
override def processElement(left: Integer, right: Integer, ctx: ProcessJoinFunction[Integer, Integer, String]#Context, out: Collector[String]): Unit = {
out.collect(left + "," + right);
}
});
});

【翻译】Flink Joining的更多相关文章

  1. 【翻译】Flink Table Api & SQL — 流概念

    本文翻译自官网:Streaming Concepts  https://ci.apache.org/projects/flink/flink-docs-release-1.9/dev/table/st ...

  2. Flink Table Api & SQL 翻译目录

    Flink 官网 Table Api & SQL  相关文档的翻译终于完成,这里整理一个安装官网目录顺序一样的目录 [翻译]Flink Table Api & SQL —— Overv ...

  3. 【翻译】Flink Table Api & SQL — 性能调优 — 流式聚合

    本文翻译自官网:Streaming Aggregation  https://ci.apache.org/projects/flink/flink-docs-release-1.9/dev/table ...

  4. 【翻译】Flink Table Api & SQL — 配置

    本文翻译自官网:Configuration https://ci.apache.org/projects/flink/flink-docs-release-1.9/dev/table/config.h ...

  5. 【翻译】Flink Table Api & SQL — Hive —— 在 scala shell 中使用 Hive 连接器

    本文翻译自官网:Use Hive connector in scala shell  https://ci.apache.org/projects/flink/flink-docs-release-1 ...

  6. 【翻译】Flink Table Api & SQL — Hive —— Hive 函数

    本文翻译自官网:Hive Functions  https://ci.apache.org/projects/flink/flink-docs-release-1.9/dev/table/hive/h ...

  7. 【翻译】Flink Table Api & SQL — SQL客户端Beta 版

    本文翻译自官网:SQL Client Beta  https://ci.apache.org/projects/flink/flink-docs-release-1.9/dev/table/sqlCl ...

  8. 【翻译】Flink Table Api & SQL — Hive —— 读写 Hive 表

    本文翻译自官网:Reading & Writing Hive Tables  https://ci.apache.org/projects/flink/flink-docs-release-1 ...

  9. 【翻译】Flink Table Api & SQL —— Overview

    本文翻译自官网:https://ci.apache.org/projects/flink/flink-docs-release-1.9/dev/table/ Flink Table Api & ...

随机推荐

  1. spring boot 集成 redis lettuce(jedis)

    spring boot框架中已经集成了redis,在1.x.x的版本时默认使用的jedis客户端,现在是2.x.x版本默认使用的lettuce客户端 引入依赖 <!-- spring boot ...

  2. Vue基础入门笔记

    不是面向DOM进行编程,而是面向数据去编程.当数据发生改变,页面就会随着改变. 属性绑定(v-bind)和双向数据绑定(v-model) 模板指令(v-bind:)后面跟的内容不再是字符串而是: js ...

  3. easyui-datagrid统计

    <script> //打印指定的table function dayin() { var tableToPrint = document.getElementById("dg&q ...

  4. Acwing P288 休息时间 题解

    Analysis 首先假设一天的第N小时与后一天的第一个小时不相连, 这种情况下DP转移比较好想 dp[i][j][0/1]dp[i][j][0/1]表示 考虑一天的前i个小时,已经休息了j小时,且第 ...

  5. vue路由监听及路由守卫

    路由监听: //当一个组件被复用的时候,那么路由发生变化,但是页面上面的数据不会发生变化 新建one.vue 组件 作为home的子组件,在home.vue 中写遍历渲染页面 ,并用params传参, ...

  6. PDB符号文件

    一.什么是PDB文件 PDB(Program DataBase),全称为“程序数据库”文件.存储程序的所有调试信息数据.在编译连接时,如果选择了/debug选项或/debug:full选项,则最新的M ...

  7. 【转】根据Quartz-Cron表达式获取最近几次执行时间

    public static List<String> getRecentTriggerTime(String cron) { List<String> list = new A ...

  8. #6085. 「美团 CodeM 资格赛」优惠券

    题目描述 用last[x]表示对x进行的上一次操作的位置,vis[x]表示x是否在大楼内. Splay维护'?'的位置. 若x要进楼: 1.若x已在楼内,则去找last[x]到i之间是否有'?',若有 ...

  9. Luogu5591 小猪佩奇学数学 【单位根反演】

    题目链接:洛谷 \[ Ans=\frac{1}{k}(\sum_{i=0}^n\binom{n}{i}p^ii-\sum_{i=0}^n\binom{n}{i}p^i(i \ \mathrm{mod} ...

  10. 创建一个简单tcp服务器需要的流程

    1.socket创建一个套接字 2.bind绑定ip和port 3.listen使套接字变为可以被动链接 4.accept等待客户端的链接 5.recv/send接收发送数据