首页 > 解决方案 > 如何处理(Apache Beam)高 IO 瓶颈?

问题描述

假设举一个简单的例子,我有一个非常简单的光束管道,它只是从文件中读取数据并将数据转储到输出文件中。现在让我们考虑输入文件很大(几 GB 大小,通常无法在文本编辑器中打开的文件类型)。由于直接运行器实现非常简单(它将整个输入集读取到内存中),它无法读取和输出那些巨大的文件(除非您为 java vm 进程分配了不切实际的大量内存);所以我的问题是:“像 flink/spark/cloud dataflow 这样的生产运行程序”如何处理这个“巨大的数据集问题”?- 假设他们不只是尝试将整个文件/数据集放入内存?” -。

我希望生产运行器的实现需要“分批或分批”工作(例如部分读取/处理/输出),以避免尝试在任何特定时间点将大量数据集放入内存中。有人可以分享他们对生产运行人员如何处理这种“巨大数据”情况的反馈吗?

如果只有一个然后以某种方式参数化管道以批量读/写?还是迭代一个简单的管道并在管道外部管理必要的元数据?

在此先感谢,任何反馈将不胜感激!


编辑(反映大卫的反馈):

大卫,您的反馈非常有价值,并且肯定触及了我感兴趣的点。有一个工作发现阶段来拆分源和读取阶段以同时读取拆分分区绝对是我有兴趣听到的,所以感谢您的指点我在正确的方向。如果您不介意,我有几个小的后续问题:

1 - 文章在“通用枚举器 - 读者通信机制”部分指出以下内容:

“SplitEnumerator 和 SourceReader 都是用户实现的类。实现需要在这两个组件之间进行一些通信的情况并不少见。为了促进这样的用例 [....]”

所以我的问题是,是由某些用户(即开发人员)触发的“拆分+阅读行为”提供了实现(特别是 SplitEnumerator 和 SourceReader),还是我可以在没有任何自定义代码的情况下从开箱即用中受益?

2 - 可能只是更深入地研究上述问题;如果我有批处理/有界工作负载(假设我正在使用 apache flink),并且我有兴趣处理原始帖子中描述的“巨大文件”,那么管道是否会“开箱即用”(做幕后的“工作准备阶段”拆分和并行读取),还是需要开发人员实现一些自定义代码?

提前感谢您的所有宝贵反馈!

标签: apache-sparkapache-flinkgoogle-cloud-dataflowapache-beamdataflow

解决方案


请注意,当输入是有界的并且事先已知时(即,批处理工作负载而不是流式处理),这更简单。

在设计时考虑到流式传输的 Flink 中,这是通过将“工作发现”与“阅读”分开来完成的。单个SplitEnumerator运行一次并枚举要读取的块(拆分/分区),并将它们分配给并行读取器。在批处理情况下,拆分由一系列偏移量定义,而在流式传输情况下,每个拆分的结束偏移量设置为 LONG_MAX。

这在FLIP-27: Refactor Source Interface中有更详细的描述。


推荐阅读