如何使用Beam读取大型CSV?

时间:2018-07-20 09:17:46

标签: apache-beam

我试图弄清楚如何使用Apache Beam读取大型CSV文件。 “大”是指几千兆字节(因此一次将整个CSV读取到内存中是不切实际的。)

到目前为止,我已经尝试了以下选项:

  • 使用TextIO.read():这不好,因为带引号的CSV字段可能包含换行符。此外,这会尝试一次将整个文件读入内存。
  • 编写一个DoFn,将其作为流读取文件并发出记录(例如,使用commons-csv)。但是,这仍然会一次读取整个文件。
  • 尝试使用SplittableDoFn as described here。我的目标是使它逐渐作为Unbounded PCollection发出记录-基本上是将我的文件转换为记录流。但是,(1)很难正确计算计数;(2)由于ParDo创建了多个线程,因此需要进行一些hacky同步;(3)我得到的PCollection仍然不受限制。
  • 尝试创建自己的UnboundedSource。这似乎非常复杂并且没有充分的文档记录(除非我遗漏了什么?)。

Beam是否提供任何简单的方法来允许我以自己想要的方式解析文件,而不必在进行下一个转换之前将整个文件读入内存?

1 个答案:

答案 0 :(得分:0)

TextIO应该按照Beam的预期做正确的事情,Beam希望尽快读取文本文件并将事件发送到下一个阶段。

我猜您正在为此使用DirectRunner,这就是为什么您看到大量内存占用的原因。希望这不是太多的解释:DirectRunner是用于小型作业的测试运行器,因此可以将中间步骤缓冲在内存中而不是磁盘上。如果仍在测试管道,则应使用一小部分数据样本,直到您认为它可以工作为止。然后,您可以使用Apache Flink运行器或Google Cloud Dataflow运行器,它们都将在需要时将中间阶段写入磁盘。