弾性探索凝集の性能への潜入


AntiticSearchは、私たちがこれまでに気づいていないパフォーマンスを向上させるために、我々はそれをさらに改善するために何ができるか?これは、私たちが使っているいくつかの重い集計のパフォーマンスを調べるとき、私自身に尋ねたものです.この投稿では、エラスティックサーチでキャッシュする基本的な説明を行い、キャッシュとクエリーの相互作用を検証する2つの実験を行います.

どのようにFlasticSearchキャッシュですか?


FlasticSearchは、それが可能な限り迅速に対応することを確認するために一緒にすべての作業のキャッシュのさまざまなレベルを持っています.すべてのキャッシュレベルには同じ約束があります.つまり、あなたが得る応答は、インデックスに現在存在しているように、データと高速でマッチする(またはほとんど一致する)ことです.

リクエストキャッシュ


エラスティックサーチは独自のインテリジェントリクエストキャッシュを持っています.このキャッシュは、キャッシュが常に正確であることを確認する基礎となるインデックスへの更新に基づいて更新されます.もちろんいくつかのGotchaがあります.

Requests where size is greater than 0 will not be cached even if the request cache is enabled in the index settings.


要求キャッシュが働かないかもしれない他の理由は、あなたの応答がすべての要求で変化する値を含むときです.たとえば、あなたの応答が現在の日付またはいくつかのランダムに生成された数を含んでいるなら、それは応答を容認できないでしょう.
あなたがリクエストキャッシュを調整する方法についてもっと知りたいなら、the documentationを見てください.

クエリキャッシュ


より深いレベルでは、フィルター型クエリの結果はビットセットと呼ばれるバイナリ表現にキャッシュされます.リクエストキャッシュと同じように、インデックス内の関連するものが更新されるたびに、このキャッシュは自動的に更新されます.エラスティックサーチは、多数のドキュメントに適用されるクエリをキャッシュします.

Only segments that hold more than 10,000 documents (or 3% of the total documents, whichever is larger) will cache the bitset.


小さいセグメントに対しては、クエリを評価するのがたぶんより速いからです.どのように多くの弾性率はすでにキャッシュなしでパフォーマンスを最適化している、それは非常にキャッシュを追加することによって物事を遅くするのは簡単です.クエリキャッシュhereに関する詳細な情報を見つけることができます.

フィールドデータキャッシュ


フィールドデータキャッシュは集約に非常に関連しています.ドキュメントが以下のように設定します.

It loads all the field values to memory in order to provide fast document based access to those values.


フィールドデータキャッシュのために予約された十分なメモリがないと、アグリゲーションが遅くなります.フィールドデータキャッシュの使用状況を監視し、お客様のニーズに合わせて調整できます.より多くを学ぶために、hereに行ってください.

共通のクエリ要素を抽出するのに役立ちますか?


クエリキャッシュは、現実世界の集約の多くのために非常にbenifialされるように思える.フィルタリングされたインデックスのサブセットにいくつかの集約を行うのは非常に一般的です.エラスティック検索はこの場合のフィルタリングを再利用できますか?または、我々はそれを助けることができますか?
次のクエリのパフォーマンスを比較しましょう.最初のクエリには、両方のアグリゲーションに対して別々に指定されたフィルターがあります.
{
  "size": 0,
  "aggregations": {
    "1": {
      "filter": {
        "match": {
          "search_field": "text"
        }
      },
      "aggregations": {
        "items": {
          "top_hits": {
            "size": 100,
            "_source": {
              "includes": "field1"
            }
          }
        }
      }
    },
    "2": {
      "filter": {
        "match": {
          "search_field": "text"
        }
      },
      "aggregations": {
        "items": {
          "top_hits": {
            "size": 100,
            "_source": {
              "includes": "field2"
            }
          }
        }
      }
    }
  }
}
番目のクエリーは、このフィルタをより高いレベルに抽出します.これは、集約が結果を共有する必要があります.フィルタをboolで包む必要がある.フィルタは、得点が同じであることを確認します.
{
  "query": {
    "bool": {
      "filter": [
        {
          "match": {
            "search_field": "text"
          }
        }
      ]
    }
  },
  "size": 0,
  "aggregations": {
    "1": {
      "top_hits": {
        "size": 100,
        "_source": {
          "includes": "field1"
        }
      }
    },
    "2": {
      "top_hits": {
        "size": 100,
        "_source": {
          "includes": "field2"
        }
      }
    }
  }
}
私たちはこのテストのためにリクエストキャッシュを無効にしました、しかし、クエリキャッシュとフィールドデータキャッシュはまだ彼らの仕事をすることができました.フィルタクエリのセグメントが実際に10000のドキュメントより大きいことを確認しました.これは、クエリキャッシュがこのために起動する必要があることを意味し、これらの2つのクエリ間のクエリ時間の違いはありません.それはまさに私たちが見るものです.

これらの2つの解決策の間にはパフォーマンスの違いはありません.クエリーキャッシュがうまく仕事をしているようです.クエリキャッシュに対する要件を念頭に置いて、おそらく2番目のバリエーションを好むでしょう.フィールドデータキャッシュも同様にうまく動作します.

集約は並列に実行されますか?


昼間の仕事では、1つのクエリーに多数の集約を置く場合が多い.これは私が疑問に思って、アグリゲーションを実際に並列に実行するか?または、例えば、一まとまりあたりのクエリーでmsearchを行うことによって、応答時間を改善することができましたか?
このテストでは、以前と同じクエリを実行します.つのクエリで1 , 2 , 5 , 10の集約をテストします.集約を分割するときに比較し、各集約は独自のクエリを取得します.

それぞれの集約を独自のクエリに与え、msearchを実行すると、有意なパフォーマンスが向上します.10集計では,スピードアップは第2因子に近い.このテストでは、2つの利用可能なCPUのを持つDockerコンテナの中にエラスティックサーチインスタンスが走っていたので、このスピードアップはあなたが得ることが期待できる最高のものです.
集約がデフォルトで並列に実行されないことは明らかです.したがって、複数のクエリに集約を分割すると、応答時間を改善したい場合に意味があります.これはCPUがボトルネックでないときにのみ適用されます.なぜなら、クエリを分割することによって、より多くのCPU時間を合計することになるからです.

結論


だから、一般的なクエリ要素を抽出するのに役立ちますか?一般に、あなたはそうしなければなりません.これらのケースに対して、AntiticSearchが最適化できるので、必要はありません.クエリキャッシュに対してフィルタが正しくない場合には、集約の中でより高い一般的なクエリ要素を移動すると、パフォーマンスが少し向上します.
また、集約は並列に実行されますか?デフォルトではない.msearchを使用してそれらを分割するのは、あなたがまだCPUに限られていない限り、スマートかもしれません.完全に利用されていないクラスタでは、これは応答時間を大幅に改善することができる.