-
Notifications
You must be signed in to change notification settings - Fork 25k
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
Trigger refresh when shard becomes search active #96321
Trigger refresh when shard becomes search active #96321
Conversation
a22b725
to
b82b9f5
Compare
(accidentally pushed 'ready for review' on this PR... too many open browser tabs) |
0b75a31
to
b24857e
Compare
…ot register refresh listener.
b24857e
to
266aa36
Compare
Did a quick benchmark run to see what the impact this change has using the k8s query benchmark (it tests performance of queries on search idle shards). Depending on the query a 15% to a 75% reduction in query time has been observed:
|
…_becoming_search_active
of adding a new method to IndexShard
server/src/main/java/org/elasticsearch/index/shard/IndexShard.java
Outdated
Show resolved
Hide resolved
…_becoming_search_active
updated the testScheduledRefresh(...) test.
assertFalse(primary.scheduledRefresh()); | ||
assertEquals(lastSearchAccess, primary.getLastSearcherAccess()); | ||
// wait until the thread-pool has moved the timestamp otherwise we can't assert on this below | ||
assertBusy(() -> assertThat(primary.getThreadPool().relativeTimeInMillis(), greaterThan(lastSearchAccess))); | ||
CountDownLatch latch = new CountDownLatch(10); | ||
for (int i = 0; i < 10; i++) { |
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.
Because makeShardSearchActive(...)
now triggers a refresh, we can no longer invoke this method many times without a refresh to happen. Before this was possible in this test and then just invoke scheduleRefresh(...)
and all the listeners were invoked.
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 think this looks fine.
I do worry slightly about a small storm of such searches causing additional refreshes. But that seems unlikely enough to not add more protection against.
@@ -3831,14 +3831,17 @@ public void afterRefresh(boolean didRefresh) { | |||
* @param listener the listener to invoke once the pending refresh location is visible. The listener will be called with | |||
* <code>true</code> if the listener was registered to wait for a refresh. | |||
*/ | |||
public final void awaitShardSearchActive(Consumer<Boolean> listener) { | |||
public final void makeShardSearchActive(Consumer<Boolean> listener) { |
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'd probably call this ensureShardSearchActive
, though not too important.
markSearcherAccessed(); // move the shard into non-search idle | ||
final Translog.Location location = pendingRefreshLocation.get(); | ||
if (location != null) { | ||
addRefreshListener(location, (result) -> { | ||
pendingRefreshLocation.compareAndSet(location, null); | ||
listener.accept(true); | ||
}); | ||
// TODO: maybe just invoke getEngine().maybeRefresh(...) here? | ||
// (schedule refresh does a few more things that I don't is necessary here?) | ||
scheduledRefresh(); |
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 think it will work fine, but one problem with maybeRefresh
is that it will not provoke a refresh if there is an ongoing one. But there is no certainty that another ongoing refresh will contain the location. However, such a refresh would have to be an explicit one. I find the risk small and regardless an improvement over current state.
I think we can switch to maybeRefresh
instead, though I'd like to check that pendingRefreshLocation
is still location
then, i.e.:
scheduledRefresh(); | |
if (pendingRefreshLocation.get() == location) { | |
getEngine().maybeRefresh(); | |
} |
both to handle racy cases and the case where there are no more refresh listener slots.
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.
Forgot one thing.
Hi @martijnvg, I've created a changelog YAML for you. |
Pinging @elastic/es-analytics-geo (Team:Analytics) |
Pinging @elastic/es-distributed (Team:Distributed) |
…_becoming_search_active
…_becoming_search_active
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.
LGTM.
markSearcherAccessed(); // move the shard into non-search idle | ||
final Translog.Location location = pendingRefreshLocation.get(); | ||
if (location != null) { | ||
addRefreshListener(location, (result) -> { | ||
pendingRefreshLocation.compareAndSet(location, null); | ||
listener.accept(true); | ||
}); | ||
// trigger a refresh to avoid waiting for scheduledRefresh(...) to be invoked from index level refresh scheduler. | ||
// (The if statement should avoid doing an additional refresh if scheduled refresh was invoked between getting | ||
// the current refresh location and adding a refresh listener.) |
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.
In particular, addRefreshListener
might have performed the refresh already in edge cases.
server/src/test/java/org/elasticsearch/index/shard/IndexShardTests.java
Outdated
Show resolved
Hide resolved
Co-authored-by: Henning Andersen <[email protected]>
@elasticmachine update branch |
…_becoming_search_active
…_becoming_search_active
…_becoming_search_active
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.
LGTM.
This change invokes
Engine#maybeRefresh()
when a shard is search-idle and becomes search-active inIndexShard#ensureShardSearchActive(...)
(used to be namedwaitShardSearchActive(...)
).Prior to this change shard level search execution is idle until the schedule refresh has been execute. This includes the time it takes for the refresh to be scheduled (which is a full second). This unnecessarily increases the query time of a search request.
Closes #95544