将数据从bigquery导出到Jupyter Notebook花费的时间太长

时间:2018-11-22 14:22:06

标签: python dataframe google-bigquery jupyter-notebook jupyter

在Jupyter Notebook中,我正在尝试在BigQuery服务器上使用类似sql的查询从BigQuery导入数据。然后,我将数据存储在一个数据框中:

import os
os.environ["GOOGLE_APPLICATION_CREDENTIALS"]="credentials.json"
from google.cloud import bigquery

sql = """
SELECT * FROM dataset.table
"""
client = bigquery.Client()
df_bq = client.query(sql).to_dataframe()

数据的形状为(6000000,8),并且一旦存储在数据框中就使用大约350MB的内存。

查询sql(如果直接在BQ中执行)大约需要2秒钟。

但是,通常需要大约30-40分钟的时间来执行上述代码,并且代码执行失败的机会常常多出以下错误:

ConnectionError: ('Connection aborted.', OSError("(10060, 'WSAETIMEDOUT')",))

总而言之,可能有三个错误原因:

  1. BigQuery服务器需要很长时间才能执行查询
  2. 传输数据需要很长时间(我不明白为什么350MB文件需要30分钟才能通过网络发送。我尝试使用LAN连接来消除服务器中断并最大程度地提高吞吐量,但这没有帮助)
  3. 使用BigQuery中的数据设置数据框需要很长时间

很高兴获得对该问题的任何见解,在此先感谢您!

4 个答案:

答案 0 :(得分:1)

使用bigquery存储,可以将bigquery中的大数据查询真正快速地输入到pandas数据框中。

工作代码段:

import google.auth
from google.cloud import bigquery
from google.cloud import bigquery_storage

# Explicitly create a credentials object. This allows you to use the same
# credentials for both the BigQuery and BigQuery Storage clients, avoiding
# unnecessary API calls to fetch duplicate authentication tokens.
credentials, your_project_id = google.auth.default(
    scopes=["https://www.googleapis.com/auth/cloud-platform"]
)

# Make clients.
bqclient = bigquery.Client(credentials=credentials, project=your_project_id,)
bqstorageclient = bigquery_storage.BigQueryReadClient(credentials=credentials)

# define your query
your_query = """select * from your_big_query_table"""

# set you bqstorage_client as argument in the to_dataframe() method.
# i've also added the tqdm progress bar here so you get better insight
# into how long it's still going to take
dataframe = (
    bqclient.query(query_string)
            .result()
            .to_dataframe(
                bqstorage_client=bqstorageclient,
                progress_bar_type='tqdm_notebook',)
)

您可以在此处找到有关如何使用bigquery存储的更多信息:
https://cloud.google.com/bigquery/docs/bigquery-storage-python-pandas

答案 1 :(得分:0)

WSAETIMEDOUT错误表示关联方在一段时间后未正确响应。您需要检查防火墙。

关于:

  1. 查询需要2秒钟才能完成查询
  2. 查看防火墙
  3. 由于您的数据形状为(6000000,8),这将需要一些时间,具体取决于您使用的计算资源

这就是说,由于多维数组花费的时间太长,您可能会达到连接超时。

您可以将查询和数据框分开,并打印时间以更好地了解正在发生的事情。

    result = client.query(sql)
    print(datetime.datetime.now())
    df_bq = result.to_dataframe()
    print(datetime.datetime.now())

答案 2 :(得分:0)

如果上述方法无效,则可以将文件从BQ写入GCS,然后从此处复制到服务器。

或者,您可以在GCE VM上运行笔记本,并充分利用Google的带宽。

答案 3 :(得分:0)

尝试使用BigQuery Storage API-将大型表下载为pandas数据框的速度非常快

https://cloud.google.com/bigquery/docs/bigquery-storage-python-pandas