从 GCS 获取海量 csv 文件到 BQ

Posted

技术标签:

【中文标题】从 GCS 获取海量 csv 文件到 BQ【英文标题】:Get a massive csv file from GCS to BQ 【发布时间】:2019-01-08 20:56:39 【问题描述】:

我有一个非常大的 CSV 文件(比如说 1TB),需要从 GCS 获取到 BQ。虽然 BQ 确实有一个 CSV 加载器,但我拥有的 CSV 文件非常不标准,并且在没有格式化的情况下最终无法正确加载到 BQ。

通常我会将 csv 文件下载到服务器上进行“处理”,然后将其直接保存到 BQ 或 BQ 可以轻松摄取的 avro 文件。但是,文件非常大,如果不编写大量代码来优化/流式传输,我很有可能(并且可能)没有存储/内存来进行批处理。

这是使用 Cloud Dataflow 的好用例吗?是否有任何教程可以将格式为“X”的文件从 GCS 获取到 BQ 中?任何这样做的教程指针或示例脚本都会很棒。

【问题讨论】:

Dataflow 可以使用 Python 或 Java 完成此任务,Dataprep 也可以为您完成。 @Pablo 是否有任何示例链接可以显示如何使用 Dataflow 完成此类操作? 【参考方案1】:

我会亲自使用 Dataflow(而不是 Dataprep)并编写一个简单的管道来并行读取文件、清理/转换文件,最后将其写入 BigQuery。这很简单。 Here's 我的 GitHub 存储库中的一个示例。尽管它使用 Java,但您可以轻松地将其移植到 Python。注意:它使用 Dataflow 中的“模板”功能,但可以通过一行代码更改。

如果 Dataflow 不可用,另一种选择可能是使用奇怪/未使用的分隔符并将整行读入 BigQuery。然后使用 SQL/Regex/UDFs 来清理/转换/解析它。请参阅here(Felipe 的建议)。过去我们已经多次这样做了,而且因为您在 BigQuery 中,它的扩展性非常好。

【讨论】:

在上面使用奇怪的分隔符的非常有趣的方法。我有时在熊猫中使用它来将所有数据放入一列。然而,我们在使用这种方法时遇到的一件事是,行有时没有\n 分隔符。我见过诸如\x02 之类的字段终止符,因此一条记录将跨越两行(或更多行)。有没有可能用 BQ 方法解决这个问题?【参考方案2】:

我会考虑使用Cloud Dataprep。

Dataprep 可以从 GCS 导入数据、清理/修改数据并导出到 BigQuery。我喜欢的功能之一是一切都可以可视化/交互方式完成,这样我就可以看到数据是如何转换的。

从您的数据子集开始,了解需要进行哪些转换,并在加载和处理 TB 数据之前给自己一些练习。

【讨论】:

感谢您的建议。使用 Dataflow 与 Dataprep 有什么区别?要么适合这项工作,还是 Cloud Dataflow 不适合上述工作? Dataflow 使用软件(通常是 Python),Dataprep 使用可视化仪表板。两者都会做你想做的,只是不同的技术。 我尝试使用 Dataprep 的界面几次,每次都遇到导入文件的限制。例如,json文件必须是json-newline等。每次我使用它时,我实际上都无法完成我所需要的,所以我认为Dataflow可能更适合这个任务。 一个奇怪的事实是 Dataprep 生成 Dataflow 管道并运行它们。 Dataprep 作为一种可视化工具比使用 SDK 本身编写 Dataflow 管道更受限制。 @Pablo - 同意。不是每个人都可以编写(甚至想编写)Python 或 Java 程序。一些分析师想要可视化或拖放式工具,并且不需要开发人员为它们编写程序。我是一名开发人员,我尝试使用正确的工具来完成这项工作。有时这是 Dataprep,有时是 Dataflow,有时是 Dataproc,有时是在 GCE 上运行的简单 Python 脚本,在直接导入 BQ 之前读取和写回 GCS。【参考方案3】:

您始终可以从存储桶直接转移到 BQ 表中:

bq --location=US load --[no]replace --source_format=CSV dataset.table gs://bucket/file.csv [schema]

在这里,[schema] 可以是 csv 文件的内联架构(如 id:int,name:string,..)或 JSON 架构文件的路径(本地可用)。

根据 BQ 文档,他们尝试将大型 CSV 负载并行化到表中。当然,这涉及到一个上限:从 GCS 加载到 BQ 的未压缩 (csv) 文件的最大大小应该

【讨论】:

理论上这很好用。但是,在实践中,这些文件通常不是“BQ-ready”。例如,文件中的(字段)分隔符可能是非标准分隔符,例如\x01,可能不在第一行开始,可能有注释字符等。鉴于此要求,您建议如何做? 来自这里的链接 -- cloud.google.com/bigquery/docs/loading-data-cloud-storage-csv -- 我们会遇到四个限制中的四个,并且我们的 csv 编码(分隔符部分)也不适用于 BQ。换句话说,我们需要对文件进行“预处理”。

以上是关于从 GCS 获取海量 csv 文件到 BQ的主要内容,如果未能解决你的问题,请参考以下文章

CSV 到 BQ:空字段而不是空值

数据流 GCS 到 BQ 问题

大查询 csv 加载问题

将 GCS 文件加载到 BigQuery 的 Cloud Functions 的 Python 单元测试

无法将 csv 文件从 GCS 加载到 bigquery

将海量 CSV 文件读入 Oracle 表