-
Notifications
You must be signed in to change notification settings - Fork 25.1k
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
Avoid copying during iteration of all shards in routing table #94417
Avoid copying during iteration of all shards in routing table #94417
Conversation
Pinging @elastic/es-distributed (Team:Distributed) |
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 your analysis is correct. However, this will apply to all callers of RoutingTable#allShards()
- there's just no good reason to copy all the shards in the cluster into a new list like this, so I think it would be better to fix the method on RoutingTable
so that all callers (including future callers) will see the benefits. For instance, try making it return Iterable<ShardRouting>
(you'll probably find org.elasticsearch.common.collect.Iterators#flatMap
to be useful in this endeavour) or Stream<ShardRouting>
.
2. Reduce iterator in RestAllocationAction
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.
Looks ok to me, but @original-brownbear IIRC we removed some methods that made it easy to iterate over the routing table because they were over-used and much more expensive than doing it by index. Are you ok with bringing them back in this limited format to avoid GET _cat/shards
and GET _cat/allocation
having to do all that copying?
@elasticmachine ok to test |
LGTM , let me try it |
@luyuncheng sorry that question was intended for |
@DaveCTurner yea definitely, that makes sense to me! |
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 then 😄
|
Today when applying a new cluster state we block the cluster applier thread for up to 5s while waiting to acquire each shard lock. Failure to acquire the shard lock is treated as an allocation failure, so after 5 retries (by default) we give up on the allocation. The shard lock may be held by some other actor, typically the previous incarnation of the shard which is still shutting down, but it will eventually be released. Yet, 5 retries of 5s each is sometimes not enough time to wait. Knowing that the shard lock will eventually be released, we can retry much more tenaciously. Moreover there's no reason why we have to create the `IndexShard` while applying the cluster state, because the shard remains in state `INITIALIZING`, and therefore unused, while it coordinates its own recovery. With this commit we try and acquire the shard lock during cluster state application, but do not wait if the lock is unavailable. Instead, we schedule a retry (also executed on the cluster state applier thread) and proceed with the rest of the cluster state application process. Relates elastic#24530 Backport of elastic#94545 and elastic#94623 (and a little bit of elastic#94417) to 8.7
Today when applying a new cluster state we block the cluster applier thread for up to 5s while waiting to acquire each shard lock. Failure to acquire the shard lock is treated as an allocation failure, so after 5 retries (by default) we give up on the allocation. The shard lock may be held by some other actor, typically the previous incarnation of the shard which is still shutting down, but it will eventually be released. Yet, 5 retries of 5s each is sometimes not enough time to wait. Knowing that the shard lock will eventually be released, we can retry much more tenaciously. Moreover there's no reason why we have to create the `IndexShard` while applying the cluster state, because the shard remains in state `INITIALIZING`, and therefore unused, while it coordinates its own recovery. With this commit we try and acquire the shard lock during cluster state application, but do not wait if the lock is unavailable. Instead, we schedule a retry (also executed on the cluster state applier thread) and proceed with the rest of the cluster state application process. Relates #24530 Backport of #94545 and #94623 (and a little bit of #94417) to 8.7
we used
cat/allocation
to get cluster allocation.the logic in the code:
elasticsearch/server/src/main/java/org/elasticsearch/rest/action/cat/RestAllocationAction.java
Lines 102 to 110 in a96ffea
elasticsearch/server/src/main/java/org/elasticsearch/cluster/routing/RoutingTable.java
Lines 201 to 208 in a96ffea
it would iterator all shards twice, we can deduplicated it