Kafka Stream
Repartition
Data Processing
Stream Processing
Distributed Systems

What, exactly happens when a repartition occurs in a kafka stream?

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 streams provide a powerful framework for processing streaming data in real-time. Repartitioning within Kafka Streams is a fundamental concept that enables the scalable and efficient distribution of data across different nodes or processes. Let’s delve into what exactly happens during a repartition operation, why it's necessary, and how it affects stream processing.

Understanding Kafka Streams Repartition

Repartitioning in Kafka Streams refers to the redistribution of data across Kafka topics based on the key of the messages. This process is crucial when the subsequent operations in the Kafka Streams application (like groupByKey, aggregate, or join) require data to be partitioned differently than the original input topic.

When Does Repartition Occur?

Kafka Streams may perform repartitioning in the following cases:

  1. Key Modification Operations: If a stream's key is modified through operations such as selectKey or map, Kafka Streams might need to repartition the stream to ensure that records with the same key are routed to the same Stream Task.
  2. Grouping Operations: Before performing aggregation operations (count, reduce, aggregate), data must be grouped by key. If the current partitioning doesn’t align with the keys, a repartition will occur.
  3. Join Operations: For both KStream-to-KStream and KTable-to-KTable joins, it is essential that the records of both streams are partitioned on the join key.

Technical Process of Repartition

When Kafka Streams decides to repartition:

  1. New Topic Creation: Kafka Streams internally creates a new Kafka topic for repartitioning purposes. This topic's name typically follows the pattern applicationId-<name>-repartition.
  2. Data Writing: Data from the original stream that needs repartitioning is written to this new topic. The partitioning happens based on the new key or the relevant key derived from stream transformations.
  3. Data Reading: The new (repartitioned) data is then read back as a new KStream for subsequent operations like joins or aggregations.

Example of a Repartition Operation in Kafka Streams

Consider a Kafka Streams application that reads user click events and counts clicks per user per hour. If the incoming data is not keyed by user ID, a repartition might look like this:

java
1KStream<byte[], String> clicks = builder.stream("clicks-topic");
2
3KStream<String, String> clicksByUser = clicks.selectKey((key, value) -> extractUserId(value))
4                                             .repartition(Repartitioned.as("clicks-by-user-repartition"));
5
6KTable<Windowed<String>, Long> clicksPerUserPerHour = clicksByUser
7    .groupByKey(Grouped.with(Serdes.String(), Serdes.String()))
8    .windowedBy(TimeWindows.of(Duration.ofHours(1)))
9    .count();

In this example, the selectKey operation changes the key of the stream (to user ID), leading Kafka Streams to create a new repartition topic to ensure that all clicks by the same user go to the same task for correct aggregation.

Impact and Considerations

Performance: While repartitioning helps in functionally correct stream processing, it has a performance cost. Writing to and reading from an intermediate topic consumes additional resources and increases latency.

Scalability: Repartition topics in Kafka can be scaled by increasing the number of partitions, just like any standard Kafka topic.

Fault Tolerance: Like other Kafka topics, repartition topics benefit from Kafka's inherent fault tolerance through replication.

Monitoring: Kafka Streams’ performance during repartitioning can be monitored using Kafka metrics, which include counts of produced and consumed messages to and from these topics.

Summary

Here is a summary table of when repartitioning action is triggered:

ConditionRepartition Trigger
Key ModificationWhen operations like selectKey change the stream’s key.
Grouping for AggregationNecessary before operations like groupByKey.
Join OperationsRequired when joining streams or tables on different keys.

In conclusion, repartitioning is a powerful mechanism in Kafka Streams that supports the logical redirection of data for stream processing tasks that depend on certain keys. It ensures data co-location based on keys, which is critical for stateful operations but comes with considerations of additional resource usage and latency. Proper understanding and handling of repartitioning can lead to more efficient Kafka Streams 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.