Flink sql 之 join 与 StreamPhysicalJoinRule (源码解析)
源码分析基于flink1.14
Join是flink中最常用的操作之一,但是如果滥用的话会有很多的性能问题,了解一下Flink源码的实现原理是非常有必要的
本文的join主要是指flink sql的Regular join 也就是平时我们的双流join中普通的full join ,left join,right join
先找到calcite的relNode转换rule

会将逻辑节点logiceJoin转换成flink的FlinkLogicalJoin
接着看下哪里Rule会转换这个FlinkLogicalJoin

这里会将这种普通join也就是regularJoin给匹配上
条件是

不是这三种join,并且

也不能join表达式包含时间属性
匹配上次rule以后,接着

返回了StreamPhysicalJoin这个StreamPhysicalRel是个物理节点
他的translateToExecNode方法会返回StreamExecJoin,这个类就是我们具体的逻辑了
来看一下

首先会根据会join的类型,确定两个流那个需要输出,如果是fulljoin两个流都会输出,left join就是左流需要outer,right join就是right流需要outer
之后创建了具体的Operator,来看下这个StreamingJoinOperator
先看一下这个类里面两个比较重要的状态

可以看到,左右流都会保存一个状态
看下状态包装类的描述

总共就三,方法,分别是加入数据,撤回数据,获取这个数据关联上的所有数据
在open方法里面会根据上面计算的左右流是否需要输出来初始化这个两个状态


这里状态包装类的创建,将根据数据类型分为三种
1. 流带主键,且join条件包含了主键

这样数据唯一,就只用ValueState来存
2. 流带主键,但join条件没有包含主键

这里就用MapState来存了,每次根据主键更新
3. 流不带主键

就用map,直接把record当key存了
接着看processElement方法
这里详细的代码就不列出来了太复杂了,想看的直接看这个类
org.apache.flink.table.runtime.operators.join.stream.StreamingJoinOperator.processElement()
梳理逻辑我们还是来看下伪代码


主要分为两段
1. 如果是 +Insert / +Update 类型的数据
判断输入数据的流需不需要输出
如果需要输出
看下和另外一个流关联的上不
关联的上输出 +I[record+other]s
关联不上输出 +I[record+null]
将数据加入状态中
如果不需要输出
将数据加入状态中
如果与另外一个流的数据关联上了
如果另外一个流要outer, 输出 +I[record+other]s
如果另外一个流不用输出 ,输出 +I/+U[record+other]s
1. 如果是 -Delete / -Update 类型的数据
状态里面先撤回这条数据
如果与另外流没有匹配上,如果输入数据的流需要输出,则输出 -D[record+null]
如果与另外一条流匹配上了
当前流outer,发送 -D[record+other]s,如果是inner join发送-D/-U[record+other]s
最后的最后

用两个流join的key作为状态的selecter来完成transform的构建就完成了
总结一下:
Flink会根据join的key作为状态分流的selecter,根据表是否有主键,join条件是否包含主键,来创建对应的state数据结构,来优化状态的读写
两条流会根据join类型,来设置此流需不需要输出outer
当数据进入,查询另一侧的流是否有数据可以关联上,以及两条流的outer类型,来确定向下游发送的撤回和新增的数据
Flink sql 之 join 与 StreamPhysicalJoinRule (源码解析)的更多相关文章
- Flink sql 之 TopN 与 StreamPhysicalRankRule (源码解析)
基于flink1.14的源码做解析 公司内有很多业务方都在使用我们Flink sql平台做TopN的计算,今天同事突然问到我,Flink sql 是怎么实现topN的 ? 蒙圈了,这块源码没看过啊 , ...
- [源码解析] GroupReduce,GroupCombine 和 Flink SQL group by
[源码解析] GroupReduce,GroupCombine和Flink SQL group by 目录 [源码解析] GroupReduce,GroupCombine和Flink SQL grou ...
- Flink 源码解析 —— 深度解析 Flink 是如何管理好内存的?
前言 如今,许多用于分析大型数据集的开源系统都是用 Java 或者是基于 JVM 的编程语言实现的.最着名的例子是 Apache Hadoop,还有较新的框架,如 Apache Spark.Apach ...
- [源码解析] 当 Java Stream 遇见 Flink
[源码解析] 当 Java Stream 遇见 Flink 目录 [源码解析] 当 Java Stream 遇见 Flink 0x00 摘要 0x01 领域 1.1 Flink 1.2 Java St ...
- Flink 源码解析 —— 源码编译运行
更新一篇知识星球里面的源码分析文章,去年写的,周末自己录了个视频,大家看下效果好吗?如果好的话,后面补录发在知识星球里面的其他源码解析文章. 前言 之前自己本地 clone 了 Flink 的源码,编 ...
- Flink 源码解析 —— 如何获取 ExecutionGraph ?
https://t.zsxq.com/UnA2jIi 博客 1.Flink 从0到1学习 -- Apache Flink 介绍 2.Flink 从0到1学习 -- Mac 上搭建 Flink 1.6. ...
- Flink 源码解析 —— 如何获取 JobGraph?
JobGraph https://t.zsxq.com/naaMf6y 博客 1.Flink 从0到1学习 -- Apache Flink 介绍 2.Flink 从0到1学习 -- Mac 上搭建 F ...
- Flink 源码解析 —— Flink JobManager 有什么作用?
JobManager 的作用 https://t.zsxq.com/2VRrbuf 博客 1.Flink 从0到1学习 -- Apache Flink 介绍 2.Flink 从0到1学习 -- Mac ...
- Flink 源码解析 —— JobManager 处理 SubmitJob 的过程
JobManager 处理 SubmitJob https://t.zsxq.com/3JQJMzZ 博客 1.Flink 从0到1学习 -- Apache Flink 介绍 2.Flink 从0到1 ...
随机推荐
- (九)羽夏看C语言——C++番外篇
写在前面 此系列是本人一个字一个字码出来的,包括示例和实验截图.本人非计算机专业,可能对本教程涉及的事物没有了解的足够深入,如有错误,欢迎批评指正. 如有好的建议,欢迎反馈.码字不易,如果本篇文章 ...
- noip模拟32
\(\color{white}{\mathbb{山高而青云冷,池深而蛟穴昏,行以慎步,援以轻身,名之以:落石}}\) 开题发现 \(t1\) 80分特别好写,于是先写了 但是这个做法没有任何扩展性,导 ...
- Linux常用命令 - less命令详解
21篇测试必备的Linux常用命令,每天敲一篇,每次敲三遍,每月一循环,全都可记住!! https://www.cnblogs.com/poloyy/category/1672457.html 查看文 ...
- 通过JDK动态代理实现 Spring AOP
1.新建一个目标类 接口:public interface IUserService //切面编程 public void addUser(); public void updateUser( ); ...
- (8)java Spring Cloud+Spring boot+mybatis企业快速开发架构之SpringCloud-Spring Cloud Eureka是什么?
Spring Cloud Eureka 是 Spring Cloud Netflix 微服务套件的一部分,基于 Netflix Eureka 做了二次封装,主要负责实现微服务架构中的服务治理功能. ...
- C# 中 async 和 await 的基本使用
C# 中 async 和 await 的基本使用 前言 经常在 C# 的代码中看到以 Async 结尾的方法,大概知道意为异步方法,但不知道怎么使用,也不知道如何定义. 对于"同步" ...
- PTA 面向对象程序设计6-2 统计数字
对于给定的一个字符串,统计其中数字字符出现的次数. 类和函数接口定义: 设计一个类Solution,其中包含一个成员函数count_digits,其功能是统计传入的string类型参数中数字字符的个数 ...
- 整理STC延时函数时遇到的玄学问题
void Delay { unsigned char i, j; i = 11; j = 190; do { while (--j); } while (--i); } void Delay { un ...
- Loadrunner拼装唯一值方法
由于Loadrunner函数有限性,唯一值需要几个函数的字符串进行拼装,可实现流水号.订单号等等数值的唯一性.具体可见下列方法: 方法一: char OraderID[15];srand(time{N ...
- ssh 执行 shell脚本执行jps时:-bash: jps: command not found
转至: https://www.codeleading.com/article/67592908468/ 我构建了hadoop集群.我们一定会写一个shell脚本去每一个节点上去jps,查看每个节点的 ...