You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@iceberg.apache.org by "vbhanuchander-lang (via GitHub)" <gi...@apache.org> on 2026/08/13 01:00:15 UTC
Re: [I] Kafka Connect: `cg-control` consumer group fails to stabilize on idle/low-volume topics after PR #14395 [iceberg]
vbhanuchander-lang commented on issue #17193:
URL: https://github.com/apache/iceberg/issues/17193#issuecomment-5274641634
I looked into this because the symptom is corroborated (#11818 reports the same "constant hanging
lag for low-volume topics"), but I do not think the stated mechanism can be what is happening.
Four things in the chain do not match the code. I am posting them because they change what needs
fixing, not to argue the bug away.
**1. #14395 did not remove a `cg-control` readiness check.** The check it removed was on
`config.connectGroupId()` — the *Connect* consumer group for the data topic — inside
`CommitterImpl.hasLeaderPartition`, and its purpose was coordinator **leader election** (deciding
which task owns the first partition):
```java
- if (groupDesc.state() == ConsumerGroupState.STABLE) {
- Collection<MemberDescription> members = groupDesc.members();
- if (containsFirstPartition(members, currentAssignedPartitions)) { ... }
- }
```
It never inspected the control group, so it cannot have been "ensuring the Worker's `cg-control`
consumer had joined".
**2. `put()` is still called when the data topic is idle.** Step 3 assumes the control consumer's
`poll()` is not called during the block. It is: in `WorkerSinkTask.poll()`, `deliverMessages()` —
and therefore `task.put(...)` — is invoked **unconditionally** after `convertMessages(msgs)`, with
no non-empty guard:
```java
convertMessages(msgs);
deliverMessages(); // -> task.put(new ArrayList<>(messageBatch)), even when empty
```
So `Channel.consumeAvailable` still runs on every Connect poll cycle on an idle topic.
**3. The 60s figure is `offset.flush.interval.ms`, not `max.poll.interval.ms`.**
`WorkerSinkTask.iteration()` polls with the time remaining until the next offset commit:
```java
long timeoutMs = Math.max(nextCommit - now, 0);
poll(timeoutMs);
```
`nextCommit` advances by `OFFSET_COMMIT_INTERVAL_MS_CONFIG` (`offset.flush.interval.ms`), whose
default is `60000L` in `WorkerConfig`. `max.poll.interval.ms` defaults to **300000**, not 60000
(`ConsumerConfig`, line 607). So the idle gap between `put()` calls is ~60s and bounded by a Connect
worker setting.
**4. A 60s gap between polls does not trip `session.timeout.ms`.** Since KIP-62 the consumer
heartbeats from a background thread, so `session.timeout.ms` (default 45000, confirmed in
`ConsumerConfig`) covers heartbeat loss, not time between `poll()` calls. The config that evicts a
member for not polling is `max.poll.interval.ms` — 300s here, which a 60s gap does not breach. That
is also why raising `heartbeat.interval.ms`, as suggested, would not be the lever even if the timing
were as described.
**What I could not explain, and what would pin it down**
The Worker's control group is created per worker instance as
`config.controlGroupIdPrefix() + UUID.randomUUID()` (`Worker.java:53`), i.e. a fresh
**single-member** group named `cg-control-<uuid>`. A single-member group that owns its own group id
reaching a non-STABLE state indefinitely is genuinely odd, and the `UnknownMemberIdException` you
saw is real evidence of *something*, so I would rather find the actual cause than hand-wave.
Two things would settle it:
1. The exact group id in the `UnknownMemberIdException` — is it `cg-control-<uuid>`, the
`<connectGroupId>-coord` group the Coordinator uses (`Coordinator.java:97`), or the Connect group
itself? These are three different groups and the fix differs for each.
2. Whether a fresh `cg-control-<uuid>` group is created on every task restart. If restarts are
frequent, abandoned single-member groups accumulate, and it is worth checking whether the group
being described as "not STABLE" is a previous incarnation rather than the live one.
If the real problem turns out to be that the coordinator can now start a commit cycle before workers
have joined — which is a plausible consequence of #14395, just not via `cg-control` liveness — then
the fix belongs in the leader-election/commit-start path, and I am happy to work on it. But I did
not want to write a patch against a mechanism I had just shown does not hold.
*(Config defaults and the `WorkerSinkTask` behaviour above were read from the Kafka 3.9 sources,
matching the 3.9.2 runtime in your environment section.)*
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: issues-unsubscribe@iceberg.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@iceberg.apache.org
For additional commands, e-mail: issues-help@iceberg.apache.org