-
Notifications
You must be signed in to change notification settings - Fork 15k
KAFKA-15022: [5/N] compute rack aware assignment for standby tasks #14108
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 all commits
f9d021a
b58bd76
19b9401
6b858aa
27f9aaa
03f9e51
f9180c4
7d30938
7fc0000
39501da
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 |
|---|---|---|
|
|
@@ -17,8 +17,11 @@ | |
| package org.apache.kafka.streams.processor.internals.assignment; | ||
|
|
||
| import java.util.List; | ||
| import java.util.function.BiConsumer; | ||
| import java.util.function.BiFunction; | ||
| import java.util.function.Function; | ||
| import java.util.stream.Collectors; | ||
| import org.apache.kafka.streams.KeyValue; | ||
| import org.apache.kafka.streams.processor.TaskId; | ||
| import org.apache.kafka.streams.processor.internals.assignment.AssignorConfiguration.AssignmentConfigs; | ||
| import org.slf4j.Logger; | ||
|
|
@@ -156,6 +159,48 @@ public boolean isAllowedTaskMovement(final ClientState source, final ClientState | |
| return true; | ||
| } | ||
|
|
||
| /** | ||
| * Whether one task can be moved from source to destination. If the number of distinct tags including active | ||
| * and standby after the movement isn't decreased, then we can move the task. Otherwise, we can not move | ||
| * the task. | ||
| * @param source Source client | ||
| * @param destination Destination client | ||
| * @param sourceTask Task to move | ||
| * @param clientStateMap All client metadata | ||
| * @return If the task can be moved | ||
| */ | ||
| @Override | ||
| public boolean isAllowedTaskMovement(final ClientState source, | ||
| final ClientState destination, | ||
| final TaskId sourceTask, | ||
| final Map<UUID, ClientState> clientStateMap) { | ||
|
|
||
| final BiConsumer<ClientState, Set<KeyValue<String, String>>> addTags = (cs, tagSet) -> { | ||
| final Map<String, String> tags = clientTagFunction.apply(cs.processId(), cs); | ||
| if (tags != null) { | ||
| tagSet.addAll(tags.entrySet().stream() | ||
| .map(entry -> KeyValue.pair(entry.getKey(), entry.getValue())) | ||
| .collect(Collectors.toList()) | ||
| ); | ||
| } | ||
| }; | ||
|
|
||
| final Set<KeyValue<String, String>> tagsWithSource = new HashSet<>(); | ||
| final Set<KeyValue<String, String>> tagsWithDestination = new HashSet<>(); | ||
| for (final ClientState clientState : clientStateMap.values()) { | ||
| if (clientState.hasAssignedTask(sourceTask) | ||
| && !clientState.processId().equals(source.processId()) | ||
|
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. Not sure if I can follow? Does
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.
|
||
| && !clientState.processId().equals(destination.processId())) { | ||
| addTags.accept(clientState, tagsWithSource); | ||
| addTags.accept(clientState, tagsWithDestination); | ||
| } | ||
| } | ||
| addTags.accept(source, tagsWithSource); | ||
| addTags.accept(destination, tagsWithDestination); | ||
|
|
||
| return tagsWithDestination.size() >= tagsWithSource.size(); | ||
| } | ||
|
|
||
| // Visible for testing | ||
| void fillClientsTagStatistics(final Map<UUID, ClientState> clientStates, | ||
| final Map<TagEntry, Set<UUID>> tagEntryToClients, | ||
|
|
||
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.
Not sure if I grog the semantics of this method.
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.
This method is to check whether a specific task can be moved between two clients. The method on line 149 checks if any task can be moved between two clients.
About the implementation in tag aware case, a task can be moved between two clients if the number of distinct tags after the movement is equal to or more than the number of tags before the movement. So the reliability constraint doesn't get worse.