Как масштабировать S3 до тысячи запросов в секунду? - PullRequest
2 голосов
/ 31 марта 2019

Состояния документации AWS S3 (https://docs.aws.amazon.com/AmazonS3/latest/dev/request-rate-perf-considerations.html):

. Amazon S3 автоматически масштабируется до высокой частоты запросов. Например, ваше приложение может выполнить не менее 3500 запросов PUT / POST / DELETE и 5500 запросов GET в секунду.для каждого префикса в сегменте.

Для проверки этого у меня есть следующий код NodeJS (с использованием aws-sdk), который асинхронно инициирует 1000 загрузок нулевых байтов (следовательно, просто добавляя пустые записи в сегмент).Имеется таймер для измерения пропускной способности:

var t0 = new Date().getTime()
for (var i = 0; i < 1000; i++) {
  var s3 = new AWS.S3()
  var id = uuid()
  console.log('Uploading ' + id)
  s3.upload({
      Bucket: bucket,
      Body : '',
      Key : "test/" + id
    },
    function (err, data) {
      if (data) console.log('Uploaded ' + id + ' ' + (new Date().getTime() - t0))
      else console.log('Error')
    })
}

Для выполнения всех запросов на загрузку требуется приблизительно 25 секунд. Это, очевидно, далеко не заявленные 3500 запросов в секунду, а скорее приблизительно 40 запросов в секунду.

У меня примерно 1 МБ скорости загрузки по сети, и статистика сети показывает, что в большинстве случаев полоса пропускания заполнена только на 25%. В равной степени загрузка ЦП также низкая.

Так что вопрос:

Как я могу увеличить пропускную способность загрузки S3, чтобы достичь чего-то около 3500 рчто может быть достигнуто в секунду, что может быть достигнуто?

РЕДАКТИРОВАТЬ:

Я изменил код следующим образом:

var t0 = new Date().getTime()
for (var i = 0; i < 1000; i++) {
  var s3 = new AWS.S3()
  var id = String.fromCharCode('a'.charCodeAt(0) + (i % 26)) + uuid()
  console.log('Uploading ' + id)
  s3.upload({
      Bucket: bucket,
      Body: '',
      Key: id
    },
    function (err, data) {
      if (data) console.log('Uploaded ' + id + ' ' + (new Date().getTime() - t0))
      else console.log('Error')
    })
}

Это использует26 различных префиксов, которые, как утверждает документация AWS, должны масштабировать пропускную способность в 26 раз.

"Производительность чтения или записи просто экспоненциально увеличить.Например, если вы создаете 10 префиксов в корзине Amazon S3 для распараллеливания операций чтения, вы можете увеличить производительность чтения до 55 000 запросов на чтение в секунду. "

Однако никакой разницы в пропускной способности не видно.Существует некоторое различие в поведении, так что кажется, что запросы выполняются более параллельно, а не последовательно - но время завершения примерно одинаково.

Наконец, я попытался запустить приложение вx4 отдельных потока bash (4 потока, 4 ядра, 4x1000 запросов). Несмотря на добавленный параллелизм от использования нескольких ядер, общее время выполнения составляет около 80 секунд и, следовательно, не масштабируется.

for i in {0..3}; do node index.js & done

IИнтересно, ограничивает ли S3 скорость отдельных клиентов / IP-адресов (хотя это, по-видимому, не задокументировано)?

Ответы [ 2 ]

4 голосов
/ 31 марта 2019

Прежде чем дать прямой ответ на ваш вопрос, я должен упомянуть несколько вещей.

Во-первых, я однажды провел эксперимент, и я выполнил 200000 PUT / DELETE запросов примерно за 25 минут, что составляет чуть более 130 запросов в секунду.Объекты, которые я загружал, имели размер около 10 КБ каждый.(У меня также было ~ 125000 GET запросов за тот же промежуток времени, поэтому я уверен, что, если бы я только делал PUT с, я мог бы достичь еще более высокой пропускной способности PUT.) Я достиг этого наЭкземпляр m4.4xlarge, имеющий 16 виртуальных ЦП и 64 ГБ ОЗУ, который работал в том же регионе AWS, что и корзина S3.

Чтобы повысить пропускную способность, используйте более мощное оборудование и минимизируйте количество сетевых скачков и потенциальных узких мест между вами и S3.

S3 - распределенная система.(В их документации говорится, что данные реплицируются на несколько AZ.) Он предназначен для одновременного обслуживания запросов от множества клиентов (поэтому он отлично подходит для размещения статических веб-ресурсов).

Реально, если вы хотите проверить пределы S3, вам тоже нужно распределиться, раскручивая парк экземпляров EC2 или выполняя свои тесты как лямбда-функцию.

Редактировать: S3 не дает гарантии задержки для обслуживания ваших запросов.Одной из причин этого может быть то, что каждый запрос может иметь разный размер полезной нагрузки.(Запрос GET для объекта 10 B будет намного быстрее, чем объект 10 МБ.)

Вы продолжаете упоминать время для обработки запроса, но это не обязательно коррелирует с количеством запросов в секунду.,S3 может обрабатывать тысячи запросов в секунду, но ни один потребительский портативный компьютер или обычный потребительский сервер, о котором я знаю, не может выдавать тысячи отдельных сетевых запросов в секунду.

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

Вам необходимо тщательно определить, что вы хотите выяснить, а затем тщательно определить, как правильно его проверить.

1 голос
/ 31 марта 2019

Еще одна вещь, на которую стоит обратить внимание, это используемый HTTPS-агент.

Раньше было (и, вероятно, все еще), что в AWS SDK используется глобальный агент. Если вы используете агент, который будет повторно использовать соединения, это, вероятно, HTTP / 1.1 и, вероятно, конвейер отключен из соображений совместимости.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...