基于flink1.14的源码做解析

公司内有很多业务方都在使用我们Flink sql平台做TopN的计算,今天同事突然问到我,Flink sql 是怎么实现topN的 ?

蒙圈了,这块源码没看过啊 ,业务要问起来怎么办,赶快打开源码补一下

拿到这个问题先冷静分析一下范围

首先肯定属于Flink sql模块,源码里面肯定是在flink-table-planner包里面,接着topN那不就是ROW_NUMBER嘛,是个函数呀

既然如此那就从flink源码的系统函数作为线索开始找起来,来到 org.apache.calcite.sql.fun.SqlStdOperatorTable类

果然找到了,那calcite的某个rule肯定有个地方判断了它,继续查调用链

不出所料,FlinkLogicalRankRuleBase这个calcite的rule里面果然根据这个function的类型来确定rank的类型了

看下这个rule的匹配条件

这里也好理解,overAgg的时候会判断这个rank以及对应的类型

这是只是做了一下简单的提取了rank的字段啊,提取谓语啊,提取表达式啊这一些拿信息的操作

然后直接生成新的relNode叫FlinkLogicalRank通过transformTo直接返回了这个等价节点

既然是relNode那肯定又会有calcite的rule去处理它,来找一找

批处理的就不管了,从名字就可以看出来我们要找的类了

看个不带window的吧

返回StreamPhysicalRank

这个类是一个FlinkPhysicalRel是可以转换成execNode的

返回的这个StreamExecRank就是可以转换成具体的Flink的算子了,具体逻辑就在里面了

接下来看下row_number的具体逻辑,找到方法translateToPlanInternal

根据策略主要分为三种类型

AppendFastStrategy  (输入仅包含插入时)

RetractStrategy   (输入包含update和delete)

UpdateFastStrategy     (输入不应包含删除且输入有给定的primaryKeys且按字段排序时)

来看个retractStrategy的吧

先通过sort的字段获取一个用于排序RowData的比较器 ComparableRecordComparator

根据比较器创建 RetractableTopNFunction

这个类还有两个主要的状态数据结构

dataState这个map用来存放当key相同的所有数据会放在同一个list里面

treeMap这个可排序的map就是通过上面我们sql里面定义的sort by 来排序数据的,Long是指这个相同的key有多少个record

!!!!!!!!!!!  那就是用java的treeMap排序呗

继续往下看

主逻辑就是这个了

每进入一条数据,会根据这条数据的类型划分

当数据是Insert , UPDATE_AFTER类型是会走 emitRecordsWithRowNumber()方法

当数据是UPDATE_BEFORE,DELETE类型会走 retractRecordWithRowNumber ()方法

来看下具体逻辑先看INSERT的

遍历treeMap

解读一下,当数据是insert数据的时候

按顺序遍历treeMap

当遍历过程中发现遍历的key与当前数据的key相同时,和当前数据key相同的所有数据数据(dataState中的LIST),全部撤回并且更新他们的rowNumber+1

继续遍历treeMap

之后的数据全部撤回UpdateBefore,并且向下游发送UpdateAfter使rowNumber+1,遍历直到已经到第TopN个数据循环结束

当数据是DELETE类型的时候,会和Insert反过来,当前key之后的数据全部撤回,然后rowNumber-1

整个处理流程差不多就结束了,可以看到rowNumber当N较大且排序变化频繁的时候,性能消耗还是非常大的,极端情况下游的数据会翻很多倍

这个还需要注意在其他两个策略中还有一个参数,table.exec.topn.cache-size

影响下面这个本地lruCache的大小

调大可以减少状态的访问,可以按需要添加

  

Flink sql 之 TopN 与 StreamPhysicalRankRule (源码解析)的更多相关文章

  1. [源码解析] GroupReduce,GroupCombine 和 Flink SQL group by

    [源码解析] GroupReduce,GroupCombine和Flink SQL group by 目录 [源码解析] GroupReduce,GroupCombine和Flink SQL grou ...

  2. Flink 源码解析 —— 源码编译运行

    更新一篇知识星球里面的源码分析文章,去年写的,周末自己录了个视频,大家看下效果好吗?如果好的话,后面补录发在知识星球里面的其他源码解析文章. 前言 之前自己本地 clone 了 Flink 的源码,编 ...

  3. Flink 源码解析 —— 如何获取 ExecutionGraph ?

    https://t.zsxq.com/UnA2jIi 博客 1.Flink 从0到1学习 -- Apache Flink 介绍 2.Flink 从0到1学习 -- Mac 上搭建 Flink 1.6. ...

  4. Flink 源码解析 —— 深度解析 Flink 是如何管理好内存的?

    前言 如今,许多用于分析大型数据集的开源系统都是用 Java 或者是基于 JVM 的编程语言实现的.最着名的例子是 Apache Hadoop,还有较新的框架,如 Apache Spark.Apach ...

  5. Flink 源码解析 —— 如何获取 JobGraph?

    JobGraph https://t.zsxq.com/naaMf6y 博客 1.Flink 从0到1学习 -- Apache Flink 介绍 2.Flink 从0到1学习 -- Mac 上搭建 F ...

  6. Flink 源码解析 —— Flink JobManager 有什么作用?

    JobManager 的作用 https://t.zsxq.com/2VRrbuf 博客 1.Flink 从0到1学习 -- Apache Flink 介绍 2.Flink 从0到1学习 -- Mac ...

  7. Flink 源码解析 —— JobManager 处理 SubmitJob 的过程

    JobManager 处理 SubmitJob https://t.zsxq.com/3JQJMzZ 博客 1.Flink 从0到1学习 -- Apache Flink 介绍 2.Flink 从0到1 ...

  8. Flink Metrics 源码解析

    Flink Metrics 有如下模块: Flink Metrics 源码解析 -- Flink-metrics-core Flink Metrics 源码解析 -- Flink-metrics-da ...

  9. Flink 源码解析 —— 深度解析 Flink 序列化机制

    Flink 序列化机制 https://t.zsxq.com/JaQfeMf 博客 1.Flink 从0到1学习 -- Apache Flink 介绍 2.Flink 从0到1学习 -- Mac 上搭 ...

随机推荐

  1. Install Percona XtraDb Cluster 5.6.20 on CentOS 6.5

    http://blog.51cto.com/hj192837/1546149 You should have odd number of real nodes. node #1hostname: pe ...

  2. APMserv 5.2.6 安装教程

    1.下载APMServ5.2.6.rar压缩包后解压,得到文件APMServ5.1.2.exe,其余两个没什么大用,APMServ解压缩说明.txt可以看一下,里面详细介绍了APMServ的功能和注意 ...

  3. 剑指offer计划5(查找算法中等版)---java

    1.1.题目1 剑指 Offer 04. 二维数组中的查找 1.2.解法 其实就是暴力解法的升级版,从最后一行开始判断,通过num当前的大小, 如果还是大于目标值则行数-1,若是小于则列数+1 1.3 ...

  4. .NetCore 项目在服务器打包失败解决

    错误描述:NuGet警告 NU3037 NU3028 原因:Nuget无法访问到json所在的网络 2021年1月31日更新:更好的方法 把自动生成的Dockerfile内的AS build 替换成官 ...

  5. 前后端数据交互(四)——fetch 请求详解

    fetch 是 XMLHttpRequest 的升级版,使用js脚本发出网络请求,但是与 XMLHttpRequest 不同的是,fetch 方式使用 Promise,相比 XMLHttpReques ...

  6. Docker(24)- docker login 命令详解

    如果你还想从头学起 Docker,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1870863.html 作用 登录 Docker 镜像仓 ...

  7. Identity用户管理入门二(显示用户列表)

    在Controllers中新建AccountController,并在构造方法(函数)中注入SignInManager,UserManager UserManager   用户管理(注册,查找,修改, ...

  8. C# AutoMaper使用自定义主键

    有时候实际业务中主键不一定叫Id,比如示例数据库Northwind中的RegionID,TerritoryID等,本示例用Abp框架并以Northwind数据库Region表为数据依据 一.在Core ...

  9. 再谈java线程

    线程状态 描述 当线程被创建并启动之后,它既不是已启动就进入到了执行状态,也不是一直处于执行状态.在线程的声明周期中有六中状态. java api中java.lang.Thread.State这个枚举 ...

  10. 使用SQL SERVER存储过程实现历史数据迁移

    今天讲下软件开发中最常见的历史数据迁移方式.在讲迁移之前,先简单介绍下几个基本概念. 1.什么是历史数据迁移? 简单直白地说:就是将一些创建时间比较久而且不常用的历史数据,存储到另一个地方(可以是另一 ...