Felpfe Inc.
Search
Close this search box.
call 24/7

+484 237-1364‬

Search
Close this search box.

Partitioning Data in Kafka: Dividing to Conquer Stream Processing

Introduction

When working with Apache Kafka, partitioning is an essential concept to grasp. Kafka topics are divided into partitions, which allow for parallelism when consuming data, providing significant speed benefits and allowing Kafka’s impressive scalability. In this deep-dive, we’ll dissect how partitioning works in Kafka, look at strategies for effective partitioning, and discuss how it enables us to conquer stream processing.

Part 1: Basics of Kafka Partitions

Let’s begin by understanding what Kafka partitions are and why they matter.

1. Understanding Kafka Partitions

When a topic is created in Kafka, it is divided into one or more partitions. This division allows messages within a topic to be split across different brokers, enabling higher throughput.

Bash
kafka-topics.sh --create --bootstrap-server localhost:9092 --replication-factor 1 --partitions 3 --topic partitioned-topic

This command creates a topic named partitioned-topic with 3 partitions.

2. Data Distribution Across Partitions

When a producer sends data to a Kafka topic, the data gets distributed across the available partitions. This distribution depends on the selected partition strategy.

Java
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");

Producer<String, String> producer = new KafkaProducer<>(props);
for(int i = 0; i < 100; i++)
    producer.send(new ProducerRecord<String, String>("partitioned-topic", Integer.toString(i), Integer.toString(i)));
producer.close();

In this Java code, the producer sends 100 messages to partitioned-topic. By default, if a key is specified (here, Integer.toString(i)), Kafka uses a hash of the key to decide which partition to send the data.

Part 2: Effective Partitioning

Effective partitioning is crucial to leveraging the scalability and parallelism of Kafka. Let’s discuss some strategies and see examples.

3. Keyed Message Partitioning

As we saw earlier, specifying a key in your messages is one way to influence how messages are distributed across partitions. Messages with the same key will always go to the same partition, assuming the number of partitions doesn’t change.

Java
producer.send(new ProducerRecord<String, String>("partitioned-topic", "key1", "value1"));
producer.send(new ProducerRecord<String, String>("partitioned-topic", "key2", "value2"));
producer.send(new ProducerRecord<String, String>("partitioned-topic", "key1", "value3"));
producer.send(new ProducerRecord<String, String>("partitioned-topic", "key2", "value4"));

In this example, all messages with “key1” will end up in the same partition, and similarly for “key2”.

4. Round-Robin Partitioning

If no key is provided, Kafka will distribute the messages in a round-robin fashion to balance the load evenly.

Java
producer.send(new ProducerRecord<String, String>("partitioned-topic", "value1"));
producer.send(new ProducerRecord<String, String>("partitioned-topic", "value2"));
producer.send(new ProducerRecord<String, String>("partitioned-topic", "value3"));
producer.send(new ProducerRecord<String, String>("partitioned-topic", "value4"));

Here, the messages are distributed evenly and cyclically over the available partitions.

5. Custom Partitioning

Kafka also allows you to define your own partitioning logic by implementing the org.apache.kafka.clients.producer.Partitioner interface.

Java
public class CustomPartitioner implements Partitioner {
    @Override
    public int partition(String topic, Object key, byte[] keyBytes, Object value, byte[] valueBytes, Cluster cluster) {
        // Implement your custom partitioning logic here
        return 0;
    }
}

You can then specify this partitioner in your producer configuration:

Java
props.put("partitioner.class", "com.example.kafka.CustomPartitioner");

Part 3: Parallel Consumption

A significant advantage of partitioning in Kafka is the ability to consume data in parallel.

6. Single Consumer Reading from Multiple Partitions

A single consumer can read from multiple partitions, increasing throughput.

Java
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("group.id", "test");
props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");

KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
consumer.subscribe(Arrays.asList("partitioned-topic"));

while (true) {
    ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(100));
    for (ConsumerRecord<String, String> record : records)
        System.out.printf("offset = %d, key = %s, value = %s%n", record.offset(), record.key(), record.value());
}

This Java code shows a consumer that reads from all partitions of the partitioned-topic.

7. Multiple Consumers in a Group Reading from Different Partitions

Multiple consumers in the same consumer group can read from different partitions concurrently, thus sharing the load.

Java
props.put("group.id", "test");
KafkaConsumer<String, String> consumer1 = new KafkaConsumer<>(props);
KafkaConsumer<String, String> consumer2 = new KafkaConsumer<>(props);
// Both consumers will read different partitions of the same topic
consumer1.subscribe(Arrays.asList("partitioned-topic"));
consumer2.subscribe(Arrays.asList("partitioned-topic"));

These two consumers are part of the same consumer group (“test”), and each will read from a different partition of partitioned-topic.

8. Balancing Partitions Across Consumers

Kafka automatically handles the assignment of partitions to consumers in the same consumer group. If a consumer fails, Kafka reassigns its partitions to other consumers in the group.

Java
props.put("group.id", "test");
KafkaConsumer<String, String> consumer1 = new KafkaConsumer<>(props);
KafkaConsumer<String, String> consumer2 = new KafkaConsumer<>(props);
KafkaConsumer<String, String> consumer3 = new KafkaConsumer<>(props);
// If consumer1 fails, its partitions will be reassigned to consumer2 and consumer3
consumer1.subscribe(Arrays.asList("partitioned-topic"));
consumer2.subscribe(Arrays.asList("partitioned-topic"));
consumer3.subscribe(Arrays.asList("partitioned-topic"));

This scenario shows three consumers. If consumer1 fails, its partitions will be reassigned to consumer2 and consumer3.

Conclusion

Partitioning in Kafka plays a vital role in providing the high-throughput and scalable capabilities that Kafka is renowned for. In this blog post, we have discussed the basics of Kafka partitions, how data is distributed across partitions, how to implement effective partitioning strategies, and how to leverage partitioning to enable parallel data consumption.

Partitioning is key (pun intended) to conquering data stream processing with Kafka. It provides the flexibility and functionality necessary to ensure your Kafka-based data pipeline can handle vast quantities of data with ease. As always, understanding these concepts is just the first step. The real magic happens when you start applying

these principles to real-world data problems. Happy streaming!

Leave a Reply

About Author
Ozzie Feliciano CTO @ Felpfe Inc.

Ozzie Feliciano is a highly experienced technologist with a remarkable twenty-three years of expertise in the technology industry.

kafka-logo-tall-apache-kafka-fel
Stream Dream: Diving into Kafka Streams
In “Stream Dream: Diving into Kafka Streams,”...
ksql
Talking in Streams: KSQL for the SQL Lovers
“Talking in Streams: KSQL for the SQL Lovers”...
spring_cloud
Stream Symphony: Real-time Wizardry with Spring Cloud Stream Orchestration
Description: The blog post, “Stream Symphony:...
1_GVb-mYlEyq_L35dg7TEN2w
Kafka Chronicles: Saga of Resilient Microservices Communication with Spring Cloud Stream
“Kafka Chronicles: Saga of Resilient Microservices...
kafka-logo-tall-apache-kafka-fel
Tackling Security in Kafka: A Comprehensive Guide on Authentication and Authorization
As the usage of Apache Kafka continues to grow in organizations...
1 2 3 58
90's, 2000's and Today's Hits
Decades of Hits, One Station

Listen to the greatest hits of the 90s, 2000s and Today. Now on TuneIn. Listen while you code.