-
Notifications
You must be signed in to change notification settings - Fork 15.4k
KAFKA-19719: --no-initial-controllers should not assume kraft.version=1 #20551
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
dcc3668
e0ad6c0
1720ad7
a905fc8
e671a39
ae21d0e
8917f9d
9864633
951b874
c99a253
c087a97
8c0271b
cf4a00e
f8926de
6e23ed8
d1e3b65
14fabc4
989796a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -149,8 +149,9 @@ object StorageTool extends Logging { | |
| }) | ||
| val initialControllers = namespace.getString("initial_controllers") | ||
| val isStandalone = namespace.getBoolean("standalone") | ||
| if (!config.quorumConfig.voters().isEmpty && | ||
| (Option(initialControllers).isDefined || isStandalone)) { | ||
| val staticVotersEmpty = config.quorumConfig.voters().isEmpty | ||
| formatter.setStaticVotersEmpty(staticVotersEmpty) | ||
| if (!staticVotersEmpty && (Option(initialControllers).isDefined || isStandalone)) { | ||
| throw new TerseFailure("You cannot specify " + | ||
| QuorumConfig.QUORUM_VOTERS_CONFIG + " and format the node " + | ||
| "with --initial-controllers or --standalone. " + | ||
|
|
@@ -163,16 +164,12 @@ object StorageTool extends Logging { | |
| if (isStandalone) { | ||
| formatter.setInitialControllers(createStandaloneDynamicVoters(config)) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems that
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you look at the dynamic quorum arguments, you cannot specify multiple at the same time: |
||
| } | ||
| if (namespace.getBoolean("no_initial_controllers")) { | ||
| formatter.setNoInitialControllersFlag(true) | ||
| } else { | ||
| if (config.processRoles.contains(ProcessRole.ControllerRole)) { | ||
| if (config.quorumConfig.voters().isEmpty && formatter.initialVoters().isEmpty) { | ||
| if (!namespace.getBoolean("no_initial_controllers") && | ||
| config.processRoles.contains(ProcessRole.ControllerRole) && | ||
| staticVotersEmpty && formatter.initialVoters().isEmpty) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would add a newline after |
||
| throw new TerseFailure("Because " + QuorumConfig.QUORUM_VOTERS_CONFIG + | ||
| " is not set on this controller, you must specify one of the following: " + | ||
| "--standalone, --initial-controllers, or --no-initial-controllers."); | ||
| } | ||
| } | ||
| } | ||
| Option(namespace.getList("add_scram")). | ||
| foreach(scramArgs => formatter.setScramArguments(scramArgs.asInstanceOf[util.List[String]])) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -84,9 +84,8 @@ public void testCreateAndDestroyReconfigurableCluster() throws Exception { | |
| new TestKitNodes.Builder(). | ||
| setNumBrokerNodes(1). | ||
| setNumControllerNodes(1). | ||
| setFeature(KRaftVersion.FEATURE_NAME, KRaftVersion.KRAFT_VERSION_1.featureLevel()). | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the method |
||
| build() | ||
| ).build()) { | ||
| ).setStandalone(true).build()) { | ||
| cluster.format(); | ||
| cluster.startup(); | ||
| try (Admin admin = Admin.create(cluster.clientProperties())) { | ||
|
|
@@ -108,13 +107,23 @@ static Map<Integer, Uuid> findVoterDirs(Admin admin) throws Exception { | |
|
|
||
| @Test | ||
| public void testRemoveController() throws Exception { | ||
| try (KafkaClusterTestKit cluster = new KafkaClusterTestKit.Builder( | ||
| new TestKitNodes.Builder(). | ||
| setNumBrokerNodes(1). | ||
| setNumControllerNodes(3). | ||
| setFeature(KRaftVersion.FEATURE_NAME, KRaftVersion.KRAFT_VERSION_1.featureLevel()). | ||
| build() | ||
| ).build()) { | ||
| final var nodes = new TestKitNodes.Builder(). | ||
| setNumBrokerNodes(1). | ||
| setNumControllerNodes(3). | ||
| build(); | ||
|
|
||
| final Map<Integer, Uuid> initialVoters = new HashMap<>(); | ||
| for (final var controllerNode : nodes.controllerNodes().values()) { | ||
| initialVoters.put( | ||
| controllerNode.id(), | ||
| controllerNode.metadataDirectoryId() | ||
| ); | ||
| } | ||
|
|
||
| try (KafkaClusterTestKit cluster = new KafkaClusterTestKit.Builder(nodes). | ||
| setInitialVoterSet(initialVoters). | ||
| build() | ||
| ) { | ||
| cluster.format(); | ||
| cluster.startup(); | ||
| try (Admin admin = Admin.create(cluster.clientProperties())) { | ||
|
|
@@ -133,12 +142,22 @@ public void testRemoveController() throws Exception { | |
|
|
||
| @Test | ||
| public void testRemoveAndAddSameController() throws Exception { | ||
| try (KafkaClusterTestKit cluster = new KafkaClusterTestKit.Builder( | ||
| new TestKitNodes.Builder(). | ||
| setNumBrokerNodes(1). | ||
| setNumControllerNodes(4). | ||
| setFeature(KRaftVersion.FEATURE_NAME, KRaftVersion.KRAFT_VERSION_1.featureLevel()). | ||
| build()).build() | ||
| final var nodes = new TestKitNodes.Builder(). | ||
| setNumBrokerNodes(1). | ||
| setNumControllerNodes(4). | ||
| build(); | ||
|
|
||
| final Map<Integer, Uuid> initialVoters = new HashMap<>(); | ||
| for (final var controllerNode : nodes.controllerNodes().values()) { | ||
| initialVoters.put( | ||
| controllerNode.id(), | ||
| controllerNode.metadataDirectoryId() | ||
| ); | ||
| } | ||
|
|
||
| try (KafkaClusterTestKit cluster = new KafkaClusterTestKit.Builder(nodes). | ||
| setInitialVoterSet(initialVoters). | ||
| build() | ||
| ) { | ||
| cluster.format(); | ||
| cluster.startup(); | ||
|
|
@@ -173,7 +192,6 @@ public void testControllersAutoJoinStandaloneVoter() throws Exception { | |
| final var nodes = new TestKitNodes.Builder(). | ||
| setNumBrokerNodes(1). | ||
| setNumControllerNodes(3). | ||
| setFeature(KRaftVersion.FEATURE_NAME, KRaftVersion.KRAFT_VERSION_1.featureLevel()). | ||
| build(); | ||
| try (KafkaClusterTestKit cluster = new KafkaClusterTestKit.Builder(nodes). | ||
| setConfigProp(QuorumConfig.QUORUM_AUTO_JOIN_ENABLE_CONFIG, true). | ||
|
|
@@ -199,7 +217,6 @@ public void testNewVoterAutoRemovesAndAdds() throws Exception { | |
| final var nodes = new TestKitNodes.Builder(). | ||
| setNumBrokerNodes(1). | ||
| setNumControllerNodes(3). | ||
| setFeature(KRaftVersion.FEATURE_NAME, KRaftVersion.KRAFT_VERSION_1.featureLevel()). | ||
| build(); | ||
|
|
||
| // Configure the initial voters with one voter having a different directory ID. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -131,7 +131,7 @@ public class Formatter { | |
| * The initial KIP-853 voters. | ||
| */ | ||
| private Optional<DynamicVoters> initialControllers = Optional.empty(); | ||
| private boolean noInitialControllersFlag = false; | ||
| private boolean staticVotersEmpty = false; | ||
|
|
||
| public Formatter setPrintStream(PrintStream printStream) { | ||
| this.printStream = printStream; | ||
|
|
@@ -217,8 +217,8 @@ public Formatter setInitialControllers(DynamicVoters initialControllers) { | |
| return this; | ||
| } | ||
|
|
||
| public Formatter setNoInitialControllersFlag(boolean noInitialControllersFlag) { | ||
| this.noInitialControllersFlag = noInitialControllersFlag; | ||
| public Formatter setStaticVotersEmpty(boolean staticVotersEmpty) { | ||
| this.staticVotersEmpty = staticVotersEmpty; | ||
| return this; | ||
| } | ||
|
|
||
|
|
@@ -227,7 +227,7 @@ public Optional<DynamicVoters> initialVoters() { | |
| } | ||
|
|
||
| boolean hasDynamicQuorum() { | ||
| return initialControllers.isPresent() || noInitialControllersFlag; | ||
| return staticVotersEmpty; | ||
| } | ||
|
|
||
| public BootstrapMetadata bootstrapMetadata() { | ||
|
|
@@ -337,7 +337,7 @@ Map<String, Short> calculateEffectiveFeatureLevels() { | |
| /** | ||
| * Calculate the effective feature level for kraft.version. In order to keep existing | ||
| * command-line invocations of StorageTool working, we default this to 0 if no dynamic | ||
| * voter quorum arguments were provided. As a convenience, if dynamic voter quorum arguments | ||
| * voter quorum arguments were provided. As a convenience, if --standalone or --initial-voters | ||
| * were passed, we set the latest kraft.version. (Currently there is only 1 non-zero version). | ||
| * | ||
| * @param configuredKRaftVersionLevel The configured level for kraft.version | ||
|
|
@@ -348,20 +348,20 @@ private short effectiveKRaftFeatureLevel(Optional<Short> configuredKRaftVersionL | |
| if (configuredKRaftVersionLevel.get() == 0) { | ||
| if (hasDynamicQuorum()) { | ||
| throw new FormatterException( | ||
| "Cannot set kraft.version to " + | ||
| configuredKRaftVersionLevel.get() + | ||
| " if one of the flags --standalone, --initial-controllers, or --no-initial-controllers is used. " + | ||
| "Cannot set kraft.version to " + configuredKRaftVersionLevel.get() + | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would you mind using throw new FormatterException(
"Cannot set kraft.version to 0 if controller.quorum.voters is empty and one of the flags --standalone, " +
"--initial-controllers, or --no-initial-controllers is used. For dynamic controllers support, " +
"try removing the --feature flag for kraft.version."
); |
||
| " if controller.quorum.voters is empty and one of the flags --standalone, " + | ||
| "--initial-controllers, or --no-initial-controllers is used. " + | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This this true? Doesn't the tool allow --no-initial-controller when controller.quorum.voters is specified?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, this needs to be fixed.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry for the confusion, but the original error message should be correct. If the static voters is not specified, --no-intial-controllers is set, and kraft.version is set to 0, the formatter should fail. The message says if controller.quorum.voters is empty AND one of the KIP-853 flags is set. If static voters is specified, --no-initial-controllers is set, and kraft.version is set to 0, the tool does not fail. The |
||
| "For dynamic controllers support, try removing the --feature flag for kraft.version." | ||
| ); | ||
| } | ||
| } else { | ||
| if (!hasDynamicQuorum()) { | ||
| throw new FormatterException( | ||
| "Cannot set kraft.version to " + | ||
| configuredKRaftVersionLevel.get() + | ||
| " unless one of the flags --standalone, --initial-controllers, or --no-initial-controllers is used. " + | ||
| "For dynamic controllers support, try using one of --standalone, --initial-controllers, or " + | ||
| "--no-initial-controllers." | ||
| "Cannot set kraft.version to " + configuredKRaftVersionLevel.get() + | ||
| " unless controller.quorum.voters is empty and one of the flags --standalone, " + | ||
| "--initial-controllers, or -no-initial-controllers is used. " + | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit:
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sounds good, will fix |
||
| "For dynamic controllers support, try using one of --standalone, --initial-controllers, " + | ||
| "or --no-initial-controllers and removing controller.quorum.voters." | ||
| ); | ||
| } | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still feel it is weird that users configure
controller.quorum.voterswith--no-initial-controllers, but you are right that we should keep the compatibility.Should we add another warning to remind users that
--no-initial-controllersshould not be used with static voters even though it is no-op?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can add it to the flag's help output.