基于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. php open_basedir绕过

    描述 php为了安全性考虑,有一项 open_basedir 的设置,它可将用户访问文件的活动范围限制在指定的区域.根据你web服务器环境,open_basedir可以在几个地方设置. 首先 在php ...

  2. 【CSS】计数器

    抄自B站Up主CodingStartup起码课 <!DOCTYPE html> <html lang="en"> <head> <meta ...

  3. git01_常用命令

    git与github介绍 Git是什么 Git是一个开源的[分布式][版本控制系统],用于敏捷高效地处理任何或小或大的项目 版本控制器 CVS/SVN/Git SVN 客户端/服务器 GIT 客户端/ ...

  4. 灵魂画手:漫画图解 SSH

    OpenSSL 本身是一个软件库,这个软件被广泛的应用在系统服务器当中,他的主要功能是在网络通信的过程中,保证数据的一致性以及数据传输过程中的安全性.软件本身是由C语言编写,这使得他具备了跨平台的特性 ...

  5. C#中的文本到语音

    本演示说明了如何使用c#.net Windows Forms应用程序中的system.speech库将文本转换为语音.Microsoft .NET框架提供System.Speech.Synthesis ...

  6. MAC地址知识

    1. 全球唯一无法保障. 软件工具可以修改网卡的MAC地址 2.不需要全球唯一. 只要保障局域网内不重复就行.    路由器 保证 数据在不同局域网内跳转.   如果局域网内使用集线器,那么可以设置相 ...

  7. AspectJWeaver文件写入gadget详解和两种应用场景举例

    目录 0 前言 1 环境 2 gadget解析 2.1 高版本Commons-Collections的防御措施 2.2 获取AspectJWeaver的调用链 2.3 gadget详解 3 两种应用场 ...

  8. cmd中输出换行和转义字符

    cmd 中输出换行和转义字符 今天想写一个安装 Windows 任务的 bat 脚本,在命令行界面输出换行和转义一些字符,居然搜索了好久才搜到正确操作,因此记录一下. 在命令行界面输出换行 echo. ...

  9. PHP怎么遍历对象?

    对于php来说,foreach是非常方便好用的一个语法,几乎对于每一个PHPer它都是日常接触最多的请求之一.那么对象是否能通过foreach来遍历呢? 答案是肯定的,但是有个条件,那就是对象的遍历只 ...

  10. Sentry 监控 - Search 搜索查询实战

    系列 1 分钟快速使用 Docker 上手最新版 Sentry-CLI - 创建版本 快速使用 Docker 上手 Sentry-CLI - 30 秒上手 Source Maps Sentry For ...