Representative interview topic

System design interview: migrating a Kafka group to cooperative rebalancing

System designHard
Offer.cc Editorial TeamPublished Updated

Question

A high-throughput Kafka consumer group pauses every partition during scale changes. Design a migration from eager rebalance to CooperativeStickyAssignor that avoids message loss, bounds duplicates during rollout, and recovers from member crashes or configuration rollback.

Prompt and context

This question tests distributed ownership transfer rather than memorizing a Kafka setting. Eager rebalancing revokes all partitions first, while cooperative rebalancing lets members retain partitions that do not need to move and revokes only the migration set. A complete answer covers member versions, assignor protocol, offset commits, failure windows, and telemetry.

What the interviewer evaluates

  • Whether you explain the revoke and handoff differences between eager and cooperative protocols.
  • Whether you plan a compatible rolling order instead of assuming one member can switch alone.
  • Whether ownership, offsets, in-flight work, and commit timing line up.
  • Whether crashes, timeouts, duplicates, rollback, and capacity limits are handled.

Clarifying questions

Confirm client versions, the current assignor list, static membership, per-message processing time, acceptable duplicate window, and rebalance latency budget. Ask whether processing is idempotent, whether the sink supports deduplication, and whether rollout can be staged and rolled back. Establish peak scaling, partition count, and alert thresholds.

30-second answer outline

First upgrade every member to a version that supports the cooperative protocol while retaining a compatible assignor list. Once protocol support is uniform, roll out CooperativeStickyAssignor as the preferred strategy and remove the old one. Each rebalance revokes only partitions that move; the consumer stops fetching them, commits completed offsets, and the new owner resumes from committed offsets. Monitor rebalance count, revoked partitions, processing latency, and duplicates. A crash relies on session timeout and offset recovery; rollback restores the old compatible configuration through another rolling change.

Step-by-step solution

1. Define the protocol compatibility matrix

The assignor is negotiated at group level, so changing one instance is insufficient. Upgrade all clients to a version that understands cooperative rebalancing before relying on it. Keep a compatibility entry during the first phase, then prefer cooperative and remove the old strategy after the group is ready:

properties
partition.assignment.strategy=\
org.apache.kafka.clients.consumer.CooperativeStickyAssignor,\
org.apache.kafka.clients.consumer.RangeAssignor

Validate the group’s negotiated protocol and assignment after each phase; checking a configuration file alone is not evidence that the running group switched.

2. Design partition revoke and handoff

The cooperative revoke set contains only partitions that must move. On revoke, stop fetching those partitions, finish or abandon the current safe batch, and commit completed offsets. Continue processing partitions that were not revoked. The new owner starts from committed offsets, so business idempotency keys or sink deduplication handle duplicates.

3. Align offsets with in-flight work

Commit after the business side effect, never before it. If revoke arrives during a batch, set a stop flag and finish at a safe point; on deadline, stop fetching and record the unfinished batch. Asynchronous processing needs per-partition sequence tracking so only a contiguous completed prefix is committed.

4. Plan the rolling rollout

A rollout controller restarts small batches of members and waits for group stability and lag recovery after each batch. Record a baseline, upgrade clients, observe the protocol, switch the preferred assignor, rehearse scale changes, and only then increase the batch size. Pause on rebalance storms or latency breaches instead of changing session timeout and max poll interval at the same time.

5. Design crash and rollback behavior

After a member crash, the coordinator reallocates its partitions when the session timeout expires. The replacement resumes from the last committed offset, so side effects before the crash may repeat. Rollback restores the old assignor in the compatibility list and uses the same rolling order; do not forcibly remove a still-running new member. Record generation, member ID, revoke sets, and commit failures for race diagnosis.

6. Add capacity and telemetry guardrails

Track rebalance frequency and duration, revoked partition count, consumer lag, poll interval, commit latency, duplicate rate, and unassigned members. Test simultaneous restarts, hot partitions, processing beyond max.poll.interval, network jitter, and partition counts close to member counts. If capacity is short, reduce rollout batch size or add consumers before continuing.

Model high-quality answer

I would verify that every client supports cooperative assignment, then use a two-phase rolling configuration: retain a compatible assignor while upgrading versions, and only afterward prefer CooperativeStickyAssignor and remove the old strategy. Revoke callbacks stop only partitions that are moving, finish a safe point, and commit a contiguous offset; retained partitions continue. New owners resume from committed offsets, with idempotency handling duplicates. A small-batch controller watches rebalances, lag, poll intervals, commit failures, and duplicate rate. Crashes recover through session timeout and offsets, while rollback follows the same compatible rolling order instead of forcibly deleting live members.

Common mistakes

  • Changing one consumer and ignoring group-level assignor negotiation.
  • Treating cooperative rebalancing as zero pause even though moving partitions still hand off.
  • Committing offsets before the business side effect.
  • Fetching after revoke or committing non-contiguous asynchronous results.
  • Changing several timeout settings together and losing causal evidence.
  • Watching lag only while ignoring rebalance frequency, revoke sets, and duplicates.

Follow-up questions

Does cooperative rebalancing guarantee zero duplicates?

No. Crashes, commit retries, and revoke boundaries can repeat work. The goal is to reduce whole-group pauses and bound the duplicate window; sinks still need idempotency or deduplication.

Why must every member support cooperative assignment?

The assignor protocol is negotiated by the group. A member that cannot parse or execute cooperative semantics can make negotiation fail or force eager behavior, so compatible versions must be rolled out first.

What if processing exceeds max.poll.interval?

Use smaller batches, a controlled asynchronous pool, or a carefully reviewed parameter change while keeping poll calls timely. Simply increasing the timeout can delay failure detection and extend partition ownership.

How do you validate rollback safety?

Inject member crashes, network jitter, and commit failures in a staging group. Record generation, offsets, revoke sets, and deduplicated side effects. Verify that the old assignor stabilizes within the compatibility matrix without skipping uncommitted offsets.

Public sources

Related questions

Related interview tool

Use Solve for a system design answer

Clarify the requirements first, then move through scale, architecture, component choices, and trade-offs.

View the tool