web-dev-qa-db-ja.com

エラスティック検索、複数のインデックスと1つのインデックス、異なるデータセットのタイプ

MVCパターンを使用して開発されたアプリケーションがあり、その複数のモデルにインデックスを付けたいと考えています。つまり、各モデルのデータ構造は異なります。

  • モデルごとに複数のインデックスを使用するか、モデルごとに同じインデックス内に型を持つ方が良いでしょうか?どちらの方法でも、異なる検索クエリが必要になると思います。私はこれから始めました。

  • データセットが小さい場合または大きい場合、両方の概念の間にパフォーマンスの違いはありますか?

誰かが私にその目的のためにいくつかの良いサンプルデータを私に勧めることができれば、私は自分で2番目の質問をテストします。

155
burzum

両方のアプローチには異なる意味があります。

Elasticsearchのデフォルト設定を使用していると仮定すると、1つのインデックスが5つのシャードを使用するため、各モデルに1つのインデックスがあるとシャードの数が大幅に増加します。 1つのインデックスに5つのオブジェクトタイプがある場合でも、5つのシャードを使用します。

各データモデルをインデックスとして持つことの意味:

  • インデックス内での検索が効率的かつ高速です。異なるシャードに分散されるため、各シャードのデータ量を少なくする必要があるためです。
  • 2つ以上のインデックスからデータモデルの組み合わせを検索すると、クエリがインデックス全体でより多くのシャードに送信され、コンパイルされてユーザーに返送されるため、オーバーヘッドが発生します。
  • データセットが小さい場合は、追加のシャードが作成されるたびにより多くのストレージが発生し、パフォーマンスの向上はわずかなので、推奨されません。
  • 専用のシャードが特定のデータを保存しているため、Elasticsearchの処理が容易になるため、データセットが大きく、クエリの処理に時間がかかる場合に推奨されます。

各データモデルをインデックス内のオブジェクトタイプとして持つことの意味:

  • インデックスの5つのシャード内により多くのデータが保存されます。つまり、異なるデータモデルでクエリを実行した場合のオーバーヘッドの問題は少なくなりますが、シャードのサイズは非常に大きくなります。
  • シャード内のデータが増えると、Elasticsearchが検索するのに時間がかかるようになります。これは、フィルタリングするドキュメントが増えるためです。
  • 1テラバイトのデータを処理していることを知っていて、Elasticsearchマッピングの異なるインデックスまたは複数のシャードにデータを分散していない場合はお勧めしません。
  • 各シャードがハードウェアのスペースを占有するため、パフォーマンスの向上のためにストレージスペースを無駄にしないため、小さなデータセットに推奨されます。

少なすぎるデータと少なすぎるデータを尋ねる場合通常、プロセッサ速度とハードウェアのRAM、Elasticsearchのマッピングの各変数内に保存するデータ量、およびクエリ要件に依存します。クエリで多くのファセットを使用すると、応答時間が大幅に遅くなります。これに対する簡単な答えはありません。ニーズに応じてベンチマークを行う必要があります。

177
Jonathan Moo

ジョナサンの答えはその時点では正しかったものの、世界は動き続けており、ElasticSearchの背後にいる人々は、複数のタイプのサポートを廃止する長期計画を持っているようです。

到達先:親/子をサポートしながら、Elasticsearchから型の概念を削除したい

したがって、新しいプロジェクトでは、インデックスごとに1つのタイプのみを使用すると、最終的にElasticSearch 6.xへのアップグレードが容易になります。

41
Danack

ジョナサンの答えは素晴らしいです。考慮すべき点をいくつか追加します。

  • 選択したソリューションごとにシャードの数をカスタマイズできます。 15個のプライマリシャードを持つ1つのインデックスを使用することも、5個のシャードに対して3つのインデックスに分割することもできます-パフォーマンスの観点は変わりません(データが均等に分散されると仮定)
  • データの使用について考えてください。すなわち。キバナを使用して視覚化する場合、特定のインデックスを含める/除外するのは簡単ですが、ダッシュボードでタイプをフィルタリングする必要があります
  • データ保持:アプリケーションログ/メトリックデータでは、異なる保持期間が必要な場合は異なるインデックスを使用します
13
Marcel Matus

上記の答えは両方とも素晴らしいです!

いくつかのタイプの例をインデックスに追加しています。図書館で本を検索するアプリを開発しているとします。ライブラリの所有者に尋ねる質問はほとんどありませんが、

質問:

  1. 何冊の本を保存する予定ですか?

  2. 図書館にはどのような本を保管しますか?

  3. 本をどのように検索しますか?

回答:

  1. 5万〜7万冊の書籍を保存する予定です(概算)

  2. テクノロジー関連の本(コンピューターサイエンス、機械工学、化学工学など)が15,000から20,000冊、歴史書が15,000冊、医学の本が100,000冊あります。 10 kの言語関連書籍(英語、スペイン語など)

  3. 著者の名、著者の姓、発行年、発行者の名前で検索します。 (これにより、インデックスにどの情報を保存するべきかがわかります)

上記の回答から、インデックス内のスキーマはこのように見えるはずです。

//これは単なる例であり、正確なマッピングではありません

            "yearOfPublish":{
                "type": "integer"
            },
            "author":{
                "type": "object",
                "properties": {
                    "firstName":{
                        "type": "string"
                    },
                    "lastName":{
                        "type": "string"
                    }
                }
            },
            "publisherName":{
                "type": "string"
            }
        }

上記を達成するために、Booksと呼ばれる1つのインデックスを作成し、さまざまなタイプを持つことができます。

インデックス:本

タイプ:科学、芸術

(または、より多くの本がある場合は、テクノロジー、医学、歴史、言語など、多くのタイプを作成できます)

ここで注意すべき重要なことは、スキーマは似ていますが、データは同一ではないということです。もう1つの重要なことは、保存している合計データです。

インデックス内の異なるタイプを使用する場合、上記が役立つことを願っています。異なるスキーマがある場合は、異なるインデックスを検討する必要があります。少ないデータの小さなインデックス。ビッグデータのビッグインデックス:-)

1
Sourav