Apache Beam Dataflow使用splittable = True读取大CSV,导致重复条目

时间:2018-02-13 09:45:58

标签: python google-cloud-dataflow apache-beam apache-beam-io

我使用下面的代码段将CSV文件作为Dicts读入管道。

class MyCsvFileSource(beam.io.filebasedsource.FileBasedSource):
    def read_records(self, file_name, range_tracker):
        self._file = self.open_file(file_name)

        reader = csv.DictReader(self._file, dialect=MyCustomDialect)

        for rec in reader:
            yield rec

这个片段几乎完全是从How to convert csv into a dictionary in apache beam dataflow 的帖子中复制过来的(Pablo的答案)。

后来我注意到这一切都适用于相对较小的文件(例如35k行)。但对于较大的文件,例如。 700k行,我看到输出中生成了重复项(BigQuery)。几乎是因子5,所以我最终得到了超过3M行。

我仔细查看了beam.io.filebasedsource.FileBasedSource并查看了默认设置为splitted的参数True

文档说明了这一点:

splittable (bool): whether :class:`FileBasedSource` should try to
logically split a single file into data ranges so that different parts
of the same file can be read in parallel. If set to :data:`False`,
:class:`FileBasedSource` will prevent both initial and dynamic splitting
of sources for single files. File patterns that represent multiple files
may still get split into sources for individual files. Even if set to
:data:`True` by the user, :class:`FileBasedSource` may choose to not
split the file, for example, for compressed files where currently it is
not possible to efficiently read a data range without decompressing the
whole file.

当参数设置为True时,它能够并行读取源文件。

我注意到,如果我将此参数设置为False,则该文件读取正常,我没有重复。

目前我将此splittable参数设置为False,因为它会保留重复项,但我不确定这是否是我的文件在行中增长时的未来证据。

是否可能存在并行读取源文件的问题?有没有我忽视或没有正确处理的事情?

1 个答案:

答案 0 :(得分:0)

要支持不重复的拆分,从源中读取时必须使用传递的“ range_tracker”对象。例如,当声明要读取的文件的唯一位置时,必须调用try_claim()。

有关更多信息,请参见以下内容。 https://beam.apache.org/documentation/sdks/python-custom-io/