LoginSignup
2
5

More than 5 years have passed since last update.

Elasticsearch Queryのキャンセル

Last updated at Posted at 2019-03-22

はじめに

ながーくかかるクエリを実行している時に、ふとキャンセルしたい時ってありませんか?
そんな時に使える手がX-Opaque-Idを使ったキャンセルです。

長くかかるクエリのキャンセル

普通に実行した場合

例えばこんなクエリを投げて見ます。

curl -i -H 'Content-type: application/json' http://localhost:9200/.monitoring-*/_search -d'{"size": 10000}'

環境にもよるとは思いますが、レスポンスが返ってくるまで結構かかります。
レスポンスが返るまではTask Management APIを使えば、実行中のクエリを見ることはできます。
ただし、どんなクエリを実行しているのかまでは、このAPIでは見ることができません。

単発のクエリを実行し値得る場合は、

# curl 'http://localhost:9200/_tasks?pretty&actions=*search'

で出てきたタスクのIDを使ってキャンセルすれば良いでしょう。
でも、複数のクエリを実行している場合は、どれが本当にキャンセルしたいものかわかりません。

X-Opaque-Idを使用したリクエストの特定

リクエスト時にX-Opaque-Idヘッダを付加して実行します。

curl -i -H "X-Opaque-Id: 123456" -H 'Content-type: application/json' http://localhost:9200/.monitoring-*/_search -d'{"size": 10000}'

この状態でタスクを確認すると、

# curl 'http://localhost:9200/_tasks?pretty&actions=*search,*fetch*'
{
  "nodes" : {
    "RqHPIcbRRIyDb3uqTwzmDQ" : {
      "name" : "RqHPIcb",
      "transport_address" : "127.0.0.1:9300",
      "host" : "127.0.0.1",
      "ip" : "127.0.0.1:9300",
      "roles" : [
        "master",
        "data",
        "ingest"
      ],
      "attributes" : {
        "ml.machine_memory" : "16681828352",
        "xpack.installed" : "true",
        "ml.max_open_jobs" : "20",
        "ml.enabled" : "true"
      },
      "tasks" : {
        "RqHPIcbRRIyDb3uqTwzmDQ:9252" : {
          "node" : "RqHPIcbRRIyDb3uqTwzmDQ",
          "id" : 9252,
          "type" : "transport",
          "action" : "indices:data/read/search",
          "start_time_in_millis" : 1553242069549,
          "running_time_in_nanos" : 475068030,
          "cancellable" : true,
          "headers" : {
            "X-Opaque-Id" : "123456"
          }
        },
        "RqHPIcbRRIyDb3uqTwzmDQ:9278" : {
          "node" : "RqHPIcbRRIyDb3uqTwzmDQ",
          "id" : 9278,
          "type" : "direct",
          "action" : "indices:data/read/search[phase/fetch/id]",
          "start_time_in_millis" : 1553242069698,
          "running_time_in_nanos" : 326060299,
          "cancellable" : true,
          "parent_task_id" : "RqHPIcbRRIyDb3uqTwzmDQ:9252",
          "headers" : {
            "X-Opaque-Id" : "123456"
          }
        }
      }
    }
  }
}

てな感じで、レスポンスにヘッダ情報が付加されて返ってきます。
これでどのクエリか特定できるので、そのタスクIDを使ってキャンセルをする、と。

おわりらない

curlで実行している分には、curlのプロセスをkillしちゃえば(=コネクションが切れる)、Elasticsearch的にはクエリがキャンセルされるらしいので、それでも良いといえば良いかと。
コネクションを切ったときにキャンセルされるのかどうか、確証が持てない・・・

コネクションを強制的に切った場合

調べて見たら、どうやらキャンセルはされずにElasticsearch内部では処理が続く。なので、コネクションをぶちぶち切って、都度新しいリクエストを送るとリソースを使いまくる(Rallyなんかはデフォルト60秒でコネクションを切るので、それはそれはヤバイことになるかな・・・)。

タイムアウト(クエリパラメータ、リクエストボディ)を指定した場合

QueryPhase でシャードに対して実行したクエリが timeout 指定時間以内に戻らない場合にタイムアウトと判定。タイムアウトになると、当該シャードに対する FetchPhase は実行されない。結果として、FetchPhase が実行されたシャードに関する結果だけが返る。

タイムアウトが起きていなければ、レスポンスは

{"took":704,"timed_out":false,"_shards":{...

となるが、タイムアウトになった QueryPhase があると、

{"took":704,"timed_out":true,"_shards":{...

となる。

2
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
5