Как улучшить скорость медленных запросов в секунду при загрузке из ведра облачного хранилища Google

Я получаю данные из своего облачного хранилища Google с @google-cloud/storage библиотекой. Однако я не могу получать из корзины более ~ 5 загрузок в секунду.

const Storage = require('@google-cloud/storage');
const storage = Storage({ keyFilename: './gcloud-api-creds.json' });
const bucket = storage.bucket('my-bucket');

Promise.all(Array.from(Array(80)).map(
  (d,i) => bucket.file(`index.html`)
    .download()
    .then(() => console.log(`done ${i}`))
)).then(() => console.log("READY"));

На выполнение 80 запросов на загрузку уходит около 14 секунд. Я считаю, что достигаю некоторого лимита хранилища для каждого пользователя.

Документы Google Cloud Storage по умолчанию поддерживают ~ 5000 запросов в секунду.

Нет ограничений на чтение объекта. Сегменты изначально поддерживают примерно 5000 операций чтения в секунду, а затем масштабируются по мере необходимости. (https://cloud.google.com/storage/quotas)

Как я могу достичь такой скорости?


person Mikael Lepistö    schedule 01.01.2018    source источник


Ответы (2)


После обсуждения с группой поддержки облачных вычислений Google мы обнаружили, что на самом деле использовалась пропускная способность, которая ограничивала количество запросов в секунду в гибком контейнере движка приложения.

Похоже, что согласно тесту gsutil perf, между экземпляром и корзиной облачного хранилища было всего 65 Мбит.

person Mikael Lepistö    schedule 16.01.2018

Я думаю, что проблема не в библиотеке @google-cloud/storage или каком-либо ограничении скорости, а в том, как используется метод map.

Array.map выполняется синхронно, поэтому, если вы каждый раз будете ждать завершения загрузки перед начиная новый, вы выполняете каждый запрос последовательно, даже если вы используете Promise.all, а не параллельно, поскольку вы не создаете никаких обещаний при работе с массивом. Поэтому вы идете медленнее, чем ожидалось.

Думаю, этот пример может вам пригодиться {source}:

var arr = [1, 2, 3, 4, 5];

var results: number[] = await Promise.all(arr.map(async (item): Promise<number> => {
    await callAsynchronousOperation(item);
    return item + 1;
}));

Согласно документам MDN для _5 _:

Метод Promise.all (итеративный) возвращает обещание, которое разрешается, когда все обещания в итеративном аргументе были разрешены, или отклоняет по причине первого переданного обещания, которое отклоняется.

person GalloCedrone    schedule 01.01.2018
comment
Я знаю, что много раз в stackoverflow люди просто не знали, как писать асинхронный код. На этот раз проблема не в этом, и ответ неверен. Array.map запускается синхронно, но он не ожидает готовности каждой загрузки перед отправкой следующей. Он создает синхронно 80 запросов (80 обещаний), а затем ожидает, что все они будут готовы с promise.all. Вы пробовали самостоятельно получать больше запросов / сек из облачного хранилища с @google-cloud/storage? Если вам удалось этого добиться, мне было бы очень интересно увидеть ваш код и попытаться воспроизвести ваши результаты. - person Mikael Lepistö; 02.01.2018