bigquery storage API: Is it possible to stream / save AVRO files directly to Google Cloud Storage?
我想将90 TB BigQuery表导出到Google Cloud Storage。根据文档,由于与其他方法相关联的导出大小配额(例如,ExtractBytesPerDay),BigQuery Storage API(测试版)应该成为首选方法。
该表是按日期分区的,每个分区约占300 GB。我有一个在GCP上运行的Python AI笔记本,该笔记本通过从文档改编的此脚本来运行分区(并行)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | from google.cloud import bigquery_storage_v1 client = bigquery_storage_v1.BigQueryReadClient() table ="projects/{}/datasets/{}/tables/{}".format( "bigquery-public-data","usa_names","usa_1910_current" ) # I am using my private table instead of this one. requested_session = bigquery_storage_v1.types.ReadSession() requested_session.table = table requested_session.data_format = bigquery_storage_v1.enums.DataFormat.AVRO parent ="projects/{}".format(project_id) session = client.create_read_session( parent, requested_session, max_stream_count=1, ) reader = client.read_rows(session.streams[0].name) # The read stream contains blocks of Avro-encoded bytes. The rows() method # uses the fastavro library to parse these blocks as an iterable of Python # dictionaries. rows = reader.rows(session) |
是否可以将流中的数据直接保存到Google Cloud Storage?
我尝试使用fastavro将表作为AVRO文件保存到我的AI实例,然后再使用Blob.upload_from_filename()将它们上传到GCS,但这过程非常缓慢。我希望可以将流指向我的GCS存储桶。我尝试了Blob.upload_from_file,但无法弄清楚。
我无法将整个流解码到内存并使用Blob.upload_from_string,因为我没有超过300 GB的RAM。
我花了最后两天的时间来解析GCP文档,但找不到任何东西,因此,如果有可能,我将非常感谢您的帮助,最好提供代码段。 (如果使用另一种文件格式更容易,我将全力以赴。)
谢谢!
Is it possible to save data from the stream directly to Google Cloud Storage?
BigQuery Storage API本身无法直接写入GCS;您需要将API与代码配对以解析数据,将其写入本地存储,然后上传到GCS。这可能是您手动编写的代码,也可能是某种框架中的代码。
您似乎共享的代码片段以单线程方式处理每个分区,从而将吞吐量限制为单个读取流的吞吐量。该存储API旨在通过并行性实现高吞吐量,因此可以与并行处理框架(例如Google Cloud Dataflow或Apache Spark)一起使用。如果您想使用Dataflow,可以从Google提供的模板开始。对于Spark,您可以使用David已经共享的代码段。
一种简单的方法是将Spark与spark-bigquery-connector一起使用?它使用BigQuery Storage API以便将表直接读取到Spark的DataFrame中。您可以在Dataproc上创建一个Spark集群,该集群与BigQuery和GCS位于相同的数据中心,从而使读写速度更快。
代码示例如下所示:
1 2 3 4 5 | df = spark.read.format("bigquery") \\ .option("table","bigquery-public-data.usa_names.usa_1910_current") \\ .load() df.write.format("avro").save("gs://bucket/path") |
您还可以过滤数据并分别在每个分区上工作:
1 2 3 4 5 6 7 8 9 10 11 12 | df = spark.read.format("bigquery") \\ .option("table","bigquery-public-data.usa_names.usa_1910_current") \\ .option("filter","the_date='2020-05-12'") \\ .load() # OR, in case you don't need to give the partition at load df = spark.read.format("bigquery") \\ .option("table","bigquery-public-data.usa_names.usa_1910_current") \\ .load() df.where("the_date='2020-05-12'").write.... |
请注意,要读取大量数据,您将需要足够大的群集。