4

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

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

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

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

在此处输入图像描述

4

1 回答 1

8

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

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

我的其余答案将以问答的形式。

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

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

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

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

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

于 2015-02-19T15:48:02.683 回答