Если вы задаётесь вопросом, что лучше — Apache Kafka или RabbitMQ, или думаете, что RabbitMQ надёжнее Apache Kafka, хочу сразу остановить вас. Эта статья рассматривает обе системы с более широкой точки зрения и сосредоточится на функциональности, которую они предоставляют. Это поможет вам принять обоснованное решение о том, какую систему использовать и в каких случаях.
В сети можно встретить статьи, которые ставят Apache Kafka выше RabbitMQ, и наоборот — хвалят RabbitMQ за счёт Kafka. Многие из нас признают, что иногда следуют за хайпом и выбирают популярное решение. Важно понимать, что выбор между RabbitMQ и Apache Kafka зависит от требований конкретного проекта, а корректное сравнение возможно только если вы использовали обе системы с правильной настройкой в подходящем сценарии.
Компания 84codes и я давно работаем в индустрии, предоставляя облачные решения как для RabbitMQ через сервис CloudAMQP, так и для Apache Kafka через CloudKarafka (сервис устарел 27 января 2025 года). Я видела множество кейсов и различных конфигураций приложений у пользователей обоих сервисов, поэтому могу с уверенностью отвечать на вопросы о применении RabbitMQ и Apache Kafka, опираясь на свой опыт.
В этой статье моя цель — поделиться инсайтами, основанными на многочисленных разговорах с разработчиками за эти годы, и попытаться передать их мысли о том, почему они выбирали ту или иную систему обмена сообщениями.
Термины, используемые в этой статье:
Очередь сообщений — в RabbitMQ это обычная очередь, а в Kafka аналогичная структура называется логом. Чтобы упростить изложение, я буду использовать термин «очередь» вместо постоянного переключения на «лог».
Сообщение в Kafka часто называют записью (record), но для простоты здесь я буду говорить просто «сообщение».
Когда я пишу о топике в Kafka, можно воспринимать его как категорию внутри очереди сообщений. Топики Kafka делятся на партиции, которые содержат записи в неизменяемой последовательности.
Обе системы передают сообщения между производителями и потребителями через очереди или топики. Сообщение может содержать любую информацию — например, данные о событии на сайте или простое текстовое сообщение, которое запускает действие в другом приложении.
Такие системы идеально подходят для соединения различных компонентов, построения микросервисов, потоковой передачи данных в реальном времени или передачи задач удалённым исполнителям.
И RabbitMQ, и Apache Kafka играют важную роль в крупных компаниях по всему миру, подтверждая необходимость сложных и надёжных решений для обмена сообщениями и потоковой передачи данных. По данным Confluent, более трети компаний из списка Fortune 500 используют Apache Kafka. Крупные компании из разных отраслей также полагаются на RabbitMQ, включая Zalando, Adidas, WeWork, Wunderlist и Bloomberg.


Главный вопрос: когда использовать Kafka, а когда — RabbitMQ?
Некоторое время назад я отвечала на Stackoverflow на вопрос: «Есть ли причины использовать RabbitMQ вместо Kafka?» Ответ был всего в несколько строк, но оказался полезным для многих.
Я постараюсь разложить его на части и объяснить каждую. В частности, я написала: «RabbitMQ — это надёжный, зрелый, универсальный брокер сообщений, поддерживающий несколько протоколов, таких как AMQP, MQTT, STOMP и другие. RabbitMQ способен обрабатывать высокие нагрузки. Его часто используют для фоновых задач или в качестве брокера сообщений между микросервисами. Kafka — это шина сообщений, оптимизированная для потоков данных с высокой скоростью поступления и возможности повторной обработки. Kafka можно рассматривать как долговременный брокер сообщений, где приложения могут обрабатывать и повторно обрабатывать потоковые данные на диске».
Что касается термина «зрелый», то RabbitMQ просто дольше находится на рынке, чем Kafka (2007 против 2011 года). Оба брокера — RabbitMQ и Kafka — считаются зрелыми, надёжными и масштабируемыми системами обмена сообщениями.
Стоит отметить, что ответ на Stackoverflow был написан несколько лет назад, и с тех пор RabbitMQ сильно изменился. С выпуском версии 3.9 и введением Stream Queues он сделал значительный шаг к превращению в платформу потоковой передачи сообщений.
В результате его возможности теперь выходят за рамки простой очереди сообщений и охватывают сценарии, которые раньше в основном покрывались Kafka.
Прежде чем двигаться дальше, давайте кратко разберём, что такое RabbitMQ streams, так как этот концепт будет часто встречаться в последующих разделах.
Введение в RabbitMQ Streams
Ранее мы упоминали, как сообщения перемещаются от производителя к очереди, а затем к потребителю. RabbitMQ выделяется среди брокеров разнообразием типов очередей, каждая из которых создана для определённых задач обмена сообщениями. Традиционные типы очередей в RabbitMQ с момента их появления не поддерживали семантику недеструктивного потребления — сообщения удалялись из очереди после того, как потребитель их получил и подтвердил.
Такая особенность очередей делала их неподходящими для сценариев, где требуется долгосрочное хранение данных или повторное воспроизведение сообщений. Но всё изменилось с выпуском RabbitMQ v3.9…
Stream Queues (потоковые очереди) были введены в RabbitMQ v3.9. Они постоянные и реплицируемые, и, как и традиционные очереди, буферизуют сообщения от производителей для чтения потребителями. Однако потоки отличаются от классических очередей в двух аспектах:
Способ записи сообщений производителями
Способ чтения сообщений потребителями
В основе Stream Queues лежит append‑only лог, который неизменяем. Это значит, что сообщения, записанные в поток, нельзя удалить, их можно только читать. Чтобы прочитать сообщения из потока в RabbitMQ, один или несколько потребителей подписываются на него и могут читать одно и то же сообщение сколько угодно раз.
Эта функциональность повторяет поведение Kafka, делая потоковые очереди RabbitMQ привлекательным вариантом для тех, кто ищет Kafka‑подобные возможности в среде RabbitMQ.
А теперь давайте вернемся к основной теме разговора: чем RabbitMQ (с Streams) отличается от Kafka?
Обработка сообщений (воспроизведение сообщений)
Хотя традиционные очереди RabbitMQ (Classic и Quorum) хранят сообщения только до момента, пока их не получит подключённое приложение, RabbitMQ Streams кардинально изменил это поведение.
Что касается повторного воспроизведения сообщений, RabbitMQ Streams и Apache Kafka работают схожим образом. В обоих случаях данные сохраняются до окончания заданного периода хранения — либо по времени, либо по объёму. Сообщение остаётся в очереди, пока не превышен лимит хранения/объёма, то есть оно не удаляется после получения и может быть воспроизведено или прочитано несколько раз, что настраивается.
Важно использовать повторное воспроизведение сообщений корректно. Многократное воспроизведение события, которое должно произойти лишь один раз (например, сохранение заказа клиента), обычно не подходит. Повторное воспроизведение полезно, если в потребителе была ошибка, и нужно развернуть новую версию приложения с повторной обработкой некоторых или всех сообщений.
Протоколы
Я упоминала, что «RabbitMQ поддерживает несколько стандартных протоколов, таких как AMQP, MQTT, STOMP и др.», при этом нативно реализован AMQP 0.9.1. Нативная поддержка AMQP 1.0 появится в RabbitMQ v4.0. В настоящее время AMQP 1.0 поддерживается через плагин, но не нативно.
Kafka использует собственный протокол поверх TCP/IP для взаимодействия между приложениями и кластером. Kafka нельзя просто заменить, так как это единственное ПО, реализующее этот протокол.
Поддержка RabbitMQ разных протоколов делает его гибким для использования в различных сценариях.
Маршрутизация
Далее речь идёт о маршрутизации. Я писала: «Kafka имеет очень простую схему маршрутизации. RabbitMQ предлагает больше возможностей, если нужно гибко направлять сообщения к потребителям».
Одним из ключевых преимуществ RabbitMQ является гибкая маршрутизация сообщений. Прямое или регулярное выражение для маршрутизации позволяет доставлять сообщения в конкретные очереди без дополнительного кода. RabbitMQ поддерживает четыре типа маршрутизации: direct, topic, fanout и header exchanges.
Direct exchanges направляют сообщения во все очереди с точным совпадением ключа маршрутизации.
Fanout exchange рассылает сообщение всем очередям, привязанным к обменнику.
Topic exchanges похожи на direct, используя ключ маршрутизации, но позволяют использовать wildcard‑совпадения вместе с точными.

Kafka не поддерживает маршрутизацию: топики Kafka делятся на партиции, каждая из которых содержит сообщения в неизменяемой последовательности. В качестве аналога маршрутизации в RabbitMQ можно использовать группы потребителей и постоянные топики: все сообщения отправляются в один топик, а группы потребителей читают их с разных смещений (offsets).
Offset — это уникальный идентификатор каждого сообщения, показывающий порядок его следования в логе сообщений.
Динамическую маршрутизацию можно реализовать самостоятельно с помощью Kafka Streams, где события направляются в топики динамически, но это не встроенная функция.
Приоритет сообщений
RabbitMQ поддерживает очереди с приоритетом, что означает возможность задавать диапазон приоритетов для очереди. При публикации каждого сообщения можно задать его приоритет, и сообщение помещается в соответствующую очередь по приоритету.
Пример: выполняются ежедневные резервные копии базы данных. Тысячи событий добавляются в RabbitMQ без определённого порядка. Клиент также может инициировать резервное копирование по требованию; такое событие добавляется в очередь с более высоким приоритетом.
В Apache Kafka сообщения не могут иметь приоритет и доставляются в порядке поступления, независимо от загруженности потребителей.
Подтверждения (Acknowledgment. Commit или Confirm)
«Подтверждение» — это сигнал между процессами, который обозначает получение или обработку отправленного сообщения.
И Kafka, и RabbitMQ поддерживают подтверждения от производителя (в RabbitMQ — publisher confirms), чтобы убедиться, что сообщение успешно доставлено брокеру.
Когда узел отправляет сообщение потребителю, он должен решить, считать ли сообщение обработанным. Клиент может подтверждать получение сообщения сразу или после полной обработки.
RabbitMQ может считать сообщение доставленным сразу после отправки или ждать ручного подтверждения от потребителя.
Kafka отслеживает смещения (offset) каждого сообщения в партиции. Committed offset — это последнее сохранённое смещение. Если процесс падает и перезапускается, восстановление происходит с этого смещения. Потребитель Kafka может автоматически фиксировать смещения периодически или контролировать их вручную.
В разных версиях Kafka механизм отслеживания потребленных сообщений отличается: в ранних версиях это делал потребитель.
RabbitMQ также поддерживает nack (отрицательное подтверждение), если сообщение не удалось обработать. Оно возвращается в очередь как новое сообщение — полезно при временных сбоях на стороне потребителя.
Работа с очередями
Традиционные очереди RabbitMQ работают быстрее всего, когда они пусты.
Однако и RabbitMQ Streams, и Kafka разработаны для хранения и передачи больших объёмов сообщений.
Кроме того, классические очереди RabbitMQ могут работать в lazy mode. В этом режиме сообщения автоматически сохраняются на диск, что минимизирует использование RAM, но увеличивает время обработки. В версиях RabbitMQ < 3.12 режим lazy нужно включать вручную, а в версиях ≥ 3.12 это поведение по умолчанию.
На практике lazy‑очереди создают более стабильный кластер с предсказуемой производительностью. Если вы отправляете много сообщений одновременно (например, обрабатываете пакетные задачи) или ожидаете, что потребители не смогут постоянно обрабатывать сообщения с той же скоростью, что и производители, рекомендуется включать lazy‑очереди.
Масштабирование
Масштабирование — это процесс увеличения или уменьшения мощности системы. RabbitMQ и Kafka масштабируются по‑разному: можно регулировать количество потребителей, увеличивать ресурсы брокера или добавлять новые узлы в систему.
Масштабирование потребителей
Если вы публикуете сообщения быстрее, чем RabbitMQ успевает их обрабатывать, очередь начнёт расти и может достигнуть миллионов сообщений, что приведёт к исчерпанию памяти брокера. В этом случае можно увеличить количество потребителей, обрабатывающих сообщения. Каждая очередь в RabbitMQ может иметь несколько потребителей, которые «конкурируют» за получение сообщений. Обработка сообщений распределяется между всеми активными потребителями, поэтому масштабирование вверх или вниз в RabbitMQ сводится к простому добавлению или удалению потребителей.
В Kafka распределение потребителей реализуется через партиции топика: каждый потребитель в группе отвечает за одну или несколько партиций. Механизм партиций позволяет направлять различные наборы сообщений в разные партиции по бизнес‑ключу, например, по ID пользователя или по географическому положению.
Масштабирование брокера
В ответе на Stackoverflow я писала: «Kafka изначально создавалась с учётом горизонтального масштабирования (добавления машин), тогда как RabbitMQ в основном ориентирован на вертикальное масштабирование (добавление ресурсов)». Эта часть ответа касается машин, на которых работают Kafka и RabbitMQ.
Для RabbitMQ горизонтальное масштабирование не всегда повышает производительность. Оптимальные показатели достигаются при вертикальном масштабировании. Горизонтальное масштабирование возможно, но требует настройки кластеризации узлов, что может замедлить работу системы.
В Kafka масштабирование осуществляется добавлением новых узлов в кластер или увеличением числа партиций в топиках. Это иногда проще, чем добавлять CPU или память в существующую машину, как это требуется в RabbitMQ.
Многие источники, включая Confluent, отмечают высокую масштабируемость Kafka. Действительно, Kafka может масштабироваться дальше RabbitMQ, так как ресурсы физической машины всегда ограничены. Однако важно помнить, зачем нужен брокер: обычно объём сообщений, с которым вы работаете, обе системы способны обработать без проблем, и большинству проектов не приходится сталкиваться с ограничениями RabbitMQ по объёму.
Сжатие логов (Log Compaction)
Особенность, присущая Apache Kafka, которой нет в RabbitMQ — сжатие логов. Сжатие логов гарантирует, что Kafka сохраняет только последнее известное значение для каждого ключа сообщения в партиции топика. Kafka хранит последнюю версию сообщения и удаляет старые версии с тем же ключом.
Сжатие логов можно рассматривать как способ использовать Kafka в роли базы данных. Если установить период хранения «навсегда» или включить сжатие логов для топика, данные будут храниться постоянно.
Пример использования: при отображении текущего состояния одного кластера из тысяч. Вместо того чтобы постоянно хранить все изменения состояния, сохраняется только актуальный статус. Последняя информация доступна мгновенно, например, сколько сообщений находится в очереди. Сжатые логи полезны для восстановления системы после сбоев.
Мониторинг
RabbitMQ имеет удобный веб‑интерфейс для мониторинга и управления сервером. Через браузер можно управлять очередями, соединениями, каналами, обменниками, пользователями и правами доступа, а также отслеживать скорость сообщений и вручную отправлять/принимать сообщения.
Для Kafka существует множество open‑source инструментов для мониторинга, а также коммерческие решения, предоставляющие функции администрирования и мониторинга. Информацию о различных инструментах мониторинга Kafka можно найти в соответствующих источниках.
PUSH или PULL
В RabbitMQ сообщения пушатся к потребителю. Важно настроить prefetch limit (лимит предварительной загрузки), чтобы не перегружать потребителя, если сообщения поступают в очередь быстрее, чем потребители могут их обрабатывать. Потребители также могут тянуть сообщения из RabbitMQ, но это не рекомендуется.
В Kafka используется модель pull, как уже упоминалось: потребители запрашивают партии сообщений с заданного смещения (offset).
Лицензия
RabbitMQ изначально был создан компанией Rabbit Technologies Ltd. В 2023 году проект стал частью Broadcom. Исходный код RabbitMQ распространяется под Mozilla Public License, и лицензия с момента выпуска не менялась (по состоянию на сентябрь 2024).
Kafka был создан в LinkedIn и в 2011 году передан в Apache Foundation как open‑source проект под лицензией Apache 2.0. Некоторые компоненты, часто используемые с Kafka (например, Rest Proxy, Schema Registry и KSQL), покрываются лицензией Confluent Community License. Она позволяет свободно скачивать, изменять и распространять код, но не разрешает предоставлять ПО как SaaS‑сервис.
Обе лицензии являются бесплатными и открытыми. Если Kafka в будущем изменит лицензию на более строгую, RabbitMQ будет иметь преимущество, так как его легко заменить другим AMQP‑брокером, чего нельзя сказать о Kafka.
Сложность
Лично я считаю, что начать работать с RabbitMQ проще, и в целом с ним удобно работать. Как сказал один из наших клиентов:
«Мы не тратили время на изучение RabbitMQ, и он работал годами. Это действительно сократило множество операционных расходов во время стремительного роста DoorDash.» ‑ Zhaobang Liu, DoorDash
Архитектура Kafka, на мой взгляд, более сложная: с самого начала нужно разбираться в топиках, партициях, смещениях сообщений, понимать работу групп потребителей и управление offset.
Для операторов Kafka (сейчас устаревшего) и RabbitMQ управление сбоями в Kafka кажется более трудоёмким и запутанным. Процесс восстановления или исправления обычно занимает больше времени.
Экосистема Kafka
Kafka — это не просто брокер, а платформа потоковой передачи данных, и существует множество инструментов, которые легко интегрируются с Kafka вне основной дистрибуции. Экосистема Kafka включает:
Kafka Core
Kafka Streams
Kafka Connect
Kafka REST Proxy
Schema Registry
Большинство дополнительных инструментов экосистемы предоставляются Confluent и не входят в Apache Kafka.
Преимущество всех этих инструментов в том, что можно настроить большую систему ещё до написания первой строки кода.
Kafka Connect позволяет интегрировать другие системы с Kafka: можно подключить источник данных, чтобы потреблять данные в Kafka или отправлять данные из топика в другую систему для обработки или хранения. Существует множество готовых коннекторов, поэтому начать работу легко.
Kafka REST Proxy позволяет получать метаданные ��ластера, а также публиковать и потреблять сообщения через простой REST API. Эту функцию можно легко включить через панель управления кластером.
Типичные сценарии использования — RabbitMQ vs Apache Kafka
До этого момента мы рассматривали, что каждая система умеет или не умеет делать. Ниже приведены четыре основных сценария, которые помогают определить, какую систему использовать. Эти кейсы основаны на моём опыте и опыте наших клиентов. Конечно, встречались случаи, когда клиент строил систему на неправильном брокере, и стоило использовать другой.
Сценарии для RabbitMQ
В целом, если нужен простой/традиционный брокер сообщений с паттерном pub‑sub, очевидный выбор — RabbitMQ. Он, скорее всего, будет масштабироваться больше, чем вам когда‑либо понадобится. Я бы выбрал RabbitMQ, если требования сводятся к обмену сообщениями между системами через каналы/очереди, с возможностью потоковой передачи как опцией. Также RabbitMQ считается более дружелюбным для начинающих.
С появлением поддержки Streams RabbitMQ теперь можно использовать и в сценариях высокопроизводительной потоковой обработки сообщений, с возможностью многократного чтения сообщений.
Сценарии для Apache Kafka
Если нужна система, созданная для хранения, чтения (и повторного чтения) потоковых данных и их анализа, стоит выбирать Apache Kafka. Это идеальный вариант для аудируемых систем или тех, где сообщения нужно хранить постоянно. Также имеет смысл изучить экосистему Apache Kafka, если требования к системе уже определены.
Долгоживущие задачи
Оптимальный выбор: RabbitMQ
Очереди сообщений позволяют асинхронную обработку, то есть можно положить сообщение в очередь, не обрабатывая его сразу.
Пример: в нашем руководстве для начинающих по RabbitMQ описан классический сценарий, где веб‑приложение позволяет пользователям загружать данные на сайт. Сайт обрабатывает информацию, генерирует PDF и отправляет его пользователю по электронной почте. Выполнение этих задач занимает несколько секунд — именно поэтому здесь используется очередь сообщений.
Многие клиенты используют очереди RabbitMQ как шину событий, чтобы веб‑серверы могли быстро отвечать на запросы, не выполняя ресурсоёмкие задачи мгновенно.
Пример: Softonic применяет RabbitMQ в архитектуре микросервисов на основе событий, обслуживая 100 миллионов пользователей в месяц.
Посредник в архитектуре микросервисов
Оптимальный выбор: RabbitMQ
Многие клиенты используют RabbitMQ в микросервисной архитектуре для обмена сообщениями между приложениями и предотвращения узких мест.
Пример: Parkster (цифровой сервис парковки) разбивает систему на несколько микросервисов, используя RabbitMQ для обмена сообщениями.
MapQuest, крупный сервис навигации с 23,1 миллиона уникальных мобильных пользователей в месяц, публикует обновления карт на персональные устройства и корпоративное ПО. Здесь топики RabbitMQ распределены по множеству очередей, позволяя десяткам миллионов пользователей получать точную корпоративную информацию о картах.
Анализ данных: отслеживание, сбор, логирование, безопасность
Оптимальный выбор: Apache Kafka (возможен вариант через RabbitMQ Streams)
Во всех этих сценариях требуется сбор, хранение и обработка больших объёмов данных. Если компания хочет получать аналитическую информацию, реализовывать поиск, аудит или анализ огромного массива данных — оправдано использование Kafka.
По словам создателей Kafka, исходный кейс — отслеживание активности на сайте: просмотры страниц, поисковые запросы, загрузки и другие действия пользователей. Такой трекинг требует очень высокой пропускной способности, так как сообщения генерируются для каждого действия и каждого пользователя. Все эти данные можно хранить в Kafka и обрабатывать по мере необходимости.
Производителям данных нужно лишь отправлять данные в одно место, а множество backend‑сервисов могут их потреблять. Большинство аналитических, поисковых и хранилищных систем имеют интеграции с Kafka.
Kafka также подходит для потоковой передачи больших объёмов данных в системы хранения — в наши дни место на дисках не является серьёзной проблемой.
Обработка данных в реальном времени
Оптимальный выбор: Apache Kafka (возможен вариант через RabbitMQ Streams)
Kafka выступает как распределённая система с высокой пропускной способностью: сервисы‑источники передают потоки данных в целевые сервисы, которые потребляют их в реальном времени.
Kafka можно использовать в системах с многими производителями и небольшим числом потребителей; пример — финансовые IT‑системы для мониторинга биржевых данных.
Сервисы потоковой передачи, от Spotify до Rabobank, публикуют данные в реальном времени через Kafka. Возможность обработки больших потоков данных в реальном времени делает приложения мощнее и эффективнее.
CloudAMQP использует RabbitMQ для автоматизации настройки серверов, но мы применяли Kafka для публикации логов и метрик.
Характеристика |
RabbitMQ |
Apache Kafka |
Что это? |
Надёжный, зрелый, универсальный брокер сообщений |
Шина сообщений, оптимизированная для потоков данных с высокой нагрузкой и возможности повторного воспроизведения |
Основное назначение |
Очередь сообщений для коммуникации и интеграции внутри и между приложениями. Подходит для долгоживущих задач и надёжных фоновых процессов. Также может использоваться для потоковой передачи сообщений |
Фреймворк для хранения, чтения (и повторного чтения) потоковых данных и их анализа |
Лицензия |
Open Source: Mozilla Public License |
Open Source: Apache License 2.0 |
Язык разработки |
Erlang |
Scala (JVM) |
Первая версия |
2007 |
2011 |
Сохранение сообщений |
Сохраняет сообщения в традиционных очередях до подтверждения получения. В Streams сообщения сохраняются столько, сколько нужно, с возможностью удаления по истечении периода хранения |
Сохраняет сообщения с возможностью удаления по истечении периода хранения |
Повторное воспроизведение (replay) |
Да, через RabbitMQ Streams |
Да |
Маршрутизация |
Поддерживает гибкую маршрутизацию, позволяя направлять сообщения к нужному потребителю |
Гибкая маршрутизация отсутствует, требуется создавать отдельные топики |
Приоритет сообщений |
Поддерживается |
Не поддерживается |
Мониторинг |
Доступен через встроенный веб‑интерфейс |
Доступен через сторонние инструменты, например Confluent |
Поддержка языков |
Поддерживается большинство языков |
Поддерживается большинство языков |
Безопасная аутентификация |
Стандартная аутентификация и OAuth2 |
Kerberos, OAuth2 и стандартная аутентификация |
Если выбор между Kafka и RabbitMQ для вас уже не про «что моднее», а про общую архитектуру хранения и потоков данных, имеет смысл смотреть на экосистему NoSQL целиком. На курсе OTUS «NoSQL» вы на практике разбираете MongoDB, Cassandra, ClickHouse, Redis, Neo4j, Kafka, RabbitMQ и другие системы и учитесь осознанно подбирать их под модель данных, нагрузку и требования к производительности.
Чтобы узнать больше о формате обучения и познакомиться с преподавателями, приходите на бесплатные демо-уроки:
1 декабря: «Временные ряды и наблюдаемость: как устроены Time-Series базы данных». Записаться
10 декабря: «Qdrant и векторные базы данных: поиск по смыслу, а не по словам». Записаться
17 декабря: «Кластеризация MongoDB: репликация и шардирование». Записаться