Search code examples
springapache-kafkaspring-kafka

Dynamically adapt the number of consumer thread to the number of Kafka partitions


I have a Kafka topic with 50 partitions.
My Spring Boot application uses Spring Kafka to read those messages with a @KafkaListener

The number of instances of my application autoscale in my Kubernetes.

By default, it seems that Spring Kafka launch 1 consumer thread per topic.

org.springframework.kafka.KafkaListenerEndpointContainer#0-0-C-1

So, with a unique instance of the application, one thread is reading the 50 partitions.
With 2 instances, there is a load balancing and each instance listen to 25 partitions. Still with 1 thread per instance.

I know I can set the number of thread using the concurrency parameter on @KafkaListener.
But this is a fixed value.

Is there any way to tell Spring to dynamically adapt the number of consumer threads to the number of partition the client is currently listening?


Solution

  • I think there might be a better way of approaching this.

    You should figure out how many records / partitions in parallel one instance of your application can handle optimally, through load / performance tests.

    Let's say one instance can handle 10 threads / records in parallel optimally. Now if you scale out your app to 50 instances, in your approach, each instance will get one partition, and each instance will be performing below its capacity, wasting resources.

    Now consider the opposite - only one instance is left, and it spawns 50 threads to consume from all partitions in parallel. The app's performance will be severally degraded, it might become unresponsive or even crash.

    So, in this hypotethical scenario, what you might want to do is, for example, start with one or two instances handling all partitions with 10 threads each, and have it scale to up to 5 instances if there's consumer lag, so that each partition has a dedicated thread processing it.

    Again, the actual figures should be determined through load / performance testing.