В чем разница между Apache Kafka и RabbitMQ?

«В чем разница между Apache Kafka и RabbitMQ?» — вопрос из категории Архитектура, который задают на 10% собеседований QA Тестировщик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Apache Kafka и RabbitMQ — это системы обмена сообщениями, но с разными архитектурными подходами и use cases.

Архитектурные различия:

Характеристика RabbitMQ Apache Kafka
Модель Message Queue / Exchange Distributed Log / Commit Log
Хранение Удаление после подтверждения Хранение по времени/размеру (дни/недели)
Протокол AMQP, MQTT, STOMP Собственный протокол поверх TCP
Гарантии At-most-once, At-least-once Exactly-once семантика (с транзакциями)
Масштабирование Вертикальное + кластеризация Горизонтальное (партиционирование)
Пропускная способность ~50K сообщ/сек на ноде ~1M+ сообщ/сек на кластере

RabbitMQ — классический брокер сообщений:

  • Идеален для: задач с гарантированной доставкой, RPC, сложной маршрутизации
  • Архитектура: Producer → Exchange → Queue → Consumer
  • Пример использования (распределение задач):
    
    # Producer
    import pika
    connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
    channel = connection.channel()
    channel.queue_declare(queue='task_queue', durable=True)

Отправка задачи на обработку

channel.basic_publish( exchange='', routing_key='task_queue', body='Обработать документ #123', properties=pika.BasicProperties(delivery_mode=2) # Сохранить на диск )

Consumer

def callback(ch, method, properties, body): print(f"Получена задача: {body}")

Обработка задачи...

ch.basic_ack(delivery_tag=method.delivery_tag)  # Подтверждение обработки

channel.basic_consume(queue='task_queue', on_message_callback=callback) channel.start_consuming()


**Apache Kafka — распределенная streaming-платформа:**
* **Идеален для:** потоковой обработки данных, event sourcing, аналитики в реальном времени
* **Архитектура:** Producer → Topic (с партициями) → Consumer Groups
* **Пример использования (трекинг событий):**
```java
// Producer
Properties props = new Properties();
props.put("bootstrap.servers", "kafka1:9092,kafka2:9092");
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("acks", "all");  // Гарантия записи во все реплики
props.put("enable.idempotence", "true");  // Идемпотентность

Producer<String, String> producer = new KafkaProducer<>(props);

// Отправка события пользовательского действия
ProducerRecord<String, String> record = new ProducerRecord<>(
    "user-events",           // Топик
    "user-123",              // Ключ (гарантирует порядок в партиции)
    "{"action":"purchase","amount":99.99}"  // Значение
);

producer.send(record, (metadata, exception) -> {
    if (exception == null) {
        System.out.printf("Отправлено в партицию %d, offset %d%n",
            metadata.partition(), metadata.offset());
    }
});

producer.close();

Когда выбирать RabbitMQ:

  1. Требуется сложная маршрутизация сообщений (direct, topic, fanout exchanges)
  2. Нужны гарантии доставки с подтверждением (acknowledgments)
  3. Задачи RPC (request-reply pattern)
  4. Очереди задач с балансировкой нагрузки между workers

Когда выбирать Kafka:

  1. Обработка потоков данных в реальном времени
  2. Хранение истории событий для повторной обработки (replay)
  3. Высокая пропускная способность (миллионы сообщений в секунду)
  4. Интеграция микросервисов через event-driven архитектуру
  5. Аналитика и мониторинг (логи, метрики, трекинг)

Гибридный подход: В некоторых системах используют оба решения — RabbitMQ для обработки задач, Kafka для потоковой аналитики и репликации данных.