Kafka vs RabbitMQ vs Pulsar: Comparatif Objectif
Choisir entre Apache Kafka, RabbitMQ et Apache Pulsar est une decision architecturale majeure. Chaque technologie a ses forces et ses cas d'usage optimaux. Ce guide fournit une comparaison objective basee sur mon experience de terrain, avec des criteres concrets pour vous aider a faire le bon choix.
Vue d'Ensemble des Technologies
Apache Kafka
Origine : Developpe par LinkedIn (2011), maintenant projet Apache Philosophie : Log distribue haute performance pour le streaming
┌─────────────────────────────────────────────────────────────────┐
│ APACHE KAFKA │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Architecture : Log distribue partitionne │
│ │
│ Producer ──▶ [Topic/Partition] ──▶ Consumer Group │
│ │ msg1 │ msg2 │ msg3 │ msg4 │ ... │
│ └─────────────────────────────┘ │
│ Append-only Log │
│ │
│ Points forts : │
│ - Throughput extreme (millions msg/sec) │
│ - Durabilite (persistance disque) │
│ - Replay des messages │
│ - Ecosysteme riche (Connect, Streams, ksqlDB) │
│ │
└─────────────────────────────────────────────────────────────────┘
RabbitMQ
Origine : Developpe par Pivotal/VMware (2007), protocole AMQP Philosophie : Message broker traditionnel flexible
┌─────────────────────────────────────────────────────────────────┐
│ RABBITMQ │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Architecture : Exchange + Queues avec routing │
│ │
│ Producer ──▶ Exchange ──routing──▶ Queue ──▶ Consumer │
│ │ direct │ topic │ fanout │ headers │ │
│ └─────────────────────────────────────┘ │
│ Flexible Routing │
│ │
│ Points forts : │
│ - Routing flexible (exchanges) │
│ - Protocoles multiples (AMQP, STOMP, MQTT) │
│ - Simple a deployer et operer │
│ - Garanties de livraison riches │
│ │
└─────────────────────────────────────────────────────────────────┘
Apache Pulsar
Origine : Developpe par Yahoo (2016), maintenant projet Apache Philosophie : Unification messaging + streaming avec multi-tenancy
┌─────────────────────────────────────────────────────────────────┐
│ APACHE PULSAR │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Architecture : Separation compute (broker) / storage (BK) │
│ │
│ Producer ──▶ Broker ──▶ BookKeeper ──▶ Consumer │
│ │ Stateless │ │ Distributed Storage │ │
│ └───────────┘ └────────────────────┘ │
│ Decoupled Architecture │
│ │
│ Points forts : │
│ - Multi-tenancy natif │
│ - Geo-replication native │
│ - Queuing + Streaming unifie │
│ - Tiered storage (offload vers S3/GCS) │
│ │
└─────────────────────────────────────────────────────────────────┘
Comparaison Detaillee
Architecture
| Critere | Kafka | RabbitMQ | Pulsar |
|---|---|---|---|
| Modele | Log distribue | Message broker | Log + Queue unifie |
| Storage | Local (broker) | Memoire + disque | BookKeeper (separe) |
| Coordination | ZooKeeper/KRaft | Erlang clustering | ZooKeeper |
| Stateless brokers | Non | Partiellement | Oui |
| Partitioning | Natif | Via plugins | Natif |
Detail Architecture :
┌─────────────────────────────────────────────────────────────────┐
│ ARCHITECTURE COMPAREE │
├─────────────────────────────────────────────────────────────────┤
│ │
│ KAFKA │
│ ┌────────┐ ┌────────┐ ┌────────┐ │
│ │Broker 1│ │Broker 2│ │Broker 3│ ◀── Data + Compute │
│ │+ Data │ │+ Data │ │+ Data │ │
│ └────────┘ └────────┘ └────────┘ │
│ └──────────┴──────────┘ │
│ ZooKeeper / KRaft │
│ │
│ RABBITMQ │
│ ┌────────┐ ┌────────┐ ┌────────┐ │
│ │ Node 1 │──│ Node 2 │──│ Node 3 │ ◀── Erlang Cluster │
│ │Queues │ │Queues │ │Queues │ │
│ └────────┘ └────────┘ └────────┘ │
│ │
│ PULSAR │
│ ┌────────┐ ┌────────┐ ┌────────┐ │
│ │Broker 1│ │Broker 2│ │Broker 3│ ◀── Stateless Compute │
│ └────────┘ └────────┘ └────────┘ │
│ │ │ │ │
│ ┌────────┐ ┌────────┐ ┌────────┐ │
│ │ Bookie │ │ Bookie │ │ Bookie │ ◀── Storage Layer │
│ └────────┘ └────────┘ └────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
Performance
| Metrique | Kafka | RabbitMQ | Pulsar |
|---|---|---|---|
| Throughput max | 1M+ msg/sec | 50K msg/sec | 500K+ msg/sec |
| Latence P99 | 5-15ms | 1-5ms | 5-20ms |
| Latence min | ~2ms | <1ms | ~5ms |
| Messages/partition | Illimite | N/A | Illimite |
Benchmarks typiques :
┌─────────────────────────────────────────────────────────────────┐
│ BENCHMARK PERFORMANCE │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Throughput (messages/sec) - 3 nodes, 1KB messages │
│ │
│ Kafka ████████████████████████████████████████ 1,200,000 │
│ Pulsar █████████████████████████████ 650,000 │
│ RabbitMQ ████████ 45,000 │
│ │
│ Latence P99 (ms) - 100K msg/sec sustained │
│ │
│ RabbitMQ ██ 2ms │
│ Kafka █████ 8ms │
│ Pulsar ████████ 12ms │
│ │
│ Note: Resultats dependent fortement de la configuration │
│ et du hardware. A tester dans votre contexte. │
│ │
└─────────────────────────────────────────────────────────────────┘
Fonctionnalites
| Fonctionnalite | Kafka | RabbitMQ | Pulsar |
|---|---|---|---|
| Message ordering | Par partition | Par queue | Par partition |
| Message replay | Oui (natif) | Non (par defaut) | Oui (natif) |
| Routing flexible | Limite | Excellent | Moyen |
| Dead Letter Queue | Manuel | Natif | Natif |
| Priority queues | Non | Oui | Non |
| Delayed messages | Non natif | Oui (plugin) | Oui (natif) |
| Transactions | Oui | Oui | Oui |
| Exactly-once | Oui | Via confirms | Oui |
| Schema Registry | Oui (Confluent) | Non | Oui (natif) |
| Multi-tenancy | Limite | Vhosts | Natif |
| Geo-replication | MirrorMaker | Federation | Natif |
| Tiered storage | Non natif | Non | Oui |
Operations et Maintenance
| Aspect | Kafka | RabbitMQ | Pulsar |
|---|---|---|---|
| Complexite deploiement | Moyenne | Faible | Elevee |
| Courbe d'apprentissage | Moyenne | Faible | Elevee |
| Scaling horizontal | Bon | Limite | Excellent |
| Cloud managed | Confluent, MSK, etc. | CloudAMQP, etc. | StreamNative |
| Communaute | Tres large | Large | Croissante |
| Documentation | Excellente | Excellente | Bonne |
┌─────────────────────────────────────────────────────────────────┐
│ COMPLEXITE OPERATIONNELLE │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Installation & Setup │
│ RabbitMQ ██████ Simple │
│ Kafka ████████████ Moyen │
│ Pulsar ████████████████████ Complexe │
│ │
│ Day-2 Operations │
│ RabbitMQ ████████ Simple │
│ Kafka ████████████ Moyen │
│ Pulsar ██████████████ Moyen-Complexe │
│ │
│ Scaling │
│ Pulsar ██████ Facile (stateless) │
│ Kafka ████████████ Partition rebalance │
│ RabbitMQ ████████████████ Queue mirroring │
│ │
└─────────────────────────────────────────────────────────────────┘
Ecosysteme et Integration
| Integration | Kafka | RabbitMQ | Pulsar |
|---|---|---|---|
| Connecteurs | 200+ (Kafka Connect) | 30+ | 50+ (IO Connectors) |
| Stream Processing | Kafka Streams, ksqlDB | Non | Pulsar Functions |
| Spring Integration | Excellent | Excellent | Bon |
| Cloud Native | Strimzi (K8s) | RabbitMQ Operator | Pulsar Helm |
| Langages clients | Tous | Tous | Principaux |
Cas d'Usage Optimaux
Quand Choisir Kafka
┌─────────────────────────────────────────────────────────────────┐
│ KAFKA - CAS D'USAGE IDEAUX │
├─────────────────────────────────────────────────────────────────┤
│ │
│ [x] Event Streaming a haut volume │
│ - Logs aggregation │
│ - Clickstream analytics │
│ - IoT data ingestion │
│ │
│ [x] Event Sourcing et CQRS │
│ - Systemes financiers │
│ - Audit trails │
│ - Replay capability critique │
│ │
│ [x] Data Pipelines et ETL │
│ - CDC (Change Data Capture) │
│ - Data lake ingestion │
│ - Real-time analytics │
│ │
│ [x] Microservices Event-Driven │
│ - Decoupling services │
│ - Event backbone │
│ - Saga patterns │
│ │
│ [ ] PAS ideal pour: │
│ - RPC/Request-Reply simple │
│ - Routing complexe │
│ - Priority queues │
│ - Messages ephemeres │
│ │
└─────────────────────────────────────────────────────────────────┘
Exemple architecture Kafka :
┌───────────┐ ┌───────────┐ ┌───────────┐
│ Orders │────▶│ KAFKA │────▶│ Analytics │
│ Service │ │ │ │ Service │
└───────────┘ │ orders │ └───────────┘
│ topic │
┌───────────┐ │ │ ┌───────────┐
│ Inventory │◀────│ │────▶│ Shipping │
│ Service │ └───────────┘ │ Service │
└───────────┘ └───────────┘
Quand Choisir RabbitMQ
┌─────────────────────────────────────────────────────────────────┐
│ RABBITMQ - CAS D'USAGE IDEAUX │
├─────────────────────────────────────────────────────────────────┤
│ │
│ [x] Task Queues et Work Distribution │
│ - Background job processing │
│ - Email sending queues │
│ - Image/video processing │
│ │
│ [x] Routing Complexe │
│ - Multi-consumer patterns │
│ - Header-based routing │
│ - Topic exchanges │
│ │
│ [x] Request-Reply Patterns │
│ - RPC over messaging │
│ - Correlation IDs │
│ - Temporary reply queues │
│ │
│ [x] Low Latency Messaging │
│ - Real-time notifications │
│ - Chat applications │
│ - Gaming events │
│ │
│ [ ] PAS ideal pour: │
│ - Tres haut volume (>100K msg/sec) │
│ - Long-term message storage │
│ - Event replay │
│ - Big data pipelines │
│ │
└─────────────────────────────────────────────────────────────────┘
Exemple architecture RabbitMQ :
┌───────────┐ ┌───────────────────────────────────┐
│ API │────▶│ RABBITMQ │
│ Server │ │ │
└───────────┘ │ ┌─────────────────────────────┐ │
│ │ Exchange (topic) │ │
│ └──────────┬──────────────────┘ │
│ │ │ │ │
│ ┌───▼──┐┌──▼───┐┌─▼────┐ │
│ │email ││image ││notify│ │
│ │queue ││queue ││queue │ │
│ └───┬──┘└──┬───┘└─┬────┘ │
└──────┼──────┼──────┼────────────┘
│ │ │
┌────▼─┐┌───▼──┐┌──▼────┐
│Email ││Image ││Notify │
│Worker││Worker││Worker │
└──────┘└──────┘└───────┘
Quand Choisir Pulsar
┌─────────────────────────────────────────────────────────────────┐
│ PULSAR - CAS D'USAGE IDEAUX │
├─────────────────────────────────────────────────────────────────┤
│ │
│ [x] Multi-Tenancy Native │
│ - SaaS platforms │
│ - Enterprise avec multiples BUs │
│ - Isolation stricte requise │
│ │
│ [x] Geo-Replication Native │
│ - Multi-region deployments │
│ - Global data distribution │
│ - Active-active clusters │
│ │
│ [x] Unified Queuing + Streaming │
│ - Mixed workloads │
│ - Transition progressive │
│ - Subscription modes varies │
│ │
│ [x] Tiered Storage Requirements │
│ - Long retention + cost optimization │
│ - Historical data access │
│ - Offload vers object storage │
│ │
│ [ ] PAS ideal pour: │
│ - Equipes avec peu d'experience │
│ - Projets simples │
│ - Budget operations limite │
│ - Besoin de latence < 5ms │
│ │
└─────────────────────────────────────────────────────────────────┘
Exemple architecture Pulsar :
┌─────────────────────────────────────────────────────────────────┐
│ PULSAR MULTI-TENANT │
│ │
│ ┌────────────────────┐ ┌────────────────────┐ │
│ │ Tenant: BU-A │ │ Tenant: BU-B │ │
│ │ ┌──────────────┐ │ │ ┌──────────────┐ │ │
│ │ │ Namespace: │ │ │ │ Namespace: │ │ │
│ │ │ orders │ │ │ │ analytics │ │ │
│ │ │ - topic1 │ │ │ │ - events │ │ │
│ │ │ - topic2 │ │ │ │ - metrics │ │ │
│ │ └──────────────┘ │ │ └──────────────┘ │ │
│ └────────────────────┘ └────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ PULSAR CLUSTER │ │
│ │ Brokers (stateless) + BookKeeper (storage) │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ TIERED STORAGE (S3/GCS) │ │
│ │ Cold data offload │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
Matrice de Decision
Arbre de Decision Simplifie
┌─────────────────────────────────────────────────────────────────┐
│ GUIDE DE DECISION │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Besoin principal ? │
│ │ │
│ ├─▶ Haute performance streaming ────────────────▶ KAFKA │
│ │ (>100K msg/sec, replay, event sourcing) │
│ │ │
│ ├─▶ Task queues et routing flexible ────────────▶ RABBITMQ │
│ │ (work distribution, routing complexe) │
│ │ │
│ ├─▶ Multi-tenancy ou geo-replication ───────────▶ PULSAR │
│ │ (isolation, global deployment) │
│ │ │
│ └─▶ Simple messaging entre services │
│ │ │
│ ├─▶ Equipe experimentee ────────────────────▶ KAFKA │
│ └─▶ Equipe debutante ───────────────────────▶ RABBITMQ │
│ │
└─────────────────────────────────────────────────────────────────┘
Scoring par Criteres
┌─────────────────────────────────────────────────────────────────┐
│ SCORING COMPARATIF │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Critere │ Kafka │ RabbitMQ │ Pulsar │ Poids │
│ ─────────────────────┼───────┼──────────┼────────┼──────── │
│ Throughput │ 5 │ 2 │ 4 │ x3 │
│ Latence │ 3 │ 5 │ 3 │ x2 │
│ Simplicite │ 3 │ 5 │ 2 │ x2 │
│ Ecosystem │ 5 │ 4 │ 3 │ x2 │
│ Replay/Retention │ 5 │ 1 │ 5 │ x2 │
│ Routing flexible │ 2 │ 5 │ 3 │ x1 │
│ Multi-tenancy │ 2 │ 3 │ 5 │ x1 │
│ Geo-replication │ 3 │ 2 │ 5 │ x1 │
│ Cout operationnel │ 3 │ 4 │ 2 │ x2 │
│ ─────────────────────┼───────┼──────────┼────────┼──────── │
│ SCORE TOTAL │ 55 │ 51 │ 50 │ │
│ │
│ Note: Scores de 1 (faible) a 5 (excellent) │
│ Adapter les poids selon VOS priorites │
│ │
└─────────────────────────────────────────────────────────────────┘
Checklist de Decision
## Checklist pour Choisir votre Solution
### Volume et Performance
- [ ] Volume attendu : _____ messages/seconde
- [ ] Taille moyenne des messages : _____ KB
- [ ] Latence requise : _____ ms (P99)
- [ ] Besoin de replay des messages : Oui / Non
### Fonctionnalites
- [ ] Routing complexe necessaire : Oui / Non
- [ ] Multi-tenancy requis : Oui / Non
- [ ] Geo-replication native : Oui / Non
- [ ] Stream processing integre : Oui / Non
- [ ] Schema management : Oui / Non
### Operations
- [ ] Experience equipe en messaging : Debutant / Intermediaire / Expert
- [ ] Budget operations : Faible / Moyen / Eleve
- [ ] Service manage acceptable : Oui / Non
- [ ] Kubernetes deployment : Oui / Non
### Contraintes
- [ ] Langages clients requis : _____
- [ ] Integration existante : _____
- [ ] Compliance/Securite : _____
Comparaison de Code
Producer - Envoi de Message
Kafka (Python) :
from confluent_kafka import Producer
producer = Producer({'bootstrap.servers': 'localhost:9092'})
producer.produce('my-topic', key='key1', value='Hello Kafka')
producer.flush()
RabbitMQ (Python) :
import pika
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
channel.queue_declare(queue='my-queue')
channel.basic_publish(exchange='', routing_key='my-queue', body='Hello RabbitMQ')
connection.close()
Pulsar (Python) :
import pulsar
client = pulsar.Client('pulsar://localhost:6650')
producer = client.create_producer('my-topic')
producer.send('Hello Pulsar'.encode('utf-8'))
client.close()
Consumer - Reception de Message
Kafka (Python) :
from confluent_kafka import Consumer
consumer = Consumer({
'bootstrap.servers': 'localhost:9092',
'group.id': 'my-group',
'auto.offset.reset': 'earliest'
})
consumer.subscribe(['my-topic'])
while True:
msg = consumer.poll(1.0)
if msg:
print(f"Received: {msg.value().decode('utf-8')}")
RabbitMQ (Python) :
import pika
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
def callback(ch, method, properties, body):
print(f"Received: {body.decode('utf-8')}")
channel.basic_consume(queue='my-queue', on_message_callback=callback, auto_ack=True)
channel.start_consuming()
Pulsar (Python) :
import pulsar
client = pulsar.Client('pulsar://localhost:6650')
consumer = client.subscribe('my-topic', 'my-subscription')
while True:
msg = consumer.receive()
print(f"Received: {msg.data().decode('utf-8')}")
consumer.acknowledge(msg)
Migration Entre Solutions
De RabbitMQ vers Kafka
┌─────────────────────────────────────────────────────────────────┐
│ MIGRATION RABBITMQ → KAFKA │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Phase 1: Dual-Write │
│ ┌──────────┐ ┌──────────┐ │
│ │ Producer │───▶│ RabbitMQ │───▶ Consumers existants │
│ │ │ └──────────┘ │
│ │ │ ┌──────────┐ │
│ │ │───▶│ Kafka │───▶ Nouveaux consumers │
│ └──────────┘ └──────────┘ │
│ │
│ Phase 2: Migration Consumers │
│ - Migrer progressivement les consumers vers Kafka │
│ - Valider fonctionnellement │
│ │
│ Phase 3: Cutover │
│ - Arreter l'ecriture vers RabbitMQ │
│ - Decommissioner RabbitMQ │
│ │
│ Points d'attention: │
│ - Pas de routing direct dans Kafka │
│ - Gestion des offsets differente │
│ - Replay possible = changement de comportement │
│ │
└─────────────────────────────────────────────────────────────────┘
A Retenir
Resume Executif
| Solution | Utilisez si... | Evitez si... |
|---|---|---|
| Kafka | Volume eleve, event sourcing, replay | Routing complexe, latence <5ms |
| RabbitMQ | Task queues, routing, simplicite | Tres haut volume, replay |
| Pulsar | Multi-tenant, geo-rep, unifie | Equipe junior, budget limite |
Recommandations Finales
Choisissez Kafka si :
- Vous construisez des pipelines de donnees
- Le replay des evenements est critique
- Vous avez besoin d'un ecosysteme riche
- Volume > 100K messages/seconde
Choisissez RabbitMQ si :
- Vous avez besoin de task queues simples
- Le routing flexible est important
- Votre equipe debute en messaging
- La latence sub-milliseconde est critique
Choisissez Pulsar si :
- Multi-tenancy est un requirement
- Vous avez besoin de geo-replication native
- Tiered storage est important
- Vous voulez unifier queuing et streaming
Besoin d'Aide pour Choisir ?
Le choix d'une plateforme de messaging est une decision architecturale majeure. Je peux vous accompagner :
- Atelier de cadrage : Analyser vos besoins specifiques
- POC comparatif : Tester les solutions dans votre contexte
- Migration : Accompagnement de RabbitMQ vers Kafka
- Formation : Monter en competence sur la solution choisie
Contactez-moi pour discuter de votre projet
Cet article fait partie de ma serie sur les architectures de messaging. Consultez egalement mes guides approfondis sur Kafka, incluant le monitoring, le tuning, et les patterns avances.