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(...) | 指定两侧连接 key | join、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. 学习时最容易混淆的点
-
map() 和 flatMap() 的区别:
map() 必须 1 条进 1 条出;flatMap() 可以 1 条进、多条出。
-
reduce() 和 reduceGroup() 的区别:
reduce() 是逐步两两合并,最终每组只剩 1 条;
reduceGroup() 是把整组交给函数,输出条数不受限制。
-
combineGroup() 和 reduceGroup() 的区别:
combineGroup() 更像“本地预聚合”,主要为了减少后续传输量;
reduceGroup() 是真正的分组整体处理。
-
sortPartition() 和全局排序的区别:
sortPartition() 只保证“每个分区内部有序”,不保证整个 DataSet 全局有序。
-
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. 参考
所有评论(0)