Optimizing Consumer Rebalancing

1. Understanding Rebalance Protocol

Aspect Description Detail
Trigger Member join/leave Reassign
Eager Stop-the-world Legacy
Cooperative Incremental, no stop Preferred

Example: Cooperative assignor

props.put("partition.assignment.strategy",
  "org.apache.kafka.clients.consumer.CooperativeStickyAssignor");

2. Configuring Session Timeout

Config Description Default
session.timeout.ms Heartbeat deadline 45000
Too Low False rebalances Flapping
Bound Within broker min/max group.* configs

Example: Session timeout

props.put("session.timeout.ms", 30000);

3. Setting Heartbeat Interval

Config Description Default
heartbeat.interval.ms Heartbeat frequency 3000
Rule ≤ 1/3 session.timeout Safe margin
Background Separate thread Independent

Example: Heartbeat interval

props.put("heartbeat.interval.ms", 10000);

4. Configuring Max Poll Interval

Config Description Default
max.poll.interval.ms Max between polls 300000
Exceeded Consumer kicked out Rebalance
Slow Processing Increase or batch less Avoid eviction

Example: Max poll interval

props.put("max.poll.interval.ms", 600000);

5. Using Cooperative Rebalancing

Aspect Description Detail
Incremental Only moved partitions revoked Less disruption
Keep Processing Unaffected partitions continue No full stop
Default Modern clients use it Recommended

Example: Enable cooperative

props.put(ConsumerConfig.PARTITION_ASSIGNMENT_STRATEGY_CONFIG,
  List.of(CooperativeStickyAssignor.class));

6. Implementing Static Membership

Config Description Detail
group.instance.id Stable member identity Persistent
Restart No rebalance within timeout Rejoins same
Use Rolling restarts Stable infra

Example: Static membership

props.put("group.instance.id", "consumer-pod-1");

7. Minimizing Rebalance Overhead

Technique Description Benefit
Static + Cooperative Combine both Minimal moves
Tune Timeouts Avoid false triggers Stability
Graceful Shutdown close() leaves cleanly Fast handoff

Example: Graceful leave

Runtime.getRuntime().addShutdownHook(
  new Thread(consumer::wakeup));

8. Using Incremental Rebalancing

Aspect Description Detail
Two Phases Revoke then assign Cooperative
Minimal Revoke Only reassigned ones Keep rest
Scaling Smooth add/remove Less impact

Example: Partitions lost callback

public void onPartitionsLost(Collection<TopicPartition> p){
  // cooperative: cleanup without committing
}

9. Handling Rebalance Listeners

Callback Description Use
onPartitionsRevoked Before reassignment Commit offsets
onPartitionsAssigned After assignment Init state
onPartitionsLost Unexpected loss Cleanup

Example: Subscribe with listener

consumer.subscribe(List.of("orders"), new ConsumerRebalanceListener(){
  public void onPartitionsRevoked(Collection<TopicPartition> p){ consumer.commitSync(); }
  public void onPartitionsAssigned(Collection<TopicPartition> p){}
});

10. Monitoring Rebalance Latency

Metric Description Watch
rebalance-latency-avg Time to rebalance Lower better
rebalance-rate Frequency Should be low
last-rebalance-seconds-ago Recency Stability

Example: Rebalance JMX

kafka.consumer:type=consumer-coordinator-metrics,client-id=app
  -> rebalance-latency-avg, rebalance-rate-per-hour