我有一个非常简单的 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]
blob 列表包含 14599 个项目,此代码需要 7 秒才能运行。 进行性能分析时,大部分时间都浪费在从服务器读取数据上(有 16 次调用 page_iterator._next_page。
那么,我该如何改进呢?迭代代码在库中很深,指向每一页的指针都来自前一页,所以我看不出如何并行获取 16 个页面来缩短这 7 秒。
我在 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
最佳答案
您的 max_results=999999
大于 14599 - 对象的数量,迫使所有结果进入单个页面。来自 Bucket.list_blobs()
:
Parameters:
max_results (int) – (Optional) The maximum number of blobs in each page of results from this request. Non-positive values are ignored. Defaults to a sensible value set by the API.
我的猜测是代码花费了大量时间等待服务器提供迭代结果所需的信息。
所以我要尝试的第一件事就是实际遍历多个页面,使用小于 blob 数量的 max_results
。可能是 1000 或 2000,看看对总持续时间的影响?
甚至可以尝试使用 blobs.pages
显式使用多个页面,如已弃用的 page_token
属性文档(强调我的)中所建议的那样:
page_token (str) – (Optional) If present, return the next batch of blobs, using the value, which must correspond to the
nextPageToken
value returned in the previous response. Deprecated: use thepages
property of the returned iterator instead of manually passing the token.
但我不太确定如何强制同时拉取多个页面。也许是这样的?
[(b.name, b.md5_hash) for page in blobs.pages for b in page]
关于python - 谷歌云存储 python list_blobs 性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54666813/