mirror of https://github.com/apache/kafka.git
KAFKA-17081 Tweak GroupCoordinatorConfig: re-introduce local attributes and validation (#16524)
Reviewers: Chia-Ping Tsai <chia7712@gmail.com>
This commit is contained in:
parent
d45596a2a1
commit
a533e246e3
|
|
@ -1662,6 +1662,11 @@ public final class Utils {
|
|||
throw new IllegalArgumentException("requirement failed");
|
||||
}
|
||||
|
||||
public static void require(boolean requirement, String errorMessage) {
|
||||
if (!requirement)
|
||||
throw new IllegalArgumentException(errorMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge multiple {@link ConfigDef} into one
|
||||
* @param configDefs List of {@link ConfigDef}
|
||||
|
|
|
|||
|
|
@ -886,8 +886,7 @@ class KafkaConfig private(doLog: Boolean, val props: util.Map[_, _])
|
|||
" to prevent unnecessary socket timeouts")
|
||||
require(replicaFetchWaitMaxMs <= replicaLagTimeMaxMs, "replica.fetch.wait.max.ms should always be less than or equal to replica.lag.time.max.ms" +
|
||||
" to prevent frequent changes in ISR")
|
||||
require(groupCoordinatorConfig.offsetCommitRequiredAcks >= -1 && groupCoordinatorConfig.offsetCommitRequiredAcks <= groupCoordinatorConfig.offsetsTopicReplicationFactor,
|
||||
"offsets.commit.required.acks must be greater or equal -1 and less or equal to offsets.topic.replication.factor")
|
||||
|
||||
val advertisedBrokerListenerNames = effectiveAdvertisedBrokerListeners.map(_.listenerName).toSet
|
||||
|
||||
// validate KRaft-related configs
|
||||
|
|
@ -1071,27 +1070,6 @@ class KafkaConfig private(doLog: Boolean, val props: util.Map[_, _])
|
|||
require(classOf[KafkaPrincipalSerde].isAssignableFrom(principalBuilderClass),
|
||||
s"${BrokerSecurityConfigs.PRINCIPAL_BUILDER_CLASS_CONFIG} must implement KafkaPrincipalSerde")
|
||||
|
||||
// New group coordinator configs validation.
|
||||
require(groupCoordinatorConfig.consumerGroupMaxHeartbeatIntervalMs >= groupCoordinatorConfig.consumerGroupMinHeartbeatIntervalMs,
|
||||
s"${GroupCoordinatorConfig.CONSUMER_GROUP_MAX_HEARTBEAT_INTERVAL_MS_CONFIG} must be greater than or equals " +
|
||||
s"to ${GroupCoordinatorConfig.CONSUMER_GROUP_MIN_HEARTBEAT_INTERVAL_MS_CONFIG}")
|
||||
require(groupCoordinatorConfig.consumerGroupHeartbeatIntervalMs >= groupCoordinatorConfig.consumerGroupMinHeartbeatIntervalMs,
|
||||
s"${GroupCoordinatorConfig.CONSUMER_GROUP_HEARTBEAT_INTERVAL_MS_CONFIG} must be greater than or equals " +
|
||||
s"to ${GroupCoordinatorConfig.CONSUMER_GROUP_MIN_HEARTBEAT_INTERVAL_MS_CONFIG}")
|
||||
require(groupCoordinatorConfig.consumerGroupHeartbeatIntervalMs <= groupCoordinatorConfig.consumerGroupMaxHeartbeatIntervalMs,
|
||||
s"${GroupCoordinatorConfig.CONSUMER_GROUP_HEARTBEAT_INTERVAL_MS_CONFIG} must be less than or equals " +
|
||||
s"to ${GroupCoordinatorConfig.CONSUMER_GROUP_MAX_HEARTBEAT_INTERVAL_MS_CONFIG}")
|
||||
|
||||
require(groupCoordinatorConfig.consumerGroupMaxSessionTimeoutMs >= groupCoordinatorConfig.consumerGroupMinSessionTimeoutMs,
|
||||
s"${GroupCoordinatorConfig.CONSUMER_GROUP_MAX_SESSION_TIMEOUT_MS_CONFIG} must be greater than or equals " +
|
||||
s"to ${GroupCoordinatorConfig.CONSUMER_GROUP_MIN_SESSION_TIMEOUT_MS_CONFIG}")
|
||||
require(groupCoordinatorConfig.consumerGroupSessionTimeoutMs >= groupCoordinatorConfig.consumerGroupMinSessionTimeoutMs,
|
||||
s"${GroupCoordinatorConfig.CONSUMER_GROUP_SESSION_TIMEOUT_MS_CONFIG} must be greater than or equals " +
|
||||
s"to ${GroupCoordinatorConfig.CONSUMER_GROUP_MIN_SESSION_TIMEOUT_MS_CONFIG}")
|
||||
require(groupCoordinatorConfig.consumerGroupSessionTimeoutMs <= groupCoordinatorConfig.consumerGroupMaxSessionTimeoutMs,
|
||||
s"${GroupCoordinatorConfig.CONSUMER_GROUP_SESSION_TIMEOUT_MS_CONFIG} must be less than or equals " +
|
||||
s"to ${GroupCoordinatorConfig.CONSUMER_GROUP_MAX_SESSION_TIMEOUT_MS_CONFIG}")
|
||||
|
||||
require(shareGroupMaxHeartbeatIntervalMs >= shareGroupMinHeartbeatIntervalMs,
|
||||
s"${ShareGroupConfigs.SHARE_GROUP_MAX_HEARTBEAT_INTERVAL_MS_CONFIG} must be greater than or equals " +
|
||||
s"to ${ShareGroupConfigs.SHARE_GROUP_MIN_HEARTBEAT_INTERVAL_MS_CONFIG}")
|
||||
|
|
|
|||
|
|
@ -39,9 +39,13 @@ import static org.apache.kafka.common.config.ConfigDef.Type.LIST;
|
|||
import static org.apache.kafka.common.config.ConfigDef.Type.LONG;
|
||||
import static org.apache.kafka.common.config.ConfigDef.Type.SHORT;
|
||||
import static org.apache.kafka.common.config.ConfigDef.Type.STRING;
|
||||
import static org.apache.kafka.common.utils.Utils.require;
|
||||
|
||||
/**
|
||||
* The group coordinator configurations.
|
||||
* This configuration utilizes several local variables instead of calling AbstractConfig#get.... as all configs here
|
||||
* are static and non-dynamic, with some being accessed extremely frequently (e.g., offsets.commit.timeout.ms).
|
||||
* Using local variable is advantageous as it avoids the overhead of repeatedly looking up these configurations in AbstractConfig.
|
||||
*/
|
||||
public class GroupCoordinatorConfig {
|
||||
/** ********* Group coordinator configuration ***********/
|
||||
|
|
@ -213,17 +217,87 @@ public class GroupCoordinatorConfig {
|
|||
*/
|
||||
public static final int CLASSIC_GROUP_NEW_MEMBER_JOIN_TIMEOUT_MS = 5 * 60 * 1000;
|
||||
|
||||
private final AbstractConfig config;
|
||||
private final int numThreads;
|
||||
private final int appendLingerMs;
|
||||
private final int consumerGroupSessionTimeoutMs;
|
||||
private final int consumerGroupHeartbeatIntervalMs;
|
||||
private final int consumerGroupMaxSize;
|
||||
private final List<ConsumerGroupPartitionAssignor> consumerGroupAssignors;
|
||||
private final int offsetsTopicSegmentBytes;
|
||||
private final int offsetMetadataMaxSize;
|
||||
private final int classicGroupMaxSize;
|
||||
private final int classicGroupInitialRebalanceDelayMs;
|
||||
private final int classicGroupMinSessionTimeoutMs;
|
||||
private final int classicGroupMaxSessionTimeoutMs;
|
||||
private final long offsetsRetentionCheckIntervalMs;
|
||||
private final long offsetsRetentionMs;
|
||||
private final int offsetCommitTimeoutMs;
|
||||
private final ConsumerGroupMigrationPolicy consumerGroupMigrationPolicy;
|
||||
private final CompressionType offsetTopicCompressionType;
|
||||
private final int offsetsLoadBufferSize;
|
||||
private final int offsetsTopicPartitions;
|
||||
private final short offsetsTopicReplicationFactor;
|
||||
private final short offsetCommitRequiredAcks;
|
||||
private final int consumerGroupMinSessionTimeoutMs;
|
||||
private final int consumerGroupMaxSessionTimeoutMs;
|
||||
private final int consumerGroupMinHeartbeatIntervalMs;
|
||||
private final int consumerGroupMaxHeartbeatIntervalMs;
|
||||
|
||||
public GroupCoordinatorConfig(AbstractConfig config) {
|
||||
this.config = config;
|
||||
this.numThreads = config.getInt(GroupCoordinatorConfig.GROUP_COORDINATOR_NUM_THREADS_CONFIG);
|
||||
this.appendLingerMs = config.getInt(GroupCoordinatorConfig.GROUP_COORDINATOR_APPEND_LINGER_MS_CONFIG);
|
||||
this.consumerGroupSessionTimeoutMs = config.getInt(GroupCoordinatorConfig.CONSUMER_GROUP_SESSION_TIMEOUT_MS_CONFIG);
|
||||
this.consumerGroupHeartbeatIntervalMs = config.getInt(GroupCoordinatorConfig.CONSUMER_GROUP_HEARTBEAT_INTERVAL_MS_CONFIG);
|
||||
this.consumerGroupMaxSize = config.getInt(GroupCoordinatorConfig.CONSUMER_GROUP_MAX_SIZE_CONFIG);
|
||||
this.consumerGroupAssignors = Collections.unmodifiableList(
|
||||
config.getConfiguredInstances(GroupCoordinatorConfig.CONSUMER_GROUP_ASSIGNORS_CONFIG, ConsumerGroupPartitionAssignor.class));
|
||||
this.offsetsTopicSegmentBytes = config.getInt(GroupCoordinatorConfig.OFFSETS_TOPIC_SEGMENT_BYTES_CONFIG);
|
||||
this.offsetMetadataMaxSize = config.getInt(GroupCoordinatorConfig.OFFSET_METADATA_MAX_SIZE_CONFIG);
|
||||
this.classicGroupMaxSize = config.getInt(GroupCoordinatorConfig.GROUP_MAX_SIZE_CONFIG);
|
||||
this.classicGroupInitialRebalanceDelayMs = config.getInt(GroupCoordinatorConfig.GROUP_INITIAL_REBALANCE_DELAY_MS_CONFIG);
|
||||
this.classicGroupMinSessionTimeoutMs = config.getInt(GroupCoordinatorConfig.GROUP_MIN_SESSION_TIMEOUT_MS_CONFIG);
|
||||
this.classicGroupMaxSessionTimeoutMs = config.getInt(GroupCoordinatorConfig.GROUP_MAX_SESSION_TIMEOUT_MS_CONFIG);
|
||||
this.offsetsRetentionCheckIntervalMs = config.getLong(GroupCoordinatorConfig.OFFSETS_RETENTION_CHECK_INTERVAL_MS_CONFIG);
|
||||
this.offsetsRetentionMs = config.getInt(GroupCoordinatorConfig.OFFSETS_RETENTION_MINUTES_CONFIG) * 60L * 1000L;
|
||||
this.offsetCommitTimeoutMs = config.getInt(GroupCoordinatorConfig.OFFSET_COMMIT_TIMEOUT_MS_CONFIG);
|
||||
this.consumerGroupMigrationPolicy = ConsumerGroupMigrationPolicy.parse(
|
||||
config.getString(GroupCoordinatorConfig.CONSUMER_GROUP_MIGRATION_POLICY_CONFIG));
|
||||
this.offsetTopicCompressionType = Optional.ofNullable(config.getInt(GroupCoordinatorConfig.OFFSETS_TOPIC_COMPRESSION_CODEC_CONFIG))
|
||||
.map(CompressionType::forId)
|
||||
.orElse(null);
|
||||
this.offsetsLoadBufferSize = config.getInt(GroupCoordinatorConfig.OFFSETS_LOAD_BUFFER_SIZE_CONFIG);
|
||||
this.offsetsTopicPartitions = config.getInt(GroupCoordinatorConfig.OFFSETS_TOPIC_PARTITIONS_CONFIG);
|
||||
this.offsetsTopicReplicationFactor = config.getShort(GroupCoordinatorConfig.OFFSETS_TOPIC_REPLICATION_FACTOR_CONFIG);
|
||||
this.offsetCommitRequiredAcks = config.getShort(GroupCoordinatorConfig.OFFSET_COMMIT_REQUIRED_ACKS_CONFIG);
|
||||
this.consumerGroupMinSessionTimeoutMs = config.getInt(GroupCoordinatorConfig.CONSUMER_GROUP_MIN_SESSION_TIMEOUT_MS_CONFIG);
|
||||
this.consumerGroupMaxSessionTimeoutMs = config.getInt(GroupCoordinatorConfig.CONSUMER_GROUP_MAX_SESSION_TIMEOUT_MS_CONFIG);
|
||||
this.consumerGroupMinHeartbeatIntervalMs = config.getInt(GroupCoordinatorConfig.CONSUMER_GROUP_MIN_HEARTBEAT_INTERVAL_MS_CONFIG);
|
||||
this.consumerGroupMaxHeartbeatIntervalMs = config.getInt(GroupCoordinatorConfig.CONSUMER_GROUP_MAX_HEARTBEAT_INTERVAL_MS_CONFIG);
|
||||
|
||||
require(offsetCommitRequiredAcks >= -1 && offsetCommitRequiredAcks <= offsetsTopicReplicationFactor,
|
||||
String.format("%s must be greater or equal to -1 and less or equal to %s", OFFSET_COMMIT_REQUIRED_ACKS_CONFIG, OFFSETS_TOPIC_REPLICATION_FACTOR_CONFIG));
|
||||
|
||||
// New group coordinator configs validation.
|
||||
require(consumerGroupMaxHeartbeatIntervalMs >= consumerGroupMinHeartbeatIntervalMs,
|
||||
String.format("%s must be greater than or equals to %s", CONSUMER_GROUP_MAX_HEARTBEAT_INTERVAL_MS_CONFIG, CONSUMER_GROUP_MIN_HEARTBEAT_INTERVAL_MS_CONFIG));
|
||||
require(consumerGroupHeartbeatIntervalMs >= consumerGroupMinHeartbeatIntervalMs,
|
||||
String.format("%s must be greater than or equals to %s", CONSUMER_GROUP_HEARTBEAT_INTERVAL_MS_CONFIG, CONSUMER_GROUP_MIN_HEARTBEAT_INTERVAL_MS_CONFIG));
|
||||
require(consumerGroupHeartbeatIntervalMs <= consumerGroupMaxHeartbeatIntervalMs,
|
||||
String.format("%s must be less than or equals to %s", CONSUMER_GROUP_HEARTBEAT_INTERVAL_MS_CONFIG, CONSUMER_GROUP_MAX_HEARTBEAT_INTERVAL_MS_CONFIG));
|
||||
|
||||
require(consumerGroupMaxSessionTimeoutMs >= consumerGroupMinSessionTimeoutMs,
|
||||
String.format("%s must be greater than or equals to %s", CONSUMER_GROUP_MAX_SESSION_TIMEOUT_MS_CONFIG, CONSUMER_GROUP_MIN_SESSION_TIMEOUT_MS_CONFIG));
|
||||
require(consumerGroupSessionTimeoutMs >= consumerGroupMinSessionTimeoutMs,
|
||||
String.format("%s must be greater than or equals to %s", CONSUMER_GROUP_SESSION_TIMEOUT_MS_CONFIG, CONSUMER_GROUP_MIN_SESSION_TIMEOUT_MS_CONFIG));
|
||||
require(consumerGroupSessionTimeoutMs <= consumerGroupMaxSessionTimeoutMs,
|
||||
String.format("%s must be less than or equals to %s", CONSUMER_GROUP_SESSION_TIMEOUT_MS_CONFIG, CONSUMER_GROUP_MAX_SESSION_TIMEOUT_MS_CONFIG));
|
||||
}
|
||||
|
||||
/**
|
||||
* The number of threads or event loops running.
|
||||
*/
|
||||
public int numThreads() {
|
||||
return config.getInt(GroupCoordinatorConfig.GROUP_COORDINATOR_NUM_THREADS_CONFIG);
|
||||
return numThreads;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -231,35 +305,35 @@ public class GroupCoordinatorConfig {
|
|||
* accumulate before flushing them to disk.
|
||||
*/
|
||||
public int appendLingerMs() {
|
||||
return config.getInt(GroupCoordinatorConfig.GROUP_COORDINATOR_APPEND_LINGER_MS_CONFIG);
|
||||
return appendLingerMs;
|
||||
}
|
||||
|
||||
/**
|
||||
* The consumer group session timeout in milliseconds.
|
||||
*/
|
||||
public int consumerGroupSessionTimeoutMs() {
|
||||
return config.getInt(GroupCoordinatorConfig.CONSUMER_GROUP_SESSION_TIMEOUT_MS_CONFIG);
|
||||
return consumerGroupSessionTimeoutMs;
|
||||
}
|
||||
|
||||
/**
|
||||
* The consumer group heartbeat interval in milliseconds.
|
||||
*/
|
||||
public int consumerGroupHeartbeatIntervalMs() {
|
||||
return config.getInt(GroupCoordinatorConfig.CONSUMER_GROUP_HEARTBEAT_INTERVAL_MS_CONFIG);
|
||||
return consumerGroupHeartbeatIntervalMs;
|
||||
}
|
||||
|
||||
/**
|
||||
* The consumer group maximum size.
|
||||
*/
|
||||
public int consumerGroupMaxSize() {
|
||||
return config.getInt(GroupCoordinatorConfig.CONSUMER_GROUP_MAX_SIZE_CONFIG);
|
||||
return consumerGroupMaxSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* The consumer group assignors.
|
||||
*/
|
||||
public List<ConsumerGroupPartitionAssignor> consumerGroupAssignors() {
|
||||
return config.getConfiguredInstances(GroupCoordinatorConfig.CONSUMER_GROUP_ASSIGNORS_CONFIG, ConsumerGroupPartitionAssignor.class);
|
||||
return consumerGroupAssignors;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -267,28 +341,28 @@ public class GroupCoordinatorConfig {
|
|||
* log compaction and faster offset loads.
|
||||
*/
|
||||
public int offsetsTopicSegmentBytes() {
|
||||
return config.getInt(GroupCoordinatorConfig.OFFSETS_TOPIC_SEGMENT_BYTES_CONFIG);
|
||||
return offsetsTopicSegmentBytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* The maximum size for a metadata entry associated with an offset commit.
|
||||
*/
|
||||
public int offsetMetadataMaxSize() {
|
||||
return config.getInt(GroupCoordinatorConfig.OFFSET_METADATA_MAX_SIZE_CONFIG);
|
||||
return offsetMetadataMaxSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* The classic group maximum size.
|
||||
*/
|
||||
public int classicGroupMaxSize() {
|
||||
return config.getInt(GroupCoordinatorConfig.GROUP_MAX_SIZE_CONFIG);
|
||||
return classicGroupMaxSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* The delay in milliseconds introduced for the first rebalance of a classic group.
|
||||
*/
|
||||
public int classicGroupInitialRebalanceDelayMs() {
|
||||
return config.getInt(GroupCoordinatorConfig.GROUP_INITIAL_REBALANCE_DELAY_MS_CONFIG);
|
||||
return classicGroupInitialRebalanceDelayMs;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -302,21 +376,21 @@ public class GroupCoordinatorConfig {
|
|||
* The classic group minimum session timeout.
|
||||
*/
|
||||
public int classicGroupMinSessionTimeoutMs() {
|
||||
return config.getInt(GroupCoordinatorConfig.GROUP_MIN_SESSION_TIMEOUT_MS_CONFIG);
|
||||
return classicGroupMinSessionTimeoutMs;
|
||||
}
|
||||
|
||||
/**
|
||||
* The classic group maximum session timeout.
|
||||
*/
|
||||
public int classicGroupMaxSessionTimeoutMs() {
|
||||
return config.getInt(GroupCoordinatorConfig.GROUP_MAX_SESSION_TIMEOUT_MS_CONFIG);
|
||||
return classicGroupMaxSessionTimeoutMs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Frequency at which to check for expired offsets.
|
||||
*/
|
||||
public long offsetsRetentionCheckIntervalMs() {
|
||||
return config.getLong(GroupCoordinatorConfig.OFFSETS_RETENTION_CHECK_INTERVAL_MS_CONFIG);
|
||||
return offsetsRetentionCheckIntervalMs;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -334,7 +408,7 @@ public class GroupCoordinatorConfig {
|
|||
* committed offsets for that topic will also be deleted without extra retention period.
|
||||
*/
|
||||
public long offsetsRetentionMs() {
|
||||
return config.getInt(GroupCoordinatorConfig.OFFSETS_RETENTION_MINUTES_CONFIG) * 60L * 1000L;
|
||||
return offsetsRetentionMs;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -342,24 +416,21 @@ public class GroupCoordinatorConfig {
|
|||
* or this timeout is reached
|
||||
*/
|
||||
public int offsetCommitTimeoutMs() {
|
||||
return config.getInt(GroupCoordinatorConfig.OFFSET_COMMIT_TIMEOUT_MS_CONFIG);
|
||||
return offsetCommitTimeoutMs;
|
||||
}
|
||||
|
||||
/**
|
||||
* The config indicating whether group protocol upgrade/downgrade are allowed.
|
||||
*/
|
||||
public ConsumerGroupMigrationPolicy consumerGroupMigrationPolicy() {
|
||||
return ConsumerGroupMigrationPolicy.parse(
|
||||
config.getString(GroupCoordinatorConfig.CONSUMER_GROUP_MIGRATION_POLICY_CONFIG));
|
||||
return consumerGroupMigrationPolicy;
|
||||
}
|
||||
|
||||
/**
|
||||
* The compression type used to compress records in batches.
|
||||
*/
|
||||
public CompressionType offsetTopicCompressionType() {
|
||||
return Optional.ofNullable(config.getInt(GroupCoordinatorConfig.OFFSETS_TOPIC_COMPRESSION_CODEC_CONFIG))
|
||||
.map(CompressionType::forId)
|
||||
.orElse(null);
|
||||
return offsetTopicCompressionType;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -367,14 +438,14 @@ public class GroupCoordinatorConfig {
|
|||
* the cache (soft-limit, overridden if records are too large).
|
||||
*/
|
||||
public int offsetsLoadBufferSize() {
|
||||
return config.getInt(GroupCoordinatorConfig.OFFSETS_LOAD_BUFFER_SIZE_CONFIG);
|
||||
return offsetsLoadBufferSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* The number of partitions for the offset commit topic (should not change after deployment).
|
||||
*/
|
||||
public int offsetsTopicPartitions() {
|
||||
return config.getInt(GroupCoordinatorConfig.OFFSETS_TOPIC_PARTITIONS_CONFIG);
|
||||
return offsetsTopicPartitions;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -382,7 +453,7 @@ public class GroupCoordinatorConfig {
|
|||
* Internal topic creation will fail until the cluster size meets this replication factor requirement.
|
||||
*/
|
||||
public short offsetsTopicReplicationFactor() {
|
||||
return config.getShort(GroupCoordinatorConfig.OFFSETS_TOPIC_REPLICATION_FACTOR_CONFIG);
|
||||
return offsetsTopicReplicationFactor;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -391,34 +462,34 @@ public class GroupCoordinatorConfig {
|
|||
*/
|
||||
@Deprecated // since 3.8
|
||||
public short offsetCommitRequiredAcks() {
|
||||
return config.getShort(GroupCoordinatorConfig.OFFSET_COMMIT_REQUIRED_ACKS_CONFIG);
|
||||
return offsetCommitRequiredAcks;
|
||||
}
|
||||
|
||||
/**
|
||||
* The minimum allowed session timeout for registered consumers.
|
||||
*/
|
||||
public int consumerGroupMinSessionTimeoutMs() {
|
||||
return config.getInt(GroupCoordinatorConfig.CONSUMER_GROUP_MIN_SESSION_TIMEOUT_MS_CONFIG);
|
||||
return consumerGroupMinSessionTimeoutMs;
|
||||
}
|
||||
|
||||
/**
|
||||
* The maximum allowed session timeout for registered consumers.
|
||||
*/
|
||||
public int consumerGroupMaxSessionTimeoutMs() {
|
||||
return config.getInt(GroupCoordinatorConfig.CONSUMER_GROUP_MAX_SESSION_TIMEOUT_MS_CONFIG);
|
||||
return consumerGroupMaxSessionTimeoutMs;
|
||||
}
|
||||
|
||||
/**
|
||||
* The minimum heartbeat interval for registered consumers.
|
||||
*/
|
||||
public int consumerGroupMinHeartbeatIntervalMs() {
|
||||
return config.getInt(GroupCoordinatorConfig.CONSUMER_GROUP_MIN_HEARTBEAT_INTERVAL_MS_CONFIG);
|
||||
return consumerGroupMinHeartbeatIntervalMs;
|
||||
}
|
||||
|
||||
/**
|
||||
* The maximum heartbeat interval for registered consumers.
|
||||
*/
|
||||
public int consumerGroupMaxHeartbeatIntervalMs() {
|
||||
return config.getInt(GroupCoordinatorConfig.CONSUMER_GROUP_MAX_HEARTBEAT_INTERVAL_MS_CONFIG);
|
||||
return consumerGroupMaxHeartbeatIntervalMs;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,8 +16,10 @@
|
|||
*/
|
||||
package org.apache.kafka.coordinator.group;
|
||||
|
||||
import org.apache.kafka.common.KafkaException;
|
||||
import org.apache.kafka.common.config.AbstractConfig;
|
||||
import org.apache.kafka.common.config.ConfigDef;
|
||||
import org.apache.kafka.common.config.ConfigException;
|
||||
import org.apache.kafka.common.record.CompressionType;
|
||||
import org.apache.kafka.common.utils.Utils;
|
||||
import org.apache.kafka.coordinator.group.assignor.RangeAssignor;
|
||||
|
|
@ -32,6 +34,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public class GroupCoordinatorConfigTest {
|
||||
|
|
@ -46,8 +49,8 @@ public class GroupCoordinatorConfigTest {
|
|||
Map<String, Object> configs = new HashMap<>();
|
||||
configs.put(GroupCoordinatorConfig.GROUP_COORDINATOR_NUM_THREADS_CONFIG, 10);
|
||||
configs.put(GroupCoordinatorConfig.GROUP_COORDINATOR_APPEND_LINGER_MS_CONFIG, 10);
|
||||
configs.put(GroupCoordinatorConfig.CONSUMER_GROUP_SESSION_TIMEOUT_MS_CONFIG, 30);
|
||||
configs.put(GroupCoordinatorConfig.CONSUMER_GROUP_HEARTBEAT_INTERVAL_MS_CONFIG, 10);
|
||||
configs.put(GroupCoordinatorConfig.CONSUMER_GROUP_SESSION_TIMEOUT_MS_CONFIG, 555);
|
||||
configs.put(GroupCoordinatorConfig.CONSUMER_GROUP_HEARTBEAT_INTERVAL_MS_CONFIG, 200);
|
||||
configs.put(GroupCoordinatorConfig.CONSUMER_GROUP_MAX_SIZE_CONFIG, 55);
|
||||
configs.put(GroupCoordinatorConfig.CONSUMER_GROUP_ASSIGNORS_CONFIG, Collections.singletonList(RangeAssignor.class));
|
||||
configs.put(GroupCoordinatorConfig.OFFSETS_TOPIC_SEGMENT_BYTES_CONFIG, 2222);
|
||||
|
|
@ -70,12 +73,11 @@ public class GroupCoordinatorConfigTest {
|
|||
configs.put(GroupCoordinatorConfig.CONSUMER_GROUP_MIN_HEARTBEAT_INTERVAL_MS_CONFIG, 111);
|
||||
configs.put(GroupCoordinatorConfig.CONSUMER_GROUP_MAX_HEARTBEAT_INTERVAL_MS_CONFIG, 222);
|
||||
|
||||
GroupCoordinatorConfig config = new GroupCoordinatorConfig(
|
||||
new AbstractConfig(Utils.mergeConfigs(GROUP_COORDINATOR_CONFIG_DEFS), configs, false));
|
||||
GroupCoordinatorConfig config = createConfig(configs);
|
||||
|
||||
assertEquals(10, config.numThreads());
|
||||
assertEquals(30, config.consumerGroupSessionTimeoutMs());
|
||||
assertEquals(10, config.consumerGroupHeartbeatIntervalMs());
|
||||
assertEquals(555, config.consumerGroupSessionTimeoutMs());
|
||||
assertEquals(200, config.consumerGroupHeartbeatIntervalMs());
|
||||
assertEquals(55, config.consumerGroupMaxSize());
|
||||
assertEquals(1, config.consumerGroupAssignors().size());
|
||||
assertEquals(RangeAssignor.RANGE_ASSIGNOR_NAME, config.consumerGroupAssignors().get(0).name());
|
||||
|
|
@ -101,6 +103,77 @@ public class GroupCoordinatorConfigTest {
|
|||
assertEquals(222, config.consumerGroupMaxHeartbeatIntervalMs());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidConfigs() {
|
||||
Map<String, Object> configs = new HashMap<>();
|
||||
configs.put(GroupCoordinatorConfig.OFFSET_COMMIT_REQUIRED_ACKS_CONFIG, (short) -2);
|
||||
configs.put(GroupCoordinatorConfig.OFFSETS_TOPIC_REPLICATION_FACTOR_CONFIG, (short) 3);
|
||||
assertEquals("offsets.commit.required.acks must be greater or equal to -1 and less or equal to offsets.topic.replication.factor",
|
||||
assertThrows(IllegalArgumentException.class, () -> createConfig(configs)).getMessage());
|
||||
|
||||
configs.clear();
|
||||
configs.put(GroupCoordinatorConfig.CONSUMER_GROUP_MAX_HEARTBEAT_INTERVAL_MS_CONFIG, 10);
|
||||
configs.put(GroupCoordinatorConfig.CONSUMER_GROUP_MIN_HEARTBEAT_INTERVAL_MS_CONFIG, 20);
|
||||
configs.put(GroupCoordinatorConfig.CONSUMER_GROUP_HEARTBEAT_INTERVAL_MS_CONFIG, 20);
|
||||
assertEquals("group.consumer.max.heartbeat.interval.ms must be greater than or equals to group.consumer.min.heartbeat.interval.ms",
|
||||
assertThrows(IllegalArgumentException.class, () -> createConfig(configs)).getMessage());
|
||||
|
||||
configs.clear();
|
||||
configs.put(GroupCoordinatorConfig.CONSUMER_GROUP_MAX_HEARTBEAT_INTERVAL_MS_CONFIG, 30);
|
||||
configs.put(GroupCoordinatorConfig.CONSUMER_GROUP_MIN_HEARTBEAT_INTERVAL_MS_CONFIG, 20);
|
||||
configs.put(GroupCoordinatorConfig.CONSUMER_GROUP_HEARTBEAT_INTERVAL_MS_CONFIG, 10);
|
||||
assertEquals("group.consumer.heartbeat.interval.ms must be greater than or equals to group.consumer.min.heartbeat.interval.ms",
|
||||
assertThrows(IllegalArgumentException.class, () -> createConfig(configs)).getMessage());
|
||||
|
||||
configs.clear();
|
||||
configs.put(GroupCoordinatorConfig.CONSUMER_GROUP_MAX_HEARTBEAT_INTERVAL_MS_CONFIG, 30);
|
||||
configs.put(GroupCoordinatorConfig.CONSUMER_GROUP_MIN_HEARTBEAT_INTERVAL_MS_CONFIG, 20);
|
||||
configs.put(GroupCoordinatorConfig.CONSUMER_GROUP_HEARTBEAT_INTERVAL_MS_CONFIG, 40);
|
||||
assertEquals("group.consumer.heartbeat.interval.ms must be less than or equals to group.consumer.max.heartbeat.interval.ms",
|
||||
assertThrows(IllegalArgumentException.class, () -> createConfig(configs)).getMessage());
|
||||
|
||||
configs.clear();
|
||||
configs.put(GroupCoordinatorConfig.CONSUMER_GROUP_MAX_SESSION_TIMEOUT_MS_CONFIG, 10);
|
||||
configs.put(GroupCoordinatorConfig.CONSUMER_GROUP_MIN_SESSION_TIMEOUT_MS_CONFIG, 20);
|
||||
configs.put(GroupCoordinatorConfig.CONSUMER_GROUP_SESSION_TIMEOUT_MS_CONFIG, 20);
|
||||
assertEquals("group.consumer.max.session.timeout.ms must be greater than or equals to group.consumer.min.session.timeout.ms",
|
||||
assertThrows(IllegalArgumentException.class, () -> createConfig(configs)).getMessage());
|
||||
|
||||
configs.clear();
|
||||
configs.put(GroupCoordinatorConfig.CONSUMER_GROUP_MAX_SESSION_TIMEOUT_MS_CONFIG, 30);
|
||||
configs.put(GroupCoordinatorConfig.CONSUMER_GROUP_MIN_SESSION_TIMEOUT_MS_CONFIG, 20);
|
||||
configs.put(GroupCoordinatorConfig.CONSUMER_GROUP_SESSION_TIMEOUT_MS_CONFIG, 10);
|
||||
assertEquals("group.consumer.session.timeout.ms must be greater than or equals to group.consumer.min.session.timeout.ms",
|
||||
assertThrows(IllegalArgumentException.class, () -> createConfig(configs)).getMessage());
|
||||
|
||||
configs.clear();
|
||||
configs.put(GroupCoordinatorConfig.CONSUMER_GROUP_MAX_SESSION_TIMEOUT_MS_CONFIG, 30);
|
||||
configs.put(GroupCoordinatorConfig.CONSUMER_GROUP_MIN_SESSION_TIMEOUT_MS_CONFIG, 20);
|
||||
configs.put(GroupCoordinatorConfig.CONSUMER_GROUP_SESSION_TIMEOUT_MS_CONFIG, 40);
|
||||
assertEquals("group.consumer.session.timeout.ms must be less than or equals to group.consumer.max.session.timeout.ms",
|
||||
assertThrows(IllegalArgumentException.class, () -> createConfig(configs)).getMessage());
|
||||
|
||||
configs.clear();
|
||||
configs.put(GroupCoordinatorConfig.CONSUMER_GROUP_ASSIGNORS_CONFIG, Object.class);
|
||||
assertEquals("Invalid value class java.lang.Object for configuration group.consumer.assignors: Expected a comma separated list.",
|
||||
assertThrows(ConfigException.class, () -> createConfig(configs)).getMessage());
|
||||
|
||||
configs.clear();
|
||||
configs.put(GroupCoordinatorConfig.CONSUMER_GROUP_ASSIGNORS_CONFIG, Collections.singletonList(Object.class));
|
||||
assertEquals("class java.lang.Object is not an instance of org.apache.kafka.coordinator.group.api.assignor.ConsumerGroupPartitionAssignor",
|
||||
assertThrows(KafkaException.class, () -> createConfig(configs)).getMessage());
|
||||
|
||||
configs.clear();
|
||||
configs.put(GroupCoordinatorConfig.CONSUMER_GROUP_MIGRATION_POLICY_CONFIG, "foobar");
|
||||
assertEquals("Invalid value foobar for configuration group.consumer.migration.policy: String must be one of (case insensitive): DISABLED, DOWNGRADE, UPGRADE, BIDIRECTIONAL",
|
||||
assertThrows(ConfigException.class, () -> createConfig(configs)).getMessage());
|
||||
|
||||
configs.clear();
|
||||
configs.put(GroupCoordinatorConfig.OFFSETS_TOPIC_COMPRESSION_CODEC_CONFIG, -100);
|
||||
assertEquals("Unknown compression type id: -100",
|
||||
assertThrows(IllegalArgumentException.class, () -> createConfig(configs)).getMessage());
|
||||
}
|
||||
|
||||
public static GroupCoordinatorConfig createGroupCoordinatorConfig(
|
||||
int offsetMetadataMaxSize,
|
||||
long offsetsRetentionCheckIntervalMs,
|
||||
|
|
@ -110,7 +183,9 @@ public class GroupCoordinatorConfigTest {
|
|||
configs.put(GroupCoordinatorConfig.GROUP_COORDINATOR_NUM_THREADS_CONFIG, 1);
|
||||
configs.put(GroupCoordinatorConfig.GROUP_COORDINATOR_APPEND_LINGER_MS_CONFIG, 10);
|
||||
configs.put(GroupCoordinatorConfig.CONSUMER_GROUP_SESSION_TIMEOUT_MS_CONFIG, 45);
|
||||
configs.put(GroupCoordinatorConfig.CONSUMER_GROUP_MIN_SESSION_TIMEOUT_MS_CONFIG, 45);
|
||||
configs.put(GroupCoordinatorConfig.CONSUMER_GROUP_HEARTBEAT_INTERVAL_MS_CONFIG, 5);
|
||||
configs.put(GroupCoordinatorConfig.CONSUMER_GROUP_MIN_HEARTBEAT_INTERVAL_MS_CONFIG, 5);
|
||||
configs.put(GroupCoordinatorConfig.CONSUMER_GROUP_MAX_SIZE_CONFIG, Integer.MAX_VALUE);
|
||||
configs.put(GroupCoordinatorConfig.CONSUMER_GROUP_ASSIGNORS_CONFIG, Collections.singletonList(RangeAssignor.class));
|
||||
configs.put(GroupCoordinatorConfig.OFFSETS_TOPIC_SEGMENT_BYTES_CONFIG, 1000);
|
||||
|
|
@ -125,6 +200,10 @@ public class GroupCoordinatorConfigTest {
|
|||
configs.put(GroupCoordinatorConfig.CONSUMER_GROUP_MIGRATION_POLICY_CONFIG, ConsumerGroupMigrationPolicy.DISABLED.name());
|
||||
configs.put(GroupCoordinatorConfig.OFFSETS_TOPIC_COMPRESSION_CODEC_CONFIG, (int) CompressionType.NONE.id);
|
||||
|
||||
return createConfig(configs);
|
||||
}
|
||||
|
||||
private static GroupCoordinatorConfig createConfig(Map<String, Object> configs) {
|
||||
return new GroupCoordinatorConfig(
|
||||
new AbstractConfig(Utils.mergeConfigs(GROUP_COORDINATOR_CONFIG_DEFS), configs, false));
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue