Search backpressure

Search backpressure is a mechanism used to identify resource-intensive search requests and cancel them when the node is under duress. If a search request on a node or shard has breached the resource limits and does not recover within a certain threshold, it is rejected. These thresholds are dynamic and configurable through cluster settings.

Measuring resource consumption

To decide whether to apply search backpressure, OpenSearch periodically measures the following resource consumption statistics for each search request:

  • CPU usage
  • Heap usage
  • Elapsed time

An observer thread periodically measures the resource usage of the node. If OpenSearch determines that the node is under duress, OpenSearch examines the resource usage of each search shard task and compares it against configurable thresholds. OpenSearch considers CPU usage, heap usage, and elapsed time and assigns each task a cancellation score that is then used to cancel the most resource-intensive tasks.

OpenSearch limits the number of cancellations to a fraction of successful task completions. Additionally, it limits the number of cancellations per unit time. OpenSearch continues to monitor and cancel tasks until the node is no longer under duress.

Canceled queries

If a query is canceled, OpenSearch may return partial results if some shards failed. If all shards failed, OpenSearch returns an error from the server similar to the following error:

  1. {
  2. "error": {
  3. "root_cause": [
  4. {
  5. "type": "task_cancelled_exception",
  6. "reason": "cancelled task with reason: cpu usage exceeded [17.9ms >= 15ms], elapsed time exceeded [1.1s >= 300ms]"
  7. },
  8. {
  9. "type": "task_cancelled_exception",
  10. "reason": "cancelled task with reason: elapsed time exceeded [1.1s >= 300ms]"
  11. }
  12. ],
  13. "type": "search_phase_execution_exception",
  14. "reason": "all shards failed",
  15. "phase": "query",
  16. "grouped": true,
  17. "failed_shards": [
  18. {
  19. "shard": 0,
  20. "index": "foobar",
  21. "node": "7yIqOeMfRyWW1rHs2S4byw",
  22. "reason": {
  23. "type": "task_cancelled_exception",
  24. "reason": "cancelled task with reason: cpu usage exceeded [17.9ms >= 15ms], elapsed time exceeded [1.1s >= 300ms]"
  25. }
  26. },
  27. {
  28. "shard": 1,
  29. "index": "foobar",
  30. "node": "7yIqOeMfRyWW1rHs2S4byw",
  31. "reason": {
  32. "type": "task_cancelled_exception",
  33. "reason": "cancelled task with reason: elapsed time exceeded [1.1s >= 300ms]"
  34. }
  35. }
  36. ]
  37. },
  38. "status": 500
  39. }

Search backpressure modes

Search backpressure runs in monitor_only (default), enforced, or disabled mode. In the enforced mode, the server rejects search requests. In the monitor_only mode, the server does not actually cancel search requests but tracks statistics about them. You can specify the mode in the search_backpressure.mode parameter.

Search backpressure settings

Search backpressure adds several settings to the standard OpenSearch cluster settings. These settings are dynamic, so you can change the default behavior of this feature without restarting your cluster.

SettingDefaultDescription
search_backpressure.
    mode
monitor_onlyThe search backpressure mode. Valid values are monitor_only, enforced, or disabled.
search_backpressure.
    interval_millis
1,000 msThe interval at which the observer thread measures the resource usage and cancels tasks.
search_backpressure.
    cancellation_ratio
10%The maximum number of tasks to cancel, as a percentage of successful task completions.
search_backpressure.
    cancellation_rate
0.003The maximum number of tasks to cancel per millisecond of elapsed time.
search_backpressure.
    cancellation_burst
10The maximum number of tasks to cancel in a single iteration of the observer thread.
search_backpressure.
    node_duress.
        num_successive_breaches
3The number of successive limit breaches after which the node is considered to be under duress.
search_backpressure.
    node_duress.
        cpu_threshold
90%The CPU usage threshold (as a percentage) required for a node to be considered to be under duress.
search_backpressure.
    node_duress.
        heap_threshold
70%The heap usage threshold (as a percentage) required for a node to be considered to be under duress.
search_backpressure.
    search_shard_task.
        total_heap_percent_threshold
5%The heap usage threshold (as a percentage) required for the sum of heap usages of all search shard tasks before cancellation is applied.
search_backpressure.
    search_shard_task.
        heap_percent_threshold
0.5%The heap usage threshold (as a percentage) required for a single search shard task before it is considered for cancellation.
search_backpressure.
    search_shard_task.
        heap_variance
2.0The minimum variance required for a single search shard task’s heap usage compared to the rolling average of previously completed tasks before it is considered for cancellation.
search_backpressure.
    search_shard_task.
        heap_moving_average_window_size
100The number of previously completed search shard tasks to consider when calculating the rolling average of heap usage.
search_backpressure.
    search_shard_task.
        cpu_time_millis_threshold
15,000 msThe CPU usage threshold (in milliseconds) required for a single search shard task before it is considered for cancellation.
search_backpressure.
    search_shard_task.
        elapsed_time_millis_threshold
30,000 msThe elapsed time threshold (in milliseconds) required for a single search shard task before it is considered for cancellation.

Search Backpressure Stats API

Introduced 2.4

You can use the nodes stats API operation to monitor server-side request cancellations.

Sample request

To retrieve the statistics, use the following request:

  1. GET _nodes/stats/search_backpressure

Sample response

The response contains server-side request cancellation statistics:

  1. {
  2. "_nodes": {
  3. "total": 1,
  4. "successful": 1,
  5. "failed": 0
  6. },
  7. "cluster_name": "runTask",
  8. "nodes": {
  9. "T7aqO6zaQX-lt8XBWBYLsA": {
  10. "timestamp": 1667409521070,
  11. "name": "runTask-0",
  12. "transport_address": "127.0.0.1:9300",
  13. "host": "127.0.0.1",
  14. "ip": "127.0.0.1:9300",
  15. "roles": [
  16. ],
  17. "attributes": {
  18. "testattr": "test",
  19. "shard_indexing_pressure_enabled": "true"
  20. },
  21. "search_backpressure": {
  22. "search_shard_task": {
  23. "resource_tracker_stats": {
  24. "heap_usage_tracker": {
  25. "cancellation_count": 34,
  26. "current_max_bytes": 1203272,
  27. "current_avg_bytes": 700267,
  28. "rolling_avg_bytes": 1156270
  29. },
  30. "cpu_usage_tracker": {
  31. "cancellation_count": 318,
  32. "current_max_millis": 731,
  33. "current_avg_millis": 303
  34. },
  35. "elapsed_time_tracker": {
  36. "cancellation_count": 310,
  37. "current_max_millis": 1305,
  38. "current_avg_millis": 649
  39. }
  40. },
  41. "cancellation_stats": {
  42. "cancellation_count": 318,
  43. "cancellation_limit_reached_count": 97
  44. }
  45. },
  46. "mode": "enforced"
  47. }
  48. }
  49. }
  50. }

Response fields

The response contains the following fields.

Field NameData typeDescription
search_backpressureObjectStatistics about search backpressure.
search_backpressure.
    search_shard_task
ObjectStatistics specific to the search shard task.
search_backpressure.
    search_shard_task.
    resource_tracker_stats
ObjectStatistics about the current tasks.
search_backpressure.
    search_shard_task.
    calcellation_stats
ObjectStatistics about the tasks canceled since the node last restarted.
search_backpressure.modeStringThe mode for search backpressure.

resource_tracker_stats

The resource_tracker_stats object contains the statistics for each resource tracker: elapsed_time_tracker, heap_usage_tracker, and cpu_usage_tracker.

elapsed_time_tracker

The elapsed_time_tracker object contains the following statistics related to the elapsed time.

Field NameData typeDescription
cancellation_countIntegerThe number of tasks canceled because of excessive elapsed time since the node last restarted.
current_max_millisIntegerThe maximum elapsed time for all tasks currently running on the node, in milliseconds.
current_avg_millisIntegerThe average elapsed time for all tasks currently running on the node, in milliseconds.

heap_usage_tracker

The heap_usage_tracker object contains the following statistics related to the heap usage.

Field NameData typeDescription
cancellation_countIntegerThe number of tasks canceled because of excessive heap usage since the node last restarted.
current_max_bytesIntegerThe maximum heap usage for all tasks currently running on the node, in bytes.
current_avg_bytesIntegerThe average heap usage for all tasks currently running on the node, in bytes.
rolling_avg_bytesIntegerThe rolling average heap usage for n most recent tasks, in bytes. n is configurable and defined by the search_backpressure.search_shard_task.heap_moving_average_window_size setting. The default value for this setting is 100.

cpu_usage_tracker

The cpu_usage_tracker object contains the following statistics related to the CPU usage.

Field NameData typeDescription
cancellation_countIntegerThe number of tasks canceled because of excessive CPU usage since the node last restarted.
current_max_millisIntegerThe maximum CPU time for all tasks currently running on the node, in milliseconds.
current_avg_millisIntegerThe average CPU time for all tasks currently running on the node, in milliseconds.

cancellation_stats

The cancellation_stats object contains the following statistics for canceled tasks.

Field NameData typeDescription
cancellation_countIntegerThe total number of tasks canceled since the node last restarted.
cancellation_limit_reached_countIntegerThe number of times when the number of tasks eligible for cancellation exceeded the set cancellation threshold.