System design — проектируем брокер сообщений
Предисловие
Общаясь со многими разработчиками выяснил - тема архитектуры и архитектурные интервью часто вызывают трепет даже у опытных ребят. Решил накинуть ряд статей на вентилятор Хабра для обсуждения и популяризации этой темы.
О чем статья
Статья построена в стиле архитектурного интервью. Она в первую очередь нацелена на размышление в рамках конкретной задачи, Активность читателей приветствуется :)
В этой статье я постараюсь разобрать устройство очередей. Обсудим зачем этот инструмент нужен. Разберу популярные решения и нарисуем архитектурную часть, которая может пригодиться в жизни и на интервью.
P.S.: Постараюсь все объяснить обычным языком. Цель помочь тем ребятам которые хотят разобраться. А технической литературы на эту тему много и без меня :)
Общая теория
Брокер сообщений (иначе очереди) - это инструмент который помогает общаться программам в асинхронном режиме. Иначе брокер это курьер который берет письмо у одной программы и отдает её другой.
Пример из жизни
Представьте жизненную ситуацию: вы решили отправить письмо. Написали его и запечатали. На конверте оформили все по шаблону. Посылка готова. К вам приезжает курьер и забирает её. Далее вы продолжаете заниматься своими делами пока курьер разбирается с письмом и доставляет его бабушке в Балашиху или Папе в Рим.
Так получается и с программой: отдает сообщение и продолжает свою работу. Если брокер сказал что письмо оформлено корректно и принято для отправки, то программе больше не нужно "думать" как там дела.
Виды брокеров сообщений
Брокеров можно разделить на два типа:
Умный брокер - этот тот кто получает письмо и как курьер сам связывается с получателем и отдает его.
Глупый брокер - это как пункт выдачи товаров. Письмо пришло, но получатель должен забрать его самостоятельно.
На практике если нужен умный брокер, используют RabbitMQ. А если нужен глупый брокер, то Kafka.
Нужно помнить что все инструменты отличаются и этот случай не исключение
Критерий |
RabbitMQ |
Apache Kafka |
Модель |
Сам доставит куда нужно |
Сохранит сообщение и будет ждать пока его заберут |
Скорость |
~10 000 RPS |
~1 000 000 RPS |
Масштабируемость |
Вертикальная |
Горизонтальная |
Хранение данных |
Удаляет сообщение после чтения получателем |
Может хранить годами даже прочитанное |
Использование |
RPC, микросервисы, сделать PHP "Параллельным" |
Микросервисы, стириминг, логи |
Сложность использования |
Проще |
Сложнее |
Подводим итог этой части
RabbitMQ:
— Кину в нужную очередь, а если адресат не онлайн — оставлю у себя, пока не заберёт.Kafka:
— Буду кричать в рупор, разошлю всем подряд, и пусть сами разбираются, кому оно нужно.
Вот мы поднабрались теории, переходим к интервью :)
План собеседования
Задаем вопросы
Рисуем драфт схемы
Рассуждаем про инструменты и выбираем что будем использовать
Рисуем финальную схему
Делаем расчеты по железу
Задаем вопросы перед началом работ
Начало работы над любым проектом/задачей или на архитектурном интервью обязательно должен начинаться с разбора границ системы. Иначе можно построить звездолет когда он не требуется или наоборот собрать что-то простенькое и упасть на проде.
Вопрос: существует два вида брокеров умный и глупый какой вариант будем проектировать,
Ответ: на твой выборВопрос: Есть ли какие-то ограничения по данным? Могут ли передаваться данные большого объема?
Ответ: давай пока это пропустим. Пока считаем что что-то крупное посылать не будем.Вопрос: а сколько память будет занимать одно сообщение?
Ответ: пусть в теле будет передаваться json с небольшим массивом данных. Тело пусть будет не более 1кбайтаВопрос: подскажите какая нагрузка ожидается?
Ответ: в сутки очень много запросов.Вопрос: а подскажите пиковую нагрузку в RPS?
Ответ: в пике достигает 30К RPSВопрос: ожидается ли увеличение системы и нагрузки в обозримом будущем,
Ответ: да ожидается, на сколько не знаем.Вопрос: Нужно ли нам сохранять прочитанные сообщения или сразу удаляем?
Ответ: Давай без сохраненияВопрос: Какой лимит по времени доставки сообщения?
Ответ: чем быстрее тем лучшеВопрос: Насколько система должны быть устойчива к падениям?
Ответ: хочется надежную технологию 99.99Вопрос: Как много сервисов будет использовать брокера на запись и чтение?
Ответ: давай не будем к этому привязыватьсяВопрос: учитываем ли мониторинги? И будет ли аллертинг?
Ответ: мониторинги нужны. Аллертинг дав пропустим.Вопрос: если при даунтайме будет потеря данных нам это критично?
Ответ: не хотелось бы, но переживем.
Мы задали вопросы и немного поняли картину которую от нас ждут. Теперь можем приступить к проектированию.
Оставьте в комментариях вопросы и ответы как бы поступали вы находясь на месте интервьюера или собеседующего.
Рисуем базовую схему
Исходя из диалога выше мы понимаем, что глупый брокер нам подходит лучше и рисуем базовую схему

Внимательные увидят не нужный элемент. Пишите в комментариях что можно убрать из это схемы.
В базовой схеме не пытайтесь нарисовать и учесть все. Лучше накидать базовый драфт и после сказать: Я нарисовал драфт и куда стоит углубиться дальше? Так как задача не крупная, вероятный ответ будет абстрактным

Это дает нам волю фантазии. И мы можем продолжать рассуждать в слух и реализовать схему.
Важное про выбор инструментов
Здесь сильную роль играет ваш опыт, либо если нет опыта, то хорошая погруженность в технологию. Делать

это плохая идея как в работе так и на практике :)
Что должно учитываться при выборе инструмента:
Личные знания.
Понимание что делать если все упало.
Насколько технология популярна. Иначе говоря насколько легко заменить сотрудника для работы с выбранной вами технологией.
Стоимость обслуживания и использования.
Какие БД можем использовать
У нас по условиям задачи не нужно сохранять сообщения. Из-за этого база данных не нужна. Но на случай когда нужно сохранять я бы пошел так:
Для данной задачи нам подойдет реляционная БД. Кто-то скажет почему не ZooKeeper? - да можно выбрать его и это хороший выбор. Но напомню у нас тут технопоп, а не технопопа :)
Из реляционных БД самые часто используемые MySQL и PostgreSQL. Тут в принципе на усмотрение каждого, но я выберу MySQL - знаком с ним со времен когда модемы умели говорить:
"КШШШШШШШШШШИИИИИИИИИИИИРРРРРРРРРРРРРРРРРР...ПИИИ-ПИИИ-ПИИИ... ВЖЖЖЖЖЖУУУУУУ... КРРР-КРРР-КРРР..."
Но для справедливости сравним два инструмента
Критерии |
MySQL |
Zookeeper |
Производительность |
~50 000 RPS |
~ 10 000 RPS |
Масштабируемость |
Горизонтальная |
Вертикальная |
Хранение |
На жестком диске |
Данные в памяти + на жестком диске |
Отказоустойчивость |
Ниже |
Выше для запуска требуется 3 ноды |
Сложность |
Ниже |
Выше |
Какой кеш лучше выбрать?
Будем выбирать между Redis и MemCache.
Нам требуется в первую очередь кеширование. Получается из "плюшек" Redis можно выделить только "прогрев из коробки" - это когда при перезагрузке системы, данные в кеш вернуться автоматически. Но мемкеш проще и в вопросах сказано, что нам можно потерять немного данных. Выигрывает мемкеш - дешевле, быстрее ~200K RPS.
Балансировщик нагрузки
Выбираем между NGinx и HAPRoxy.
Критерий |
NGinx |
HAPRoxy |
Производительность |
Ниже |
Выше |
Алгоритмы балансировки |
Round-robin, Least Connections |
Leastconn, Source-IP, Hash |
Чаще используется |
Веб сервер, API, статика |
Брокеры сообщений |
Сложность |
Ниже |
Выше |
Тут я выберу хапрокси.
Мониторинг
Тут на самом деле выбор за каждым. Я буду рассматривать два варианта: Elasticsearch и Clickhouse. Оба варианта имеют ряд индивидуальных нюансов. В том числе и индивидуальных для разработчика.
Критерий |
Elasticsearch |
Clickhouse |
Скорость записи |
Ниже |
Выше |
Скорость чтения |
Высокая |
Высокая |
Поддержка SQL |
Ниже |
Полноценно |
ОЗУ |
Жадная |
Экономная |
Сильная сторона |
Поиск по логам |
Агрегация метрик |
так как мониторинги очень полезны в реалтайме и может быть полезен поиск по логам я выберу Elasticsearch.
Итоговая схема
Мы выбрали технологии и можем нарисовать итоговую схему

Также если на интервью остается время, то могут попросить дополнить схему примерами API и запросов. К этому стоит быть готовыми. И желательно чтобы время на это осталось :) Но описывайте запросы и API только когда все готово, либо вас об этом попросили.
Расчет железа
На самом деле это немного абстрактный пункт. Если данных много , то расчет можно сделать относительно точным. Но если данных мало, то все зависит от вашей фантазии.
Пусть 1 сервер backend с 8ГБ ОЗУ в среднем держит 25000RPS. А 1 сервер backend с 16ГБ ОЗУ в среднем держит 45000RPS.
Получаем что для 30000 RPS нам нужно минимум два сервера 8ГБ, либо один на 16ГБ. Но нужно учитывать что одна машина может выйти из строя в пиковую нагрузку и системе может поплохеть. Я бы выбрал два сервера по 16ГБ чтобы сэкономить на железе и дальше смотрел по нагрузке и по фичам.
Итоговая калькуляция:
Backend 2 сервера с 16ГБ ОЗУ на каждом
Балансировщик: 2 сервера
MC: 2 сервера
Мониторинги: 3 ноды Elasticsearch.
Финал
На архитектурном интервью не ожидайте что вам все расскажут. Именно вы лидируете на нем и именно от вас ожидается инициатива.
Не тратьте много времени на объяснение. Рассказывайте только то что спросят. На интервью, в большинстве компаний, дается 60 минут, нужно успеть закончить схему до конца и ответить на все вопросы.
Обязательно задавайте вопросы на старте, какая бы классная и рабочая не была схема, если вы не расставили рамки на старте, интервью будет считаться не пройденным.
Домашняя работа :)
Оставьте в комментариях вопросы которые вы бы задали на месте соискателя?
А как бы вы отвечали на месте интервьюера?
И как бы вы реализовали схему работы брокера сообщений?
Опишите в виде блок схемы как вы видите работу части backend.