Flink sql知道为什么(十三):流连接问题的解决方案

本节是flink sql流连接系列的第二部分。第一部分的链接如下:

事不宜迟,我们直接进入本文的目录和结论,朋友们可以先看结论,快速了解博主们期望本文能给朋友们带来哪些帮助:

本书继续上述内容,介绍了当曝光流与点击流关联时,使用flink sql regular join的问题。

本文介绍了如何使用flink sql区间连接来解决这些问题。

Flink sql知道为什么(12):流连接很难吗?㈠

看一下上一节的实际案例,看看在具体输入值的场景下,输出值应该是什么样子。

场景:普通曝光日志流(show_log)通过log_id与点击日志流(click_log)关联,数据的关联结果被分发。

一波输入数据:

曝光数据:

点击数据:

预期的输出数据如下:

上一节flink sql正则连接的解决方案如下:

如前所述,如果流数据到达时左表流(show_log)加入右表流(click_log),则不会等待右表流(show_log,null)的直接输出,而是在后续右表流数据被复制时退出(show_log,null)并发送(show _ log,click)。这就是为什么会产生缩回流,导致对卡夫卡的重复书写。

对此,我们也提出了相应的解决方案。既然在左join中左流不会等待右流,那么是否可以强制左流等待右流一段时间,但是不能等待与数据无关的数据。

当当当当!!!

本文的flink sql interval join出现了,它可以等待。

我们先通过下面的句子和图形(熟悉DataStream的小伙伴孟可能用过)简单了解一下interval join的作用,再详细介绍一下原理。

区间连接是用一个流的数据关联一段时间内另一个流的数据。如果是关联的,关联的数据会被分发;如果没有关联,超时后根据是否是外连接(左连接、右连接、全连接)进行分配。

& ltfig caption style = " margin:5px 0px 0px;填充:0px大纲:0px最大宽度:100%;框尺寸:边框-框!重要;溢出-换行:断字!重要;文本对齐:居中;颜色:rgb(136,136,136);font-size:12px;font-family:ping fangsc-Light;"& gt间隔联接& lt/fig caption & gt;

我们来看看上面的案例是怎么写flink sql interval join sql的:

在click _ log . row _ time-interval ' 10 '分钟和click _ log . row _ time+interval ' 10 '分钟之间的Show _ log.row _ time表示Show _ log表中的数据。以及10分钟内click_log表中的row_time。

运行结果如下:

以上是我们期待的正确结果。

Flink web ui操作员示意图如下:

& ltfig caption style = " margin:5px 0px 0px;填充:0px大纲:0px最大宽度:100%;框尺寸:边框-框!重要;溢出-换行:断字!重要;文本对齐:居中;颜色:rgb(136,136,136);font-size:12px;font-family:ping fangsc-Light;"& gtflink web ui & lt/fig caption & gt;

那么这个时候你可能会有一个疑问。我知道结果中的前两条数据被连接到输出中。那为什么show_log join小于click_log时也会输出?原理是什么?

博主带你去看具体的源代码。首先看一下转换。

& ltfig caption style = " margin:5px 0px 0px;填充:0px大纲:0px最大宽度:100%;框尺寸:边框-框!重要;溢出-换行:断字!重要;文本对齐:居中;颜色:rgb(136,136,136);font-size:12px;font-family:ping fangsc-Light;"& gt转换& lt/fig caption & gt;

可以看出,事件时间区间join的具体操作者是org。阿帕奇。弗林克。桌子。运行时。操作员。加入。带水印延迟的KeyedCoprocessOperator。

其核心逻辑集中在processElement1和processElement2。在processElement1和processElement2,org中。阿帕奇。弗林克。桌子。运行时。操作员。加入。间隔。RowTimeInterval联接用于处理特定的联接逻辑。RowTimeIntervalJoin的重要方法如下图所示。

TimeIntervalJoin

我来给你详细解释一下。

加入时,左流和右流会在间隔时间内互相等待。如果他们等待,数据将被输出[+(show_log,click_log)]。如果他们等不及,并且对方流的时间已经推进到当前数据不可能加入对方流的数据的地步,那么数据就直接输出[+(show_log,null)],[+(null)。

例如,在click _ log . row _ time-interval ' 10 '分钟和click _ log . row _ time+interval ' 10 '分钟之间的show _ log.row _ time,当click _ log的时间提前到2021-1-01 11:00:00时,则show _ log就到了20265438+那么这个show_log就不能和click_log中的数据进行联接,因为click_log中的数据是2021-11-01:50:00到2021-165438。Show_log直接输出[+(show_log,null)]。

以上面案例的show_log(左表)区间连接click_log(右表)为例(无论是内区间连接、左区间连接、右区间连接还是全区间连接,都会遵循以下流程):

以上只是左流show_log数据到达时(即ProcessElement1)的执行流程,也是右流click_log到达时(即ProcessElement2)完全类似的执行流程。

小伙伴孟在使用区间连接时需要注意两件事:

主要介绍了flink sql interval如何避免flink正则连接的retract问题,并通过分析其实现说明了操作原理。博主期待你看完这篇文章后明白: