производительность в google-coud-storage python list_blobs - PullRequest
0 голосов
/ 13 февраля 2019

У меня есть очень простая функция 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 секунд.

Profile from SnakeViz

Я на питоне 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

1 Ответ

0 голосов
/ 15 февраля 2019

Ваш max_results=999999 больше 14599 - количество объектов, все результаты выливаются на страницу single .От Bucket.list_blobs():

Параметры:

max_results (int) - (Необязательно) Максимальное количество BLOB-объектов на каждой страницерезультатов этого запроса.Неположительные значения игнорируются.По умолчанию используется разумное значение, установленное API.

Я предполагаю, что код тратит много времени на блокировку, ожидая, пока сервер предоставит информацию, необходимую для перебора результатов.

Итак, первое, что я бы попробовал, было бы на самом деле перебирать несколько страниц, используя max_results меньше, чем количество BLOB-объектов.Может быть 1000 или 2000 и видите влияние на общую продолжительность?

Может быть, даже пытаетесь использовать несколько страниц явно, используя blobs.pages, как предложено в устаревшем page_token свойстве doc (выделено мое):

page_token (str) - (Необязательно) Если имеется, верните следующую порцию больших двоичных объектов, используя значение, которое должно соответствовать значению nextPageToken, возвращенному в предыдущем ответе. Устаревший: используйте свойство pages возвращенного итератора вместо ручной передачи токена .

Но я не совсем уверен, как заставить несколько страниц быть одновременнотянул.Может как то так?

[(b.name, b.md5_hash) for page in blobs.pages for b in page]
...