-
Notifications
You must be signed in to change notification settings - Fork 24.9k
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
Assign priorities to search requests #37867
Comments
Pinging @elastic/es-search |
Cluster Use case
Query cost can be part of query itself (passed by user). |
Another use case (something similar but different) is that we have a UI dashboard with 8 widgets. When the UI is loaded, those widgets fire concurrent queries to our backend (ES) and those queries share same filters but have different aggregations. But since those are being fired in parallel, we are recomputing filter in all those 8 requests. We can consider this here to cache filter results and queue same filter queries so that we don't re-compute them. |
Thanks for sharing @nitin2goyal. Use-case 1 makes sense. Use-case 2 is a bit more tricky because we'd need to make Elasticsearch aware somehow that it it going to get N times the same query with different aggregations. In my opinion this kind of problem would be better solved on the client-side by having eg. two requests that have 4 aggregations each in order to decrease the number of times the filter needs to be evaluated. |
Other use cases :
|
We have a use case that runs queries against Elasticsearch for real time search, and user has the option to export the search result to external file which can be large amount of data with many pages. It'll be great to run the queries that are for exporting data at lower priority, so the real time search is more responsive, and we can bear with slowness of exporting data. |
As we're creating more background searches in the Security app, especially EQL queries which can take a longer time, this could be interesting in the sense that prioritizing the interactive queries can keep the UI feel snappy for longer. +1 to the feature request. |
Transform allows long running jobs that execute searches. This can have a negative effect on normal usage. Therefore assigning a low priority to searches would be nice to have. We mitigated this issue by adding throttling support, see #54862 and we will also make searches less resource-hungry, however this feels like a workaround and has e.g. the bad side effect that we are not using the available capacity, e.g. transform should run at full speed if possible, for example at off-hours. Long story short, +1 for this feature request, so we can create a better alternative to throttling. |
We discussed internally and agreed that we should split this issue. Different thread pool for system indicesPriorities for system queries become more important if we allow slow queries more aggressively (script query, source-only field) since they can be blocked by slow user queries. A query made on the Handle priorities among user queries.With async search coming in the next release, we want to better handle queries that take time.
A single thread pool with different priorities should handle the first case well. The second case is more tricky since all active threads could be blocked with slow shard queries that take 1h individually. So if a new request come, it'd need to wait at most 1h to get a thread no matter what priority was set on it. That's a good argument to have a different thread pool here too but we also don't want to limit the resource of low-priority queries if there are no fast queries to run. Separating the two use cases should help to make progress. I am planning to open a separate issue for a new thread pool for system indices and hope we can continue to discuss user queries priorities here. |
Giving different priorities to async search requests vs interactive/real-time search requests looks a good idea to me. We can have a user-configured parameter for the ratio of these priorities, for example 0.05 could mean that for every 5 queued async requests, 100 queued interactive requests will be executed.
Looks like having a separate thread pool for system indices makes this problem less important, and indeed may not worth to have another thread pool for slow requests. |
This commit introduces a new thread pool, `system_read`, which is intended for use by system indices for all read operations (get and search). The `system_read` pool is a fixed thread pool with a maximum number of threads equal to lesser of half of the available processors or 5. Given the combination of both get and read operations in this thread pool, the queue size has been set to 2000. The motivation for this change is to allow system read operations to be serviced in spite of the number of user searches. In order to avoid a significant performance hit due to pattern matching on all search requests, a new metadata flag is added to mark indices as system or non-system. Previously created system indices will have flag added to their metadata upon upgrade to a version with this capability. Additionally, this change also introduces a new class, `SystemIndices`, which encapsulates logic around system indices. Currently, the class provides a method to check if an index is a system index and a method to find a matching index descriptor given the name of an index. Relates elastic#50251 Relates elastic#37867
This commit introduces a new thread pool, `system_read`, which is intended for use by system indices for all read operations (get and search). The `system_read` pool is a fixed thread pool with a maximum number of threads equal to lesser of half of the available processors or 5. Given the combination of both get and read operations in this thread pool, the queue size has been set to 2000. The motivation for this change is to allow system read operations to be serviced in spite of the number of user searches. In order to avoid a significant performance hit due to pattern matching on all search requests, a new metadata flag is added to mark indices as system or non-system. Previously created system indices will have flag added to their metadata upon upgrade to a version with this capability. Additionally, this change also introduces a new class, `SystemIndices`, which encapsulates logic around system indices. Currently, the class provides a method to check if an index is a system index and a method to find a matching index descriptor given the name of an index. Relates #50251 Relates #37867
This commit introduces a new thread pool, `system_read`, which is intended for use by system indices for all read operations (get and search). The `system_read` pool is a fixed thread pool with a maximum number of threads equal to lesser of half of the available processors or 5. Given the combination of both get and read operations in this thread pool, the queue size has been set to 2000. The motivation for this change is to allow system read operations to be serviced in spite of the number of user searches. In order to avoid a significant performance hit due to pattern matching on all search requests, a new metadata flag is added to mark indices as system or non-system. Previously created system indices will have flag added to their metadata upon upgrade to a version with this capability. Additionally, this change also introduces a new class, `SystemIndices`, which encapsulates logic around system indices. Currently, the class provides a method to check if an index is a system index and a method to find a matching index descriptor given the name of an index. Relates #50251 Relates #37867 Backport of #57936
I'd add that things like Rank Evaluation API calls, which internally make a load of parallel queries, should also have low priority. I don't know if there is a class of "internal but non system index" queries that would fall into this category as well. |
Could this also pave the way for prioritising reads over writes? Use case: Constant stream of writes but we have an SLA of 1-2 Days for the data to be actually reflected. So while these writes happen, we do not want the reads to suffer. |
How would you decide on the priority of a request?
How many priorities you would need? (only 2 to handle system vs user queries or more)
|
Dealing with a use case that is analogous to the one mentioned: There are searches against the cluster from an application, these are pretty surgical and by themselves very low latency, and then there are searches conducted on an ad hoc basis by users who have a UI, and these searches have the opportunity to be more complex or request a large result set. So from time to time, the latency that the application sees for its searches has a spike. (By the way, adaptive replica selection doesn't help with this, as it has no way to account for the weight of queries that are already in each node's search queue, among other things.)
In this case, it could be based on the user associated with the request. Or maybe it would be a request param. That would be easy enough to control where all of the actual requests are generated "under wraps", abstracted from any end users.
2 priorities for this scenario.
That trade-off seems reasonable. In this scenario, as the searches desired to be made low-priority are already slow, such rate-limiting probably won't change the user experience a great deal. For what it's worth, in trying to devise a way to accomplish this with currently available features, I've necessarily been looking at the cluster level instead of the node level, like using allocation awareness plus search shard preference to designate specific sets of nodes to service specific searches. That approach would likely result in inefficiency in the form of idle time in one set of nodes or the other, but it is probably an improvement over deploying a second cluster with duplicate data. EDIT: clarified language |
Use case same as above:
provided as a parameter (?requestprio=)
At least two for user queries (fast vs slow). |
Our use case follows:
Optimally, I would like:
|
Pinging @elastic/es-search (Team:Search) |
Pinging @elastic/es-search-foundations (Team:Search Foundations) |
There has been a recurring ask to be able to prioritize some queries over other queries. One use-case for this feature is the ability to run user queries and system queries on the same cluster. Some ideas have been suggested like having separate threadpools or using priority queues rather than regular queues. Regardless of priority, search requests are competing for the same resources in the end, so given that we don't have (and probably don't want) the ability to pause running queries, low-priority queries would likely always have the potential to slow down higher-priority queries.
This doesn't mean that we shouldn't do anything, hence this new issue where we would like to collect feedback about use-cases to see what we could do. Please share your use-case, we are especially interested to know:
Some related issues include #37856 (don't let queries that target lots of shards slow down more reasonable queries) and #14224 (priorities, but at index-time).
The text was updated successfully, but these errors were encountered: