Zookeeper
Kafka
Consumer Offset
Data Management
Distributed Systems

How does Zookeeper/Kafka retain offset for a consumer?

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 high-throughput, distributed messaging system that is utilized by many organizations to handle real-time data feeds. ZooKeeper, on the other hand, plays a critical role in managing this ensemble by providing a distributed configuration service, synchronization service, and naming registry for large distributed systems like Kafka. One of the fundamental aspects in Kafka's ability to process streams of data efficiently lies in how it manages the consumer offsets. Understanding how Kafka maintains these offsets with the assistance of ZooKeeper is central to grasping Kafka's operational efficacy.

Understanding Offsets in Kafka

In Kafka, an offset is a unique identifier of a record in a Kafka partition. This offset allows Kafka's consumers to keep track of which messages have been consumed and which have not. Each Kafka message within a partition has an offset that acts like an address that provides the location information of a message within that partition.

When a consumer in Kafka reads messages, it needs to track the offsets of messages to ascertain the point up to which the messages have been consumed. Thus, maintaining accurate offsets ensures that the consumers are able to manage their operations without redundancy or message loss.

Role of Kafka in Managing Offsets

Kafka manages offsets by storing the offsets themselves within Kafka topics. Created in version 0.9.0, the __consumer_offsets topic came into existence, marking a turn from older versions where ZooKeeper itself was used to store these offsets.

When a consumer in a consumer group reads messages from a partition of a topic, it commits the offsets of messages it has consumed. By doing so, it indicates to Kafka that any message up to this offset has been consumed by that consumer group, and any new consumer joining the group should start consuming from the next offset.

Committing Offsets

Offsets can be committed in two ways:

  1. Automatic Commit: Here, offsets are committed automatically at intervals specified in the consumer configuration by auto.commit.interval.ms.
  2. Manual Commit: This allows consumers to control when to commit offsets and can be more precise about when offsets are considered safe and saved.

Interaction with ZooKeeper

ZooKeeper used to play a primary role in managing consumer offsets in Kafka protocols before version 0.9.0. Consumer metadata like offsets were stored in ZooKeeper, but this led to scalability issues as the volume of offsets and consumer metadata grew with the number of topics and partitions.

Post Kafka 0.9.0, for enhanced performance and scalability, this responsibility has been shifted from ZooKeeper to Kafka itself. This change relegated ZooKeeper to managing and coordinating brokers within the Kafka ecosystem rather than handling offsets directly. Now, ZooKeeper helps in leader election for Kafka broker partitions and in managing membership within the broker cluster, among other operational tasks.

Technical Insights into Offset Storage

As mentioned, offsets are stored in the __consumer_offsets topic, where each message in this topic denotes an offset commit. This topic is a compacted Kafka topic where the server retains only the last offset commit per partition and per consumer group. This compaction ensures efficient storage even as the number of consumers and offsets grows.

Format of Storage

Each record in the __consumer_offsets consists of:

  • Key: The key contains information about the consumer group and partition.
  • Value: The value stores the offset position, metadata, and a timestamp.

Summary

Here is a brief table summarizing how offsets are handled differently with the progression of Kafka versions:

FeaturePre Kafka 0.9.0Post Kafka 0.9.0
Offset Storage LocationZooKeeperKafka internal topic
Scalability and PerformanceLowerHigher
ControlLess (automatic)More (manual or automatic)
Reliability and Fault ToleranceDependent on ZKSelf-managed within Kafka

Conclusion

The shift from using ZooKeeper for offset management to using Kafka’s internal topic has helped Kafka become more scalable and reliable concerning message consumption. Understanding these core functionalities provides insights into Kafka’s design and architecture strategies which are pivotal for developing robust streaming applications.


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.