为什么在运行管道时将零字节文件写入GCS?

时间:2015-02-19 07:43:20

标签: google-cloud-storage google-cloud-dataflow

我们的工作/管道正在将ParDo转换的结果写回GCS,即使用TextIO.Write.to("gs://...")

我们注意到,当作业/管道完成时,它会在输出桶中留下许多0字节文件。

管道的输入来自GCS的多个文件,所以我假设结果是分片的,这很好。

但为什么我们得到空文件?

enter image description here

1 个答案:

答案 0 :(得分:8)

这些空分片很可能是中间管道步骤的结果,结果有些稀疏,一些预分区的分片中没有记录。

E.g。如果在TextIO.Write之前有一个GroupByKey,比如说,键空间被分片为范围[00,01],[01,02],...,[fe,ff)(总共255个分片),但是所有从这个GroupByKey的输入发出的实际键位于[34,81]和[a3,b5]范围内,然后将生成255个输出文件,但大多数将变为空。 (这是一个假设的分区方案,只是为了给你一个想法)

我的答案的其余部分将采用Q& A的形式。

为什么要生成空文件?如果没有要输出的内容,请不要创建文件! 确实,技术上可以避免产生它们,例如,通过在写入第一个元素时写入输出时懒惰地打开它们。 AFAIK我们通常不会这样做,因为空输出文件通常不是问题,并且比没有文件更容易理解空文件:如果,例如,只有50个分片中的第一个被证明是非常混乱的非空,你只能有一个名为00001-of-000050的输出文件:你会想知道其他49个输出文件发生了什么。

但为什么不添加后处理步骤来删除空文件?原则上我们可以添加一个删除空输出并重命名其余的后处理步骤(与xxxxx-of-yyyyy filepattern)如果空输出成为一个大问题。

是否存在空分片在我的管道中发出问题? 很多空的分片可能意味着系统选择的分片是次优/不均匀的,我们应该将计算分成更少,更均匀的分片。如果这对您来说是一个问题,您能否提供有关管道输出的更多详细信息,例如:您的屏幕截图显示非空输出也很小:它们是否只包含少量记录? (如果是这样,可能很难在不事先知道数据的情况下实现统一分片)

但是我的原始输入的分片不是空的,不会对输入的输出镜像分片进行分片?如果你的管道有GroupByKey(或派生)操作,那么将有中间步骤输入和输出中的分片数量不同:例如操作可能消耗30个输入分片但产生50个分片输出,反之亦然。在不涉及GroupByKey的其他一些情况下,输入和输出中也可能有不同数量的分片。

TL; DR如果您的总体输出是正确的,那不是错误,但请告诉我们您是否有问题:)