Spring Kafka
Delivery Guarantee
Exactly Once
Message Queuing
Distributed Systems

Spring Kafka and exactly once delivery guarantee

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Apache Kafka is a distributed streaming platform that has three core capabilities: Publishing and subscribing to streams of records, storing streams of records in a fault-tolerant way, and processing streams of records as they occur. Kafka is widely used across engineering teams for its high throughput and resilience to node failures, making it an excellent choice for large-scale event processing applications.

Introducing Spring Kafka

Spring Kafka brings the simple and typical Spring template programming model to Kafka. Developed under the Spring umbrella, it provides a high-level abstraction for Kafka-based messaging solutions. Spring Kafka simplifies the use of Kafka by enabling the development of message-driven microservices and stream processing applications in a loosely coupled manner. It integrates deeply into the Spring ecosystem, including the Spring Boot framework, to provide configuration and abstraction layers that make working with Kafka considerably simpler.

Exactly Once Delivery

In the context of distributed systems, message delivery semantics can generally be divided into three categories: at-most-once, at-least-once, and exactly-once. "Exactly once" delivery semantics ensures that a message is delivered once and only once to the end consumer, even in the case of failures. This is the holy grail of messaging systems as it ensures reliable communication without duplication.

Implementing exactly once delivery is challenging due to potential duplicates on retries and the complexity of tracking acknowledges. Kafka, since version 0.11, supports exactly-once semantics in the context of message production and consumption.

How Exactly Once Semantics are Implemented in Kafka

Kafka’s exactly-once semantics is implemented through its idempotent producer and transactional APIs. The idempotent producer ensures that messages are not duplicated when they are sent to a Kafka topic, while the transactional API allows applications to write multiple messages across several partitions atomically.

To achieve exactly once semantics when producing to Kafka using Spring Kafka, you can follow these steps:

  1. Enable Idempotence: Configure the producer setting enable.idempotent to true.
  2. Use Kafka Transactions: Enabled by setting up the transactional.id in the producer configuration, which ensures that a group of messages across multiple partitions can be committed or aborted together.
  3. Transaction Coordinator: Kafka uses a Transaction Coordinator to manage the transaction states, which is an internal Kafka mechanism.

Implementing Exactly Once in Spring Kafka

Implement TerminologySpring Configuration
Idempotent producerproducerProperties.put("enable.idempotence", true);
Transactional producerproducerProperties.put("transactional.id", "tx-id");
Consumer offset handlingManaged in the Kafka transaction

Code Example: Spring Kafka Exactly Once

java
1import org.springframework.kafka.annotation.KafkaListener;
2import org.springframework.kafka.core.KafkaTemplate;
3import org.springframework.beans.factory.annotation.Autowired;
4import org.springframework.kafka.transaction.KafkaTransactionManager;
5import org.springframework.transaction.annotation.Transactional;
6
7public class KafkaProducerConsumer {
8
9    @Autowired
10    private KafkaTemplate<String, String> kafkaTemplate;
11
12    @Transactional
13    public void sendMessage(String message) {
14        kafkaTemplate.executeInTransaction(kt -> kt.send("topic1", message));
15    }
16
17    @KafkaListener(topics = "topic1", groupId = "group_id")
18    public void processMessage(String content) {
19        // Here, process the message exactly once
20    }
21}

This code snippet demonstrates a simple producer and consumer application where the producer sends messages using a transaction, and the consumer processes these messages. Note that the actual message could require further integrity checks to ensure duplication hasn't occurred at other parts of the system.

Pros and Cons of Exactly Once Semantics

Advantages:

  • Eliminates the complexity of handling duplicates at the consumer level.
  • Simplifies consumer logic as each message needs to be processed only once.

Disadvantages:

  • Potential for increased latency due to overhead of maintaining and checking transactions.
  • More complex configuration and resource management.

Conclusion

Implementing exactly once semantics in Kafka using Spring Kafka requires a careful setup of producer and consumer configurations. While it ensures reliable processing of messages, it can introduce additional overhead. Depending on the use case, it is crucial to evaluate whether the benefits of exactly once semantics outweigh the potential drawbacks like latency and system complexity. For many critical applications, however, exactly once delivery is essential for data consistency and integrity, making this setup vital.


Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.