google-coud-storage python list_blobs 性能

mar*_*gas 5 python google-cloud-storage google-api-python-client

我有一个非常简单的 python 函数:

def list_blobs(bucket, project)
    storage_client = storage.Client(project=project)
    bucket = storage_client.get_bucket(bucket)
    blobs = bucket.list_blobs(prefix='basepath/', max_results=999999,
                              fields='items(name,md5Hash),nextPageToken')
    r = [(b.name, b.md5_hash) for b in blobs]
Run Code Online (Sandbox Code Playgroud)

blob 列表包含 14599 个项目,此代码运行需要 7 秒。当进行分析时,大部分时间都浪费在从服务器读取数据上(有 16 次调用 page_iterator._next_page)。

那么,我该如何改进呢?迭代代码在库的深处,指向每个页面的指针都来自前一页,所以我看不出如何并行获取 16 个页面,这样我就可以减少这 7 秒。

SnakeViz 的个人资料

我使用的是 python 3.6.8,

google-api-core==1.7.0
google-auth==1.6.2
google-cloud-core==0.29.1
google-cloud-storage==1.14.0
google-resumable-media==0.3.2
googleapis-common-protos==1.5.6
protobuf==3.6.1
Run Code Online (Sandbox Code Playgroud)

Dan*_*scu 1

您的max_results=999999值大于 14599 - 对象数量,强制将所有结果放入单个页面。从Bucket.list_blobs()

\n\n
\n

参数:

\n\n

max_results (int) \xe2\x80\x93 (可选)此请求的每页结果中的最大 blob 数。非正值将被忽略。\n 默认为 API 设置的合理值。

\n
\n\n

我的猜测是,代码花费了大量时间等待服务器提供迭代结果所需的信息。

\n\n

因此,我尝试的第一件事是使用max_results小于 blob 数量的页面来实际迭代多个页面。也许是 1000 或 2000,看看对总持续时间的影响?

\n\n

也许甚至尝试显式使用多个页面,使用blobs.pages,如已弃用的属性文档中所建议的page_token(强调我的):

\n\n
\n

page_token (str) \xe2\x80\x93 (可选)如果存在,则使用该值返回下一批 blob,该值必须与nextPageToken上一个响应中返回的 \n 值相对应。已弃用:使用pages返回的迭代器的 \n 属性,而不是手动传递 \n 标记

\n
\n\n

但我不太确定如何强制同时拉动多个页面。也许是这样的?

\n\n
[(b.name, b.md5_hash) for page in blobs.pages for b in page]\n
Run Code Online (Sandbox Code Playgroud)\n

  • 你解决了吗?“blobs.pages” 有用吗? (2认同)