Kafka Configuration
FiFo Queue
Message Queuing
Distributed Systems
Data Streaming

How to configure Kafka to behave like a FiFo queue?

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 event streaming platform capable of handling trillions of events a day. Initially conceived as a high-throughput, low-latency publishing and subscribing solution, it also comes with features that allow it to be configured as a FIFO (First In, First Out) queue. Although Kafka is not a traditional messaging system and is designed primarily for distributed data streaming, with proper configuration, it can emulate FIFO queue behavior where messages are processed in the exact order they are produced. Here's how you can configure Kafka to behave like a FIFO queue:

Step 1: Create a Single Partition Topic

Kafka retains messages in the order they are received only within a single partition. Therefore, to maintain the order of all messages, you must use a topic with only one partition. Here's how you can create a single partition topic:

bash
kafka-topics --create --bootstrap-server <host>:<port> --replication-factor 1 --partitions 1 --topic your-fifo-topic

Step 2: Producer Configuration

Ensure that the producer's acks setting is all to guarantee that messages are replicated across all replicas before an acknowledgment is sent. This enhances the reliability of the system.

java
1Properties props = new Properties();
2props.put("bootstrap.servers", "<host>:<port>");
3props.put("acks", "all");
4props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
5props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");

Always use the same key or a null key to ensure that all messages go to the same partition.

Step 3: Consumer Configuration

Make sure you configure your consumer properly:

  • Enable auto commit to false to manually control the record offset.
  • Set max.poll.records to 1 to process one message at a time.
java
1Properties props = new Properties();
2props.put("bootstrap.servers", "<host>:<port>");
3props.put("group.id", "your-consumer-group");
4props.put("enable.auto.commit", "false");
5props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
6props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
7props.put("max.poll.records", "1");

Step 4: Managing Offsets

Handling offsets manually is crucial. After processing each message, manually commit the offset. This ensures that each message is processed in order.

java
1while (true) {
2    ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(100));
3    for (ConsumerRecord<String, String> record : records) {
4        processMessage(record);
5        consumer.commitSync();
6    }
7}

Best Practices and Considerations

  1. Immutability of Messages: Once a message is written to a Kafka topic, it cannot be changed. Ensure that messages are correct before sending them.
  2. Failure Handling: Carefully handle possible exceptions in your consumer logic, such as processing errors from which the application must recover.

Performance Considerations

While configuring Kafka to act as a FIFO queue, one must be aware of potential performance impacts due to:

  • Single Partition: Limits the scalability as throughput is capped by a single partition's performance.
  • Manual Offset Management: Can slow down processing if not handled efficiently.

Summary Table

Configuration KeyRecommended SettingDescription
Partitions1Ensures message order within the topic.
Producer acksallEnsures data durability and consistency.
Consumer max.poll.records1Forces consumer to process one message at a time.
Consumer commitManual (commitSync)Gives full control over when a message is considered "consumed."
Key SerializationConsistent or nullEnsures all messages go to the same partition.

In conclusion, configuring Kafka as a FIFO queue involves strategic settings and trade-offs. Maintaining message order requires sacrificing some of Kafka's natural advantages like horizontal scalability and high-throughput performance for multiple partitions. However, for use cases where message order is paramount and large-scale throughput is less critical, these trade-offs can be justified.


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.