加入收藏 | 设为首页 | 会员中心 | 我要投稿 核心网 (https://www.hxwgxz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 教程 > 正文

Apache Flink 漫谈系列 - JOIN 算子

发布时间:2018-11-20 20:07:11 所属栏目:教程 来源:孙金城
导读:聊什么 在《Apache Flink 漫谈系列 - SQL概览》中我们介绍了JOIN算子的语义和基本的使用方式,介绍过程中大家发现Apache Flink在语法语义上是遵循ANSI-SQL标准的,那么再深思一下传统数据库为啥需要有JOIN算子呢?在实现原理上面Apache Flink内部实现和传统

根据JOIN的语义以INNER JOIN为例,右边有两条相同的订单流入,我们就应该向下游输出两条JOIN结果,当有撤回的事件流入时候,我们也需要将已经下发下游的JOIN事件撤回,如下:

Apache Flink 漫谈系列 - JOIN 算子

上面的场景以及LEFT JOIN部分介绍的撤回情况,Apache Flink内部需要处理如下几个核心点:

  • 记录重复记录(完整记录重复记录或者记录相同记录的个数)
  • 记录正向记录和撤回记录(完整记录正向和撤回记录或者记录个数)
  • 记录哪一条事件是第一个可以与左边事件进行JOIN的事件

(1) 双流JOIN的State数据结构

在Apache Flink内部对不同的场景有特殊的数据结构优化,本篇我们只针对上面说的情况(通用设计)介绍一下双流JOIN的State的数据结构和用途:

数据结构

  1. Map<JoinKey, Map<rowData, count>>; 
  • 第一级MAP的key是Join key,比如示例中的P001, value是流上面的所有完整事件;
  • 第二级MAP的key是行数据,比如示例中的P001, 2,value是相同事件值的个数

数据结构的利用

  • 记录重复记录 - 利用第二级MAP的value记录重复记录的个数,这样大大减少存储和读取
  • 正向记录和撤回记录 - 利用第二级MAP的value记录,当count=0时候删除该元素
  • 判断右边是否产生撤回记录 - 根据第一级MAP的value的size来判断是否产生撤回,只有size由0变成1的时候(第一条和左可以JOIN的事件)才产生撤回

双流JOIN的应用优化

1. 构造更新流

我们在 《Apache Flink 漫谈系列 - 持续查询(Continuous Queries)》篇中以双流JOIN为例介绍了如何构造业务上的PK source,构造PK source本质上在保证业务语义的同时也是对双流JOIN的一种优化,比如多级LEFT JOIN会让流上的数据不断膨胀,造成JOIN节点性能较慢,JOIN之后的下游节点边堵(数据量大导致,非热点)。那么嫌少流入JOIN的数据,比如构造PK source就会大大减少JOIN数据的膨胀。这里不再重复举例,大家可以查阅 《Apache Flink 漫谈系列 - 持续查询(Continuous Queries)》 的双流JOIN示例部分。

2. NULL造成的热点

比如我们有A LEFT JOIN B ON A.aCol = B.bCol LEFT JOIN C ON B.cCol = C.cCol 的业务,JOB的DAG如下:

Apache Flink 漫谈系列 - JOIN 算子

假设在实际业务中有这样的特点,大部分时候当A事件流入的时候,B还没有可以JOIN的数据,但是B来的时候,A已经有可以JOIN的数据了,这特点就会导致,A LEFT JOIN B 会产生大量的 (A, NULL),其中包括B里面的 cCol 列也是NULL,这时候当与C进行LEFT JOIN的时候,首先Blink内部会利用cCol对AB的JOIN产生的事件流进行Shuffle, cCol是NULL进而是下游节点大量的NULL事件流入,造成热点。那么这问题如何解决呢?

我们可以改变JOIN的先后顺序,来保证A LEFT JOIN B 不会产生NULL的热点问题,如下:

Apache Flink 漫谈系列 - JOIN 算子

3. JOIN ReOrder

对于JOIN算子的实现我们知道左右两边的事件都会存储到State中,在流入事件时候在从另一边读取所有事件进行JOIN计算,这样的实现逻辑在数据量很大的场景会有一定的state操作瓶颈,我们某些场景可以通过业务角度调整JOIN的顺序,来消除性能瓶颈,比如:A JOIN B ON A.acol = B.bcol JOIN C ON B.bcol = C.ccol. 这样的场景,如果 A与B进行JOIN产生数据量很大,但是B与C进行JOIN产生的数据量很小,那么我们可以强制调整JOIN的联接顺序,B JOIN C ON b.bcol = c.ccol JOIN A ON a.acol = b.bcol. 如下示意图:

Apache Flink 漫谈系列 - JOIN 算子

小结

本篇向大家介绍了数据库设计范式的要求和实际业务的查询需要是传统数据库JOIN算子存在的原因,并以具体示例的方式向大家介绍JOIN在数据库的查询过程,以及潜在的查询优化,再以实际的例子介绍Apache Flink上面的双流JOIN的实现原理和State数据结构设计,最后向大家介绍两个双流JOIN的使用优化。

作者:孙金城,花名 金竹,目前就职于阿里巴巴,自2015年以来一直投入于基于Apache Flink的阿里巴巴计算平台Blink的设计研发工作。

【本文为51CTO专栏作者“金竹”原创稿件,转载请联系原作者】

【编辑推荐】

  1. Apache Flink 漫谈系列 - State
  2. Apache Flink 漫谈系列 - Fault Tolerance
  3. Apache Flink 漫谈系列 - 流表对偶(duality)性
  4. Apache Flink 漫谈系列 - 持续查询(Continuous Queries)
  5. Apache Flink 漫谈系列 - SQL概览
【责任编辑:赵宁宁 TEL:(010)68476606】
点赞 0

(编辑:核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读