- PVSM.RU - https://www.pvsm.ru -
Любой прогресс и оптимизация приветствуется кем угодно. Сегодня хотелось бы поговорить про прекрасную вещь, значительно облегчающую жизнь – очереди. Внедрение best practices в этом вопросе не только улучшают производительность приложения, но и успешно готовят ваше приложение к архитектуре «в стиле» Cloud Computing. Тем более, что не использовать уже готовые решения от провайдеров облачных технологий просто глупо.
В этой статье мы рассмотрим Amazon Web Services с точки зрения проектирования архитектуры средних и больших веб приложений.
Рассмотрим схему такого приложения:

Примерами такой организации могут быть различного рода агрегаторы: новости, курсы валют, котировки бирж и т.д.
External data providers генерируют поток сообщений, которые, проходя постобработку, сохраняются в базе.
Пользователи через web-tier делают выборку информации из базы по определённым критериям (фильтры, группировка, сортировка), а затем опциональная обработка выборок (различные статистические функции).
Amazon старается определить наиболее типовые компоненты приложений, затем автоматизирует и предоставляет компонент-сервис. Сейчас таких сервисов уже более двух десятков и с полным списком можно ознакомиться на сайте AWS: http://aws.amazon.com/products/ [1]. На хабре уже была статья с описанием ряда популярных сервисов: Популярно об Amazon Web Services [2]. Привлекательно это в первую очередь тем, что отпадает необходимость в самостоятельной установке и конфигурации, а так же более высокой надёжностью и сдельной оплатой
И если использовать AWS, то схема проекта будет выглядеть так:

Несомненно, этот подход востребован и у него есть свой рынок. Но часто возникают вопросы о финансовой составляющей:
Далее мы постараемся ответить на эти вопросы.
Для сравнения будем рассматривать следующие компоненты:
Сервис SQS оплачивается из расчета количества запросов к API + трафик
Рассмотрим каждый сервис подробнее.
Amazon SQS – это сервис позволяющий создавать и работать с очередями сообщений. Стандартный цикл работы с готовой очередью SQS следующий:
Таким образом, в среднем для отправки и обработки одного сообщения необходимо 3 вызова API.
Используя SQS, вы платите за количество вызовов API + трафик между регионами. Стоимость 10к вызовов составляет 0.01$, т.е. в среднем за 10к сообщений (х3 вызова API) вы платите 0.03$. Расценки в других регионах вы можете посмотреть тут [3].
Существует большое количество вариантов организации сервиса отправки сообщений:
Каждый вариант имеет свои плюсы и минусы. Мы выберем RabbitMQ, как одну из самых популярных реализацию протокола AMQP.
Сервер с установленным RabbitMQ и настройками по умолчанию выдаёт очень хорошую производительность. Но такой вариант деплоймента нас не устраивает, т.к. в случае падения этого узла мы можем получить сразу ряд проблем:
В тестировании будем использовать 2 узла в режиме active-active с репликацией очередей между узлами. В рамках RabbitMQ это называется mirrored queues.

Для каждой такой очереди определяется мастер и набор слейвов, где хранится копия очереди. В случае падения мастер-узла, один из слейвов выбирается мастером.
Что бы создать такую очередь задаётся параметр «x-ha-policy» при декларировании, который указывает, где должны храниться копии очереди. Возможны 2 значения параметра
Детальнее о mirrored queues можно почитать тут: http://www.rabbitmq.com/ha.html [4].
Ранее мы рассмотрели, как будет организовано тестовое окружение. Теперь давайте рассмотрим, что и как мы будем мерять.
Для всех измерений использовались m1.small инстансы (AWS).
Будем проводить ряд замеров:
Скорость отправки сообщений до определённого значения, потом скорость получения – тем самым мы проверим деградацию производительности с увеличением очереди.
1. Скорость отправки сообщений до определённого значения, потом скорость получения – тем самым мы проверим деградацию производительности с увеличением очереди.
2. Одновременная отправка и получение сообщений из одной очереди.
3. Одновременная отправка и получение сообщений из разных очередей.
4. Асимметричная нагрузка на очередь:
5. Отправка и получение сообщений разных размеров:
Все тесты кроме первого будут проводиться в 3 этапа:
Подтверждение и получение сообщений (Message Acknowledgement)
Это свойство используется для подтверждения доставки и обработки сообщения. Существует два режима работы:
В тесте выбран второй режим, т.к. он соответствует работе SQS, где обработка сообщения делается двумя командами: ReceiveMessage и DeleteMessage.
Batch processing
Что бы не тратить на каждом сообщении время для установки соединения, авторизации и прочего, RabbitMQ и SQS позволяют обрабатывать сообщения пакетами. Это доступно как для отправки, так и для получения сообщения. Т.к. пакетная обработка по умолчанию отключена и в RabbitMQ и в SQS, мы так же не будем её использовать для сравнения.
Load-Unload Test
Сводные результаты:
| Load-Unload Test | msg/s | Время запроса | ||||
| avg, ms | min, ms | max, ms | 90%, ms | |||
| SQS | Consume | 198 | 25 | 17 | 721 | 28 |
| Produce | 317 | 16 | 10 | 769 | 20 | |
| RabbitMQ | Consume | 1293 | 3 | 0 | 3716 | 3 |
| Produce | 1875 | 2 | 0 | 14785 | 0 | |
Из таблицы видно, что SQS работает значительно стабильнее, чем RabbitMQ, в котором возможны провалы при отправке сообщения на 15 секунд! К сожалению, сразу причину такого поведения найти не удалось, а в тесте стараемся придерживаться стандартных настроек. При этом средняя скорость у RabbitMQ примерно в 6 раз выше, чем у SQS, а время выполнения запроса в несколько раз ниже.
Далее приведены графики с распределением средней скорости в зависимости от времени.


В целом, не падения производительности с ростом количества сообщений в очереди не замечено, а значит можно не бояться, что при падении принимающих узлов очередь станет узким местом.
Parallel
Не менее интересен тест зависимости скорости работы от количества одновременно работающих потоков. Результаты теста SQS можно легко предугадать: поскольку работа идёт по HTTP протоколу и большую часть времени занимает установка соединения, то, предположительно, результаты должны расти с количеством потоков, что хорошо иллюстрирует следующая таблица:
| SQS msg/s |
Threads | |||
| 1 | 5 | 10 | 40 | |
| Produce | 65 | 324 | 641 | 969 |
| Consume | 33 | 186 | 333 | 435 |
Среднее время одного запроса для отправки сообщения составляет 16 мс, а для получения 29 мс.
Так же видно, что для 1, 5 и 10 потоков зависимость линейная, но при увеличении до 40 потоков, средняя скорость возрастает на 50% для отправки и 30% для получения, но при этом значительно возрастает среднее время запроса: 43мс и 98мс соответственно.
Для RabbitMQ насыщение по скорости происходит значительно быстрее, уже при 5 потоках достигается максимум:
| RabbitMQ Threads | Threads | ||||
| 1 | 5 | 10 | 40 | ||
| Produce | speed, msg/s | 3086 | 3157 | 3083 | 3200 |
| latency, ms | 0 | 1 | 3 | 11 | |
| Consume | speed, msg/s | 272 | 811 | 820 | 798 |
| latency, ms | 3 | 6 | 12 | 51 | |
При тестировании обнаружилась особенность: если одновременно работают 1 поток на отправку и 1 поток на получение, то скорость получения сообщений падает практически до 0, при этом поток отправки показывает максимальную производительность. Проблема решается, если принудительно переключать контекст после каждой итерации теста, при этом падает пропускная способность отправки, но значительно снижается верхняя граница времени выполнения запроса. Из локальных тестов при 1 потоке (отправка/чтение): 11000/25 против 5000/1000.
Дополнительно провели тест для RabbitMQ с несколькими очередями для 5 потоков:
| RabbitMQ | Queues | |
| 1 | 5 | |
| Produce | 3157 | 3489 |
| Consume | 811 | 880 |
Видно, что скорость для нескольких очередей немного выше. Сводные результаты для 10 потоков представлены на следующей диаграмме:

Size
В этом тесте рассмотрим зависимость скорости от размера передаваемых данных.
И RabbitMQ и SQS показали ожидаемое ухудшение скорости отправки и получения с ростом размера сообщения. Помимо этого, очередь в RabbitMQ с ростом размера сообщения чаще «зависает» и не отвечает на запросы. Это косвенно подтверждает догадку о том, что это связанно с работой с жестким диском.
Сравнительные результаты скорости:

Сравнительные результаты времени запроса:

Из расчётной стоимости 0.08$ за один small instance в европейском регионе получаем стоимость в 0.16$ за RabbitMQ в конфигурации из двух узлов + стоимость трафика. В SQS стоимость отправки и получения 10000 сообщений составляет 0.03$. Получаем следующую зависимость:

60 тысяч сообщений в час – это примерно 17 сообщений в секунду, что значительно меньше, чем скорость, которую могут обеспечить SQS и RabbitMQ.
Таким образом, если вашему приложению требуется скорость в среднем меньше 17 сообщений в секунду, то предпочтительным будет использовать SQS. Если потребности приложения становятся выше, то стоит рассмотреть пути миграции на выделенные messaging сервера.
Важно понимать, что эти рекомендации справедливы только для средних скоростей, и расчёты надо проводить на всём периоде цикла колебаний нагрузки, но если вашему приложению в пике требуется скорость значительно выше, чем позволяет SQS, то это так же повод задуматься о смене провайдера.
Ещё одной причиной использовать RabbitMQ может стать требование к latency запроса, которая на порядок ниже, чем у SQS.
Есть два пути снижения стоимости:
В первом случае теряется HA кластера в случае падения узла или всей активной зоны, но это не страшно, если всё приложение только в одной зоне.
Во втором случае micro instance могут быть урезаны ресурсы, если в течение некоторого времени утилизация ресурсов близка к 100%. Это может повлиять на работу очереди, когда используется persistence очереди.
Таким образом мы видим, что однозначного ответа на вопрос «А какое же решение использовать мне?» просто нет. Все зависит от множества факторов: от размера вашего кошелька, от количества сообщений в секунду и времени отправки этих сообщений. Тем не менее, на основании метрик, приведенных в этом материале, можно просчитать поведение для конкретного случая.
Спасибо!
Статья написана и адаптированна по материалам исследования Максима Брюнера, для EPAM Cloud Computing Competency Center
Автор: lemieux66
Источник [6]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/amazon-web-services/22109
Ссылки в тексте:
[1] http://aws.amazon.com/products/: http://aws.amazon.com/products/
[2] Популярно об Amazon Web Services: http://habrahabr.ru/post/138695/
[3] тут: http://aws.amazon.com/sqs/#pricing
[4] http://www.rabbitmq.com/ha.html: http://www.rabbitmq.com/ha.html
[5] хостится: https://www.reg.ru/?rlink=reflink-717
[6] Источник: http://habrahabr.ru/post/161787/
Нажмите здесь для печати.