Skip to content

Commit da3b5e7

Browse files
authored
MINOR: Document connections.max.idle.ms dependency on max.poll.interval.ms for Classic consumer (#22752)
In the Classic consumer, `connections.max.idle.ms` can cause the coordinator connection to be reaped during a long rebalance if `max.poll.interval.ms` is higher than it. When this happens, in-flight `JoinGroup` requests are cancelled and the group cycles through connection reaping, which prolongs or destabilizes the rebalance — particularly in large consumer groups where the coordinator waits longer for all members to rejoin. Reviewers: Chia-Ping Tsai <chia7712@gmail.com>
1 parent e9b8bde commit da3b5e7

3 files changed

Lines changed: 42 additions & 2 deletions

File tree

clients/src/main/java/org/apache/kafka/clients/CommonClientConfigs.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,13 +196,19 @@ public class CommonClientConfigs {
196196
+ "For consumers using a non-null <code>group.instance.id</code> which reach this timeout, partitions will not be immediately reassigned. "
197197
+ "Instead, the consumer will stop sending heartbeats and partitions will be reassigned "
198198
+ "after expiration of the session timeout (defined by the client config <code>session.timeout.ms</code> if using the Classic rebalance protocol, or by the broker config <code>group.consumer.session.timeout.ms</code> if using the Consumer protocol). "
199-
+ "This mirrors the behavior of a static consumer which has shutdown.";
199+
+ "This mirrors the behavior of a static consumer which has shutdown. "
200+
+ "In the Classic consumer, <code>connections.max.idle.ms</code> should be set to a value greater than or equal to this timeout "
201+
+ "to avoid closing the connection to the group coordinator during an ongoing rebalance. "
202+
+ "This is particularly important in large groups, where a rebalance may take longer to complete "
203+
+ "while the coordinator waits for all members to rejoin.";
200204

201205
public static final String REBALANCE_TIMEOUT_MS_CONFIG = "rebalance.timeout.ms";
202206
public static final String REBALANCE_TIMEOUT_MS_DOC = "The maximum allowed time for each worker to join the group "
203207
+ "once a rebalance has begun. This is basically a limit on the amount of time needed for all tasks to "
204208
+ "flush any pending data and commit offsets. If the timeout is exceeded, then the worker will be removed "
205-
+ "from the group, which will cause offset commit failures.";
209+
+ "from the group, which will cause offset commit failures. "
210+
+ "<code>connections.max.idle.ms</code> should be set to a value greater than or equal to this timeout "
211+
+ "to avoid closing the connection to the group coordinator during an ongoing rebalance.";
206212

207213
public static final String SESSION_TIMEOUT_MS_CONFIG = "session.timeout.ms";
208214
public static final String SESSION_TIMEOUT_MS_DOC = "The timeout used to detect client failures when using "

clients/src/main/java/org/apache/kafka/clients/consumer/ConsumerConfig.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@
3838
import org.apache.kafka.common.serialization.Deserializer;
3939
import org.apache.kafka.common.utils.Utils;
4040

41+
import org.slf4j.Logger;
42+
import org.slf4j.LoggerFactory;
43+
4144
import java.util.ArrayList;
4245
import java.util.HashMap;
4346
import java.util.List;
@@ -60,6 +63,7 @@
6063
*/
6164
@InterfaceAudience.Public
6265
public class ConsumerConfig extends AbstractConfig {
66+
private static final Logger log = LoggerFactory.getLogger(ConsumerConfig.class);
6367
private static final ConfigDef CONFIG;
6468

6569
// a list contains all the assignor names that only assign subscribed topics to consumer. Should be updated when new assignor added.
@@ -724,9 +728,26 @@ protected Map<String, Object> postProcessParsedConfig(final Map<String, Object>
724728
maybeOverrideClientId(refinedConfigs);
725729
maybeOverrideEnableAutoCommit(refinedConfigs);
726730
checkUnsupportedConfigsPostProcess();
731+
warnIfConnectionsMaxIdleMsLowerThanMaxPollIntervalMs();
727732
return refinedConfigs;
728733
}
729734

735+
private void warnIfConnectionsMaxIdleMsLowerThanMaxPollIntervalMs() {
736+
String groupProtocol = getString(GROUP_PROTOCOL_CONFIG);
737+
if (!GroupProtocol.CLASSIC.name().equalsIgnoreCase(groupProtocol)) {
738+
return;
739+
}
740+
long connectionsMaxIdleMs = getLong(CONNECTIONS_MAX_IDLE_MS_CONFIG);
741+
int maxPollIntervalMs = getInt(MAX_POLL_INTERVAL_MS_CONFIG);
742+
if (connectionsMaxIdleMs >= 0 && connectionsMaxIdleMs < maxPollIntervalMs) {
743+
log.warn("Configuration '{}' with value '{}' is lower than configuration '{}' with value '{}'. " +
744+
"This may cause the connection to the group coordinator to be closed during an ongoing rebalance, " +
745+
"which can prolong or disrupt group rejoin.",
746+
CONNECTIONS_MAX_IDLE_MS_CONFIG, connectionsMaxIdleMs,
747+
MAX_POLL_INTERVAL_MS_CONFIG, maxPollIntervalMs);
748+
}
749+
}
750+
730751
private void maybeOverrideClientId(Map<String, Object> configs) {
731752
final String clientId = this.getString(CLIENT_ID_CONFIG);
732753
if (clientId == null || clientId.isEmpty()) {

connect/runtime/src/main/java/org/apache/kafka/connect/runtime/distributed/DistributedConfig.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,9 +598,22 @@ public String groupId() {
598598
@Override
599599
protected Map<String, Object> postProcessParsedConfig(final Map<String, Object> parsedValues) {
600600
CommonClientConfigs.warnDisablingExponentialBackoff(this);
601+
warnIfConnectionsMaxIdleMsLowerThanRebalanceTimeoutMs();
601602
return super.postProcessParsedConfig(parsedValues);
602603
}
603604

605+
private void warnIfConnectionsMaxIdleMsLowerThanRebalanceTimeoutMs() {
606+
long connectionsMaxIdleMs = getLong(CommonClientConfigs.CONNECTIONS_MAX_IDLE_MS_CONFIG);
607+
int rebalanceTimeoutMs = getInt(REBALANCE_TIMEOUT_MS_CONFIG);
608+
if (connectionsMaxIdleMs >= 0 && connectionsMaxIdleMs < rebalanceTimeoutMs) {
609+
log.warn("Configuration '{}' with value '{}' is lower than configuration '{}' with value '{}'. " +
610+
"This may cause the connection to the group coordinator to be closed during an ongoing rebalance, " +
611+
"which can prolong or disrupt group rejoin.",
612+
CommonClientConfigs.CONNECTIONS_MAX_IDLE_MS_CONFIG, connectionsMaxIdleMs,
613+
REBALANCE_TIMEOUT_MS_CONFIG, rebalanceTimeoutMs);
614+
}
615+
}
616+
604617
public DistributedConfig(Map<String, String> props) {
605618
this(Crypto.SYSTEM, props);
606619
}

0 commit comments

Comments
 (0)