-
Notifications
You must be signed in to change notification settings - Fork 810
SOLR-18080: Initiate Leader election for ShardTerms #4069
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
base: main
Are you sure you want to change the base?
Changes from all commits
b13d97e
7522caa
776c28b
e2b0e84
9f102cb
d68acf3
b60d971
9446312
34cba84
68475bc
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 |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| # See https://github.com/apache/solr/blob/main/dev-docs/changelog.adoc | ||
| title: ShardTerms can now induce a leader election if needed | ||
| type: other # added, changed, fixed, deprecated, removed, dependency_update, security, other | ||
| authors: | ||
| - name: Houston Putman | ||
| nick: HoustonPutman | ||
| links: | ||
| - name: SOLR-18080 | ||
| url: https://issues.apache.org/jira/browse/SOLR-18080 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -124,6 +124,28 @@ private boolean skipIncreaseTermOf(String key, Set<String> replicasNeedingRecove | |
| return replicasNeedingRecovery.contains(key); | ||
| } | ||
|
|
||
| public ShardTerms setHighestTerms(Set<String> highestTermKeys) { | ||
|
Contributor
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 whole "term" algorithm makes some pretty strict assumptions about who can update term values, and on what conditions. From class javadocs on ZkShardTerms: This method seems to fit under the latter provision, which is good. But could we add Javadocs here to indicate that this method should only be called by current shard-leaders? Or if this is safe for non-leaders to call in certain situations, add javadocs to describe what those are and why. Just trying to defend against the possibility of someone coming back through here in a month or two and thinking: "Hey this doesn't fit with the documented algorithm at all"
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. So this ultimately doesn't happen from the leader, and the leaders term is not guaranteed to be increased. If we see in our new test class, leader election can be triggered because of this new API. I think the easiest thing to do here is insist that the collection is in a read-only state when this API is called. I'm not sure how I'll do that, but it will definitely guard against any issues with missing updates or anything like that. |
||
| long newMaxTerm = maxTerm + 1; | ||
| boolean keyFound = false; | ||
| HashMap<String, Long> newValues = new HashMap<>(values); | ||
| long nextHighestTerm = -1; | ||
| for (String key : values.keySet()) { | ||
| if (highestTermKeys.contains(key)) { | ||
| newValues.put(key, newMaxTerm); | ||
| keyFound = true; | ||
| } else { | ||
| nextHighestTerm = Math.max(nextHighestTerm, values.get(key)); | ||
| } | ||
| } | ||
| // We only want to update if increasing the maxTerm makes an impact. | ||
| // If the nextHighestTerm is already < maxTerm, then upping the maxTerm doesn't do anything. | ||
| if (nextHighestTerm == maxTerm && keyFound) { | ||
| return new ShardTerms(newValues, version); | ||
| } else { | ||
| return null; | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Return a new {@link ShardTerms} in which the highest terms are not zero | ||
| * | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -120,6 +120,11 @@ public void ensureTermsIsHigher(String leader, Set<String> replicasNeedingRecove | |
| mutate(terms -> terms.increaseTerms(leader, replicasNeedingRecovery)); | ||
| } | ||
|
|
||
| public void ensureHighestTerms(Set<String> mostUpToDateCores) { | ||
|
Contributor
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. Ditto, re: my previous comment on |
||
| if (mostUpToDateCores.isEmpty()) return; | ||
| mutate(terms -> terms.setHighestTerms(mostUpToDateCores)); | ||
| } | ||
|
|
||
| public ShardTerms getShardTerms() { | ||
| return terms.get(); | ||
| } | ||
|
|
||
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.
lastTermDoRecovery is set here but its possible recovery is deferred below because of leader election now. Is that right? The old logic set it, then actually does recovery regardless. Reading this, seems like there is a possibility that
lastTermDoRecoveryis set to the new term but can skip actually doing recovery further down. So the term this was set to is incorrect based on the name if recovery is skipped?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.
Yeah
lastTermDoRecoverymight be a bad name, but after leader election, recovery is guaranteed for these replicas at this term value. So while recovery is not explicitly being done here, we know that leader election will do the recovery. SolastTermDoRecoveryis still technically correct, just assuming the leader election succeeds.