1. 为什么 Batch Shuffle 跟 Streaming 的 Pipelined Shuffle 不一样?
Streaming 的 pipelined shuffle 强依赖:上游和下游同时运行、边产边传边算。这对资源要求更高(slot、网络 buffer、并发等)。
Batch 的 blocking/hybrid 主要目标是:
- 允许上下游不同时运行(尤其 blocking):用更少资源把任务跑完
- 通过'持久化中间结果'提升稳定性(失败可重读、可恢复)
- 在资源充足时(尤其 hybrid)尽量缩短整体执行时间
一句话:batch shuffle 关注的是**'资源效率 + 稳定性 + 总耗时'**三角平衡。
2. Blocking Shuffle:Hash Shuffle vs Sort Shuffle
Blocking Shuffle 有两种实现:
- Hash Shuffle:Flink 1.14 及以下默认
- Sort Shuffle:Flink 1.13 引入,Flink 1.15 起成为默认
2.1 Hash Shuffle 原理与三个 IO 机制(file / mmap / auto)
Hash Shuffle 的典型行为是:
- 每个 upstream task 会为每个 downstream task写一个独立文件(同一上游会写很多小/中等文件)
- 下游运行时向上游所在 TaskManager 拉取 partition,上游读文件并通过网络发给下游
写读机制(可由 TaskManager 配置选择):
file:普通 File IO 写;读时使用 NettyFileRegion(依赖sendfile)减少拷贝与内存消耗mmap:读写使用mmap系统调用auto:写用 File IO;读在 32 位退回 file,在 64 位使用 mmap(规避 32 位 Java mmap 文件大小限制)
Hash Shuffle 的关键坑点(非常'生产级')
- SSL 开启时:
FileRegion不能用,只能用非池化 buffer 缓存再传,可能引发 direct memory OOM - 同步文件读可能阻塞 Netty 线程:需要增大 SSL handshake timeout,否则可能
connection reset mmap的内存占用不计入 Flink 配置的内存限制,但像 YARN 这类资源管理器可能会统计并在阈值超限时杀 container- 大规模作业会产生海量文件,需要更大的写 buffer,同时也容易把 inode / FD 打爆
- HDD 场景:多个下游并发拉取时更容易触发 随机 IO,性能雪崩
结论:Hash Shuffle 在'小规模 + SSD'还能凑合,一旦规模大、磁盘是 HDD 或开启 SSL,就容易把稳定性问题放大。
2.2 Sort Shuffle:为什么 1.15 以后默认切它?
Sort Shuffle 的核心改动是:
- 每个 result partition 只写一个文件
- 多个下游并发读取同一个 partition 时:文件只打开一次,多读共享
结果就是:inode/FD 更少,稳定性更好 - 读尽量顺序化,尤其 HDD 上比 Hash Shuffle 更友好
- Sort Shuffle ,不依赖 sendfile/mmap,因此

