Salta al contenuto

Kafka diventa Message Broker con KIP-932 Queue Semantics in GA

Kafka Becomes a Message Broker with KIP-932 Queue Semantics in GA

2026-03-08
Kafka diventa Message Broker con KIP-932 Queue Semantics in GA

Sommario

Il 3 marzo 2026, Confluent ha annunciato la disponibilità generale di Queues for Apache Kafka (KIP-932), una feature che abilita la semantica nativa di coda su Kafka tramite share groups. Questa non è una semplice aggiunta incrementale: per le organizzazioni enterprise che finora mantenevano paralleli Kafka (per streaming event) e RabbitMQ o Amazon SQS (per garantire exactly-once queueing), rappresenta un'opportunità concreta di consolidamento infrastrutturale, con implicazioni immediate su costi operativi, complessità di governance e latenza end-to-end dei sistemi di messaging.

Il problema architetturale: due tool per un'unica esigenza

Chi gestisce sistemi di messaging distribuiti a scala enterprise sa che esiste una frattura fondamentale nella moderna stack. Da un lato, Kafka brilla nel distribuire stream di event immutabili su centinaia di consumer in parallelo, ogni consumer legge tutto il flusso oppure una porzione per partizione. Dall'altro, i team che hanno bisogno di strict ordering per consumer, delivery guarantees e competitive consumption (ogni messaggio viene consumato da esattamente un consumer) hanno dovuto affidarsi a RabbitMQ, Apache ActiveMQ o servizi cloud come Amazon SQS. Questo non è un limite architetturale minore: è una decisione che si ripercuote su deployment, operazioni, backup e disaster recovery.

Un'azienda di medio-grande dimensione finisce spesso con:

  • Kafka cluster per analytics, audit trail, event sourcing
  • RabbitMQ stack (o SQS + SNS) per task-based messaging, order processing, transazionali
  • Due diverse curve di apprendimento, due monitoraggi, due set di secret management

In ambienti regolamentati come banche e assicurazioni, questa dualità comporta costi nascosti: ogni stack richiede audit separati, strategie di backup indipendenti, e il team di platform engineering deve certificare due broker diversi. Un consolidamento rappresenta immediatamente una riduzione di superficie di attacco, di overhead operativo e di rischio.

Share Groups e il paradigma KIP-932: da topic to queue

KIP-932 (Kafka Improvement Proposal 932) introduce il concetto di share groups, una nuova aggregazione logica di consumer che cambiano il modello semantico di Kafka dal lato consumption. Ecco cosa accade:

Modello tradizionale (topic + consumer group): Ogni consumer in un consumer group legge da partizioni distinte per motivi di load balancing. Se il topic ha 3 partizioni e 2 consumer, uno legge da 2 partizioni e uno da 1. Se esiste un terzo consumer, il rebalancing ridistribuisce. Ogni consumer riceve il messaggio. Se serve una semantica exactly-once end-to-end, la responsabilità ricade sul codice applicativo che legge, cioè deduplicazione e idempotenza lato consumer. Se il messaggio finisce in una dead letter queue, è perché l'applicazione lo ha intercettato e instradato lì.

Modello share group (nuovo, KIP-932): Un singolo messaggio viene consumato da esattamente un membro del share group. Se il consumer A acquisisce il messaggio, il consumer B non lo vedrà. Se il consumer A fallisce prima di committare l'offset, il messaggio ritorna disponibile agli altri consumer del group (lock timeout). Questo è il comportamento di RabbitMQ: competitive consumption.

La pratica con Kafka 4.2 su Confluent Cloud diventa:

kafka-console-consumer.sh \
  --bootstrap-servers=<broker> \
  --topic order-processing \
  --group-instance-id=queue-consumer-1 \
  --isolation-level=read_committed \
  --share-group=order-fulfillment-share-group

Notate il parametro --share-group invece di --group. La differenza non è cosmetica: il behavior è quello di una coda, non di un topic subscriber.

Quando consolidare: i trade-off reali

La tentazione immediata è demolire il cluster RabbitMQ e migrare tutto in Kafka. Questo è rischioso e sbagliato per almeno tre ragioni.

1. Latenza di ack e timeout di lock

RabbitMQ offre acknowledgment immediato: il consumer legge il messaggio, lo processa in 10 ms, invia l'ack, il broker lo scarta. In Kafka con share groups, il broker fa un polling-based locking interno: il messaggio rimane nel log, il consumer acquisisce un "lease" con un timeout configurabile (default 5 minuti). Se il consumer non fa heartbeat prima che il lease scada, il messaggio diventa disponibile agli altri. Per workload ultra-reattivi (es. pagamenti sub-millisecond), questo overhead può essere percettibile: test interni di Confluent mostrano P99 di 5-10 ms aggiuntivi per share group vs consumer group tradizionale su topic.

2. Semantica di poison message handling

In RabbitMQ, se un messaggio non può essere elaborato, si invia explicit NACK e il broker lo reinoltra automaticamente o lo manda in dead letter exchange. In Kafka con share group, il messaggio rimane nel log finché non viene committato. Se l'applicazione non lo committa (es. perché lancia un'eccezione), il lease scade e il messaggio torna disponibile, ma rimane nello stesso topic/partizione. Se è sistematicamente avvelenato (poison message), il consumer finisce in un loop infinito. Il pattern migliore è usare topic paralleli di dead letter o topic di retry, ma richiede logica applicativa: non è gratuito.

3. Retention policy vs queueing lifetime

Un topic Kafka ha una retention configurabile (giorni, size). Un share group message, una volta committato, è "consumato", ma il topic mantiene il dato per la retention. Se il topic è configurato per 30 giorni di retention ma il message viene letto il primo giorno, rimane nel log per altri 29 giorni. In RabbitMQ, una volta ackato, il messaggio è cancellato. Per use case di perishable messaging (es. task di cache invalidation), questo può essere inefficiente. La soluzione è configurare topic di breve retention per share group, ma aggiunge complessità.

Consolidamento pragmatico: due scenari

Scenario A: Event sourcing + order processing simultanei su Kafka (CONSIGLIATO)

L'architettura migliore vede un topic Kafka unico per una bounded context, con due consumer group pattern in parallelo:

  • Consumer group tradizionale per audit: audit-analytics-group legge l'intero topic, costruisce lo stato analitico per il data warehouse e materializza viste derivate. Non distribuisce per priorità di consumer, ma segue il timestamp dell'evento.
  • Share group per processing: order-fulfillment-group consuma per la logica applicativa transazionale, garantisce una sola elaborazione per messaggio e committa l'offset solo dopo che la transazione sul database è stata scritta con successo.
Topic: order.created (partizioni: 10, key: order_id)

Consumer Groups:

  - audit-analytics-group (3 consumer) -> legacy analytics pipeline
  - order-fulfillment-group (5 share group) -> order fulfillment engine

Ogni messaggio finisce nei log una volta. L'audit riceve tutto (eventual consistency). L'order worker riceve il messaggio esattamente una volta, anche se fallisce e riparte.

Scenario B: RabbitMQ full replacement (SOLO se no single-partition guarantee)

Se il workload non ha vincoli di ordering (es. email notifications, batch jobs non correlati), è possibile migrare RabbitMQ → Kafka share group direttamente. Non servono consumer group paralleli. La retention del topic diventa il "TTL della coda".

Requisiti:

  • payload < 1 MB (Kafka è meno efficiente per i piccoli messaggi rispetto a RabbitMQ)
  • Nessuna garanzia di ordinamento tra eventi diversi
  • Il team ha familiarità con il modello operativo di Kafka, incluso un maggiore uso di spazio disco

Implicazioni su FinOps e governance

Il consolidamento salva costi infrastrutturali ma introduce trade-off di architettura. Una stima realistica per un'azienda con 100 nodi Kubernetes e messagging diffuso:

Metrica RabbitMQ + Kafka (oggi) Kafka solo (KIP-932)
Licenze/manutenzione annuale €80-120k €120-150k (Confluent)
Storage (GB/day per topology) 500 GB 2.5 TB (retention)
Operatori specializzati 2.5 FTE 1.5 FTE
MTTR incidenti di messaging 45 min (doppio stack) 25 min (unico stack)
Net ROI in 24 mesi Baseline +€200-350k

I numeri dipendono molto dal rapporto tra traffico queue e stream, ma un consolidamento ben fatto riduce la complessità manageriale e operativa, con break-even tipicamente entro 18 mesi in ambienti enterprise.

Roadmap di migrazione minima

Se decidete di consolidare:

  1. Fase 1 (mese 1): Identificare i topic Kafka candidati. Se esiste un topic già pubblicato su Kafka ma il microservizio consumatore continua a leggere da RabbitMQ, quel flusso è un candidato ideale (viceversa, non consolidate).

  2. Fase 2 (mese 2-3): Eseguire un pilot share group su un sottosistema non critico. Misurare la latenza P50/P95/P99 contro il vecchio pattern. Usare Confluent Client v3.0+ che ha supporto share group integrato.

  3. Fase 3 (mese 4-6): Migrare il primo flusso business-critical (es. regolamento dei pagamenti). Non toccate il resto finché non avete 30 giorni di produzione stabile.

  4. Fase 4 (mese 6-12): Dismettere il cluster RabbitMQ e riallocare lo storage.

Durante tutto il periodo, mantenete entrambi gli stack live. Il costo di dual-run è inferiore al rischio di downtime.

Conclusione

KIP-932 non elimina la necessità di gestire il trade-off tra event streaming e queueing. Lo sposta, però, a un livello più uniforme di astrazione operativa: un unico broker Kafka ora supporta entrambi i pattern. Per gli architect enterprise in ambienti regolamentati, il valore non è la singola feature (Confluent Platform ha supportato questo internamente da mesi), ma la normalizzazione e la governance di un'architettura consolidata. Il consolidamento ha senso dove la complessità operativa è il vincolo principale. Se il vostro team ha già esperienza profonda su due stack, il costo di unificazione potrebbe essere tangibile nei mesi di transizione, ma le metriche di lungo termine (MTTR, overhead operativo, storage footprint omogeneo) suggeriscono che il ROI positivo emerge entro due anni.

Summary

On March 3, 2026, Confluent announced the general availability of Queues for Apache Kafka (KIP-932), a feature that enables native queue semantics on Kafka through share groups. This isn't a simple incremental addition: for enterprise organizations that have until now maintained parallel Kafka (for event streaming) and RabbitMQ or Amazon SQS (to guarantee exactly-once queueing), it represents a concrete opportunity for infrastructure consolidation, with immediate implications for operating costs, governance complexity, and end-to-end latency of messaging systems.

The Architectural Problem: Two Tools for One Need

Those who manage distributed messaging systems at enterprise scale know that there is a fundamental fracture in the modern stack. On one hand, Kafka excels at distributing immutable event streams to hundreds of consumers in parallel, each consumer reading the entire stream or a portion per partition. On the other hand, teams that need strict ordering per consumer, delivery guarantees, and competitive consumption (each message is consumed by exactly one consumer) have had to rely on RabbitMQ, Apache ActiveMQ, or cloud services like Amazon SQS. This isn't a minor architectural limitation: it's a decision that impacts deployment, operations, backup, and disaster recovery.

A medium-to-large-sized company often ends up with:

  • Kafka cluster for analytics, audit trail, event sourcing
  • RabbitMQ stack (or SQS + SNS) for task-based messaging, order processing, transactional
  • Two different learning curves, two monitorings, two sets of secret management

In regulated environments like banks and insurance companies, this duality entails hidden costs: each stack requires separate audits, independent backup strategies, and the platform engineering team must certify two different brokers. Consolidation immediately represents a reduction in attack surface, operational overhead, and risk.

Share Groups and the KIP-932 Paradigm: From Topic to Queue

KIP-932 (Kafka Improvement Proposal 932) introduces the concept of share groups, a new logical aggregation of consumers that changes Kafka's semantic model from the consumption side. Here's what happens:

Traditional Model (topic + consumer group): Each consumer in a consumer group reads from distinct partitions for load balancing purposes. If the topic has 3 partitions and 2 consumers, one reads from 2 partitions and one from 1. If a third consumer arrives, rebalancing redistributes. Each consumer receives the message. If exactly-once end-to-end semantics are needed, the responsibility falls on the application code that reads, i.e., deduplication and idempotency on the consumer side. If the message ends up in a dead letter queue, it's because the application intercepted and routed it there.

Share Group Model (new, KIP-932): A single message is consumed by exactly one member of the share group. If consumer A acquires the message, consumer B will not see it. If consumer A fails before committing the offset, the message becomes available to other consumers in the group (lock timeout). This is the behavior of RabbitMQ: competitive consumption.

In practice, with Kafka 4.2 on Confluent Cloud, it becomes:

kafka-console-consumer.sh \
  --bootstrap-servers=<broker> \
  --topic order-processing \
  --group-instance-id=queue-consumer-1 \
  --isolation-level=read_committed \
  --share-group=order-fulfillment-share-group

Note the --share-group parameter instead of --group. The difference isn't cosmetic: the behavior is that of a queue, not a topic subscriber.

When to Consolidate: The Real Trade-offs

The immediate temptation is to demolish the RabbitMQ cluster and migrate everything to Kafka. This is risky and wrong for at least three reasons.

1. Ack Latency and Lock Timeouts

RabbitMQ offers immediate acknowledgment: the consumer reads the message, processes it in 10 ms, sends the ack, and the broker discards it. In Kafka with share groups, the broker does an internal polling-based locking: the message remains in the log, the consumer acquires a "lease" with a configurable timeout (default 5 minutes). If the consumer doesn't heartbeat before the lease expires, the message becomes available to other consumers. For ultra-reactive workloads (e.g., sub-millisecond payments), this overhead can be noticeable: internal Confluent tests show P99 of 5-10 ms additional for share group vs. traditional consumer group on topic.

2. Poison Message Handling Semantics

In RabbitMQ, if a message cannot be processed, you send an explicit NACK and the broker automatically re-queues it or sends it to a dead letter exchange. In Kafka with share group, the message remains in the log until it is committed. If the application doesn't commit it (e.g., because it throws an exception), the lease expires and the message becomes available again, but remains in the same topic/partition. If it's systematically poisoned (poison message), the consumer ends up in an infinite loop. The best pattern is to use parallel dead letter topics or retry topics, but requires application logic: it's not free.

3. Retention Policy vs. Queueing Lifetime

A Kafka topic has a configurable retention (days, size). A share group message, once committed, is "consumed," but the topic retains the data for the retention period. If the topic is configured for 30 days of retention but the message is read on the first day, it remains in the log for another 29 days. In RabbitMQ, once acknowledged, the message is deleted. For use cases of perishable messaging (e.g., cache invalidation tasks), this can be inefficient. The solution is to configure short-retention topics for share groups, but adds complexity.

Pragmatic Consolidation: Two Scenarios

Scenario A: Event Sourcing + Order Processing Simultaneously on Kafka (RECOMMENDED)

The best architecture sees a single Kafka topic for a bounded context, with two consumer group patterns in parallel:

  • Traditional consumer group for audit: audit-analytics-group reads the entire topic, builds the analytical state for the data warehouse, and materializes derived views. It doesn't distribute by consumer priority, but follows the event timestamp.
  • Share group for processing: order-fulfillment-group consumes for transactional application logic, guarantees a single processing per message, and commits the offset only after the transaction on the database has been written successfully.
Topic: order.created (partitions: 10, key: order_id)

Consumer Groups:

  - audit-analytics-group (3 consumers) -> legacy analytics pipeline
  - order-fulfillment-group (5 share group) -> order fulfillment engine

Each message ends up in the logs once. Audit receives everything (eventual consistency). The order worker receives the message exactly once, even if it fails and restarts.

Scenario B: RabbitMQ Full Replacement (ONLY if no single-partition guarantee)

If the workload has no ordering constraints (e.g., email notifications, unrelated batch jobs), you can migrate RabbitMQ → Kafka share group directly. No parallel consumer groups are needed. The topic retention becomes the "queue TTL".

Requirements:

  • payload < 1 MB (Kafka is less efficient for small messages compared to RabbitMQ)
  • No ordering guarantee between different events
  • The team is familiar with Kafka's operational model, including greater use of disk space

Implications for FinOps and Governance

Consolidation saves infrastructure costs but introduces architectural trade-offs. A realistic estimate for a company with 100 Kubernetes nodes and widespread messaging:

Metric RabbitMQ + Kafka (today) Kafka only (KIP-932)
Licenses/maintenance annual €80-120k €120-150k (Confluent)
Storage (GB/day per topology) 500 GB 2.5 TB (retention)
Specialized operators 2.5 FTE 1.5 FTE
MTTR messaging incidents 45 min (double stack) 25 min (single stack)
Net ROI in 24 months Baseline +€200-350k

The numbers depend heavily on the ratio of queue traffic to stream traffic, but a well-executed consolidation reduces managerial and operational complexity, with break-even typically within 18 months in enterprise environments.

Minimum Migration Roadmap

If you decide to consolidate:

  1. Phase 1 (month 1): Identify candidate Kafka topics. If there's a topic already published on Kafka but the microservice consumer continues to read from RabbitMQ, that flow is an ideal candidate (vice versa, don't consolidate).

  2. Phase 2 (month 2-3): Run a pilot share group on a non-critical subsystem. Measure P50/P95/P99 latency against the old pattern. Use Confluent Client v3.0+ which has integrated share group support.

  3. Phase 3 (month 4-6): Migrate the first business-critical flow (e.g., payment settlement). Don't touch the rest until you have 30 days of stable production.

  4. Phase 4 (month 6-12): Retire the RabbitMQ cluster and reallocate the storage.

Throughout the period, keep both stacks live. The cost of dual-run is lower than the risk of downtime.

Conclusion

KIP-932 doesn't eliminate the need to manage the trade-off between event streaming and queueing. However, it shifts it to a more uniform level of operational abstraction: a single Kafka broker now supports both patterns. For enterprise architects in regulated environments, the value isn't the single feature (Confluent Platform has supported this internally for months), but the normalization and governance of a consolidated architecture. Consolidation makes sense where operational complexity is the primary constraint. If your team already has deep experience with two stacks, the cost of unification may be tangible in the transition months, but the long-term metrics (MTTR, operational overhead, homogeneous storage footprint) suggest that a positive ROI emerges within two years.