Flink批处理中 Operator / Transformation 方法作用总结

说明:
本文总结的是 Flink 经典 DataSet 批处理 API 中常见的 Operator/Transformation 方法。
按 Apache Flink 1.17 官方文档说明,DataSet API 自 1.12 起已进入 soft deprecated 状态;新项目更推荐使用 Table API / SQL,或使用 DataStream API 的 BATCH 执行模式。

1. 基础转换方法

方法作用常见场景说明
map()对每个元素做一对一转换字段加工、类型转换、格式标准化每个输入元素必须返回且只返回 1 个输出元素
flatMap()对每个元素做一对零/一/多转换分词、拆分记录、过滤并展开一个输入元素可以输出多个结果,也可以不输出
mapPartition()以“分区”为单位处理数据分区内批量处理、分区级聚合、减少外部连接次数一次拿到一个并行分区的全部数据,适合批量逻辑
filter()按条件保留元素条件筛选、脏数据过滤返回 true 保留,返回 false 丢弃
project(int...)选择并重排 Tuple 字段只保留部分列、调整字段顺序仅适用于 Tuple DataSet

2. 分组与分组后方法

方法作用常见场景说明
groupBy(...)按 key 分组,得到 GroupedDataSet统计、聚合、去重前分组是后续 reduce、reduceGroup、aggregate 等的基础
sortGroup(...)对每个分组内部排序组内 TopN、组内按时间或分数排序通常与 first(n) 连用
reduce()把每个分组逐步归约为 1 条记录按 key 求和、累加计数返回值中的分组 key 应与输入 key 保持一致
reduceGroup()对每个分组整体处理,可输出任意条结果复杂组内统计、组内去重、组内重组与 reduce() 的区别是它能拿到整组数据
combineGroup()先在本地分区内做预聚合,再进入下一阶段先做局部压缩,减少网络传输属于“局部 combine”,可能产生部分结果
aggregate(SUM/MIN/MAX, field)对分组后的 Tuple 执行内置聚合分组求和、最大值、最小值仅适用于 Tuple DataSet,且分组 key 只支持字段位置
.and(...)在同一次聚合链中继续添加聚合字段同时求和、求最小值等.aggregate(...).and(...) 是对原始分组继续聚合,不是再次聚合前一次结果
minBy() / maxBy()在每个分组中选出指定字段最小/最大的整条元组按组取最优记录、最高分记录返回的是“整条元组”,不是单个字段值
first(n)取每个分组前 n 条记录组内抽样、组内 TopN 的基础步骤若先 sortGroup(),则能实现“按序取前 n 条”

3. 作用于整个 DataSet 的方法

方法作用常见场景说明
reduce()将整个 DataSet 归约成 1 条结果全局求和、全局累加最终归约阶段不能完全并行,但函数可自动 combine
reduceGroup()对整个 DataSet 做整体处理,可输出任意条结果全局复杂统计、整体重组若函数不可 combine,则可能计算开销较大
combineGroup()在各节点本地先进行全量局部 combine预聚合、压缩数据量属于全量数据的局部预处理
aggregate(SUM/MIN/MAX, field)对整个 Tuple DataSet 做内置聚合全局求和、全局最值只适用于 Tuple DataSet
.and(...)追加多个全局聚合字段同时求多个字段统计值与分组聚合中的 .and(...) 作用相同
minBy() / maxBy()从整个数据集中选出某字段最小/最大的整条记录找最小值对应记录、最大值对应记录若有多条并列,返回其中任意一条
distinct()去重全量去重、按字段去重可按整条记录去重,也可按字段位置、KeySelector、key expression 去重
first(n)取整个数据集前 n 条记录样例查看、抽样查看返回的是任意前 n 条,不保证全局排序语义

4. 双输入与关联类方法

方法作用常见场景说明
join()内连接,只保留两边 key 匹配的数据用户表与订单表关联默认是等值连接
where(...).equalTo(...)指定两侧连接 keyjoin、outerJoin、coGroup 等是连接类方法中最常见的 key 指定方式
with(JoinFunction)自定义连接结果输出连接后拼装新结构1 对 1 输出
projectFirst() / projectSecond()从连接结果中选字段并重排只保留所需连接列常用于 join 和 cross 后做投影
joinWithTiny()提示优化器:第二个数据集很小小表广播连接是性能优化提示,不改变语义
joinWithHuge()提示优化器:第二个数据集很大大表连接优化也是优化器 hint
leftOuterJoin()左外连接保留左表全部记录右侧无匹配时右值可能为 null
rightOuterJoin()右外连接保留右表全部记录左侧无匹配时左值可能为 null
fullOuterJoin()全外连接保留两边全部记录任一侧无匹配时另一侧可能为 null
cross()笛卡尔积,两边所有元素两两组合组合枚举、距离矩阵等计算量很大,实际使用要谨慎
crossWithTiny()提示优化器:第二个数据集很小的 cross小规模笛卡尔组合仅是 hint
crossWithHuge()提示优化器:第二个数据集很大的 cross大规模交叉场景优化仅是 hint
coGroup()对两个按同一 key 分组后的数据集做联合分组处理双表分组比较、差异分析、非标准连接某个 key 若只出现在一边,另一边会给空组
union()合并两个或多个同类型 DataSet多批次结果合并、分支结果汇总只是拼接,不会自动去重

5. 分区、排序与数据重分布方法

方法作用常见场景说明
rebalance()把数据均匀重新分配到各并行分区解决数据倾斜属于“均匀重平衡”
partitionByHash()按 key 做哈希分区保证同 key 落到同分区常用于后续分区级处理
partitionByRange()按 key 范围分区范围统计、分区排序前准备适合有序或区间型数据
sortPartition()对每个分区内部排序分区内顺序处理、局部 TopN是“局部排序”,不是全局排序

6. 方法之间的常见关系

组合方式作用
groupBy(...).reduce(...)按 key 做简单聚合,适合求和、计数等
groupBy(...).sortGroup(...).first(n)实现“每组按顺序取前 n 条”
groupBy(...).reduceGroup(...)处理整组数据,适合复杂组内逻辑
partitionByHash(...).mapPartition(...)先按 key 分区,再做分区级批处理
join(...).where(...).equalTo(...).with(...)两表等值连接后生成新结果
distinct(...)去重;若只想保留唯一 key,可与 groupBy 思路对照理解

7. 学习时最容易混淆的点

  1. map() 和 flatMap() 的区别:
    map() 必须 1 条进 1 条出;flatMap() 可以 1 条进、多条出。

  2. reduce() 和 reduceGroup() 的区别:
    reduce() 是逐步两两合并,最终每组只剩 1 条;
    reduceGroup() 是把整组交给函数,输出条数不受限制。

  3. combineGroup() 和 reduceGroup() 的区别:
    combineGroup() 更像“本地预聚合”,主要为了减少后续传输量;
    reduceGroup() 是真正的分组整体处理。

  4. sortPartition() 和全局排序的区别:
    sortPartition() 只保证“每个分区内部有序”,不保证整个 DataSet 全局有序。

  5. union() 和 distinct() 的区别:
    union() 只是合并;
    distinct() 才是去重。

8. 一句话记忆

  • 单条变换:map、flatMap、filter
  • 分区处理:mapPartition
  • 分组聚合:groupBy + reduce/reduceGroup/aggregate
  • 连接关联:join、outerJoin、coGroup
  • 集合关系:union、distinct
  • 分布控制:rebalance、partitionByHash、partitionByRange
  • 排序截取:sortGroup、sortPartition、first

9. 参考

更多推荐