ElasticSearch の学習ノート - 第 4 章 ES シャーディングの原理と読み取りおよび書き込みプロセスの詳細な説明

4. ESシャーディング原理と読み書きプロセスの詳細説明

ES シャーディングの原理と読み取りおよび書き込みプロセスを学習する前に、まず ES の中心的な概念と ES クラスター環境の関連知識をいくつか学習する必要があります。

4.1 ESコアの概念

4.1.1 インデックス

インデックスは MySQL のデータベースに相当し、似たような特性を持つドキュメントの集合です。

4.1.2 タイプ

タイプは MySQL のテーブルに相当します。タイプはインデックスの論理的な分類/パーティションであり、そのセマンティクスはユーザーによって完全に決定されます。通常、タイプは、共通のフィールドのセットを持つドキュメントに対して定義されます。ES のバージョンが異なれば、使用するタイプも異なります。

バージョン タイプ
5.x 複数のタイプをサポート
6.x タイプは 1 つだけです
7.x カスタム タイプはデフォルトではサポートされなくなりました。デフォルトは _doc です。

4.1.3 ドキュメント

ドキュメントは MySQL の行に相当し、インデックスを作成できる基本的な情報単位、つまりデータです。

4.1.4 フィールド

フィールドは MySQL の列に相当します。つまり、フィールドは属性フィールドです。

4.1.5 マッピング

マッピングは、フィールドのデータ型、デフォルト値、アナライザー、インデックス付けできるかどうかなど、ES がデータを処理する方法を指定するために使用されます。

適切なマッピングを確立する方法が ES の使用の焦点です

4.1.6 シャーディング

インデックスに格納されるデータが大きすぎると、データ サイズがディスク領域の容量を超えたり、検索リクエストの処理効率が大幅に低下したりすることがあります。この問題を解決するために、Elasticsearch はインデックスを複数の部分に分割する機能を提供します。各部分は シャード と呼ばれますインデックスを作成するときに、必要なシャードの数を指定できます。各シャード自体も完全に機能する独立した「インデックス」であり、クラスター内の任意のノードに配置できます。

シャーディングの主な機能:

  • コンテンツ容量を水平方向に分割/拡張できます。
  • シャード上での分散並列操作が可能になり、パフォーマンスとスループットが向上します。

シャードがどのように分散されるか、そのドキュメントがどのように集約されるか、検索リクエストが Elasticsearch によって完全に管理されるかについては、ユーザーにとってはすべて透過的であるため、過度に心配する必要はありません。

注: Elasticsearch は Lucene に基づいて開発されていると前述しましたが、Lucene にはインデックス作成の概念もあります。ES では、Lucene インデックスはシャードと呼ばれ、Elasticsearch インデックスは複数のシャードのコレクションです。

ES がインデックス内を検索する場合、インデックス (Lucene インデックス) に属する各シャードにクエリ リクエストを送信し、各シャードの結果をグローバル結果セットにマージします。

4.1.7 コピー

ES を使用すると、ユーザーはシャードの 1 つ以上のコピーを作成できます。これらのコピーは複製されたシャード (レプリカ)と呼ばれ、コピーされたシャードはプライマリ シャードと呼ばれます。

コピーの主な機能:

  • シャード/ノードに障害が発生した場合に高可用性を提供します

    高可用性を実現するために、ES はレプリカ シャードとプライマリ シャードを同じノードに配置しません

  • 検索はすべてのレプリカで並行して実行できるため、検索ボリュームとスループットが拡張されます。

要約すると、各インデックスは複数のシャードに分割できます。インデックスは、0 回 (複製なしを意味します) または複数回複製することもできます。レプリケートされると、各インデックスにはプライマリ シャード (レプリケーション ソースとして使用される元のシャード) とレプリカ シャード (プライマリ シャードのコピー) が含まれます。シャードとレプリケーションの数はインデックスの作成時に指定できます。インデックスの作成後、ユーザーはいつでもレプリケーションの数を動的に変更できますが、シャードの数は変更できませんデフォルトでは、ES の各インデックスは 1 つのプライマリ シャードと 1 つのレプリカ シャードにシャード化されます。つまり、ES クラスター内に少なくとも 2 つのノードがある場合、インデックスには 1 つのプライマリ シャードと別のレプリケートされたシャード (1 つのフル コピー) が含まれます。この場合、各インデックスには合計 2 つのシャードがあるため、インデックスのニーズに基づいてシャードの数を決定する必要があります。

4.1.8 割り当て

プライマリ シャードまたはレプリカの割り当てを含む、ノードにシャードを割り当てるプロセス。レプリカの場合は、プライマリ シャードからデータをコピーするプロセスも含まれます。このプロセスはマスター ノードによって完了します。

クラスタ環境については次章で説明します。

4.2 クラスタ環境

4.2.1 システムアーキテクチャ

ここに画像の説明を挿入します

  • ノード

    実行中の各 ElasticSearch インスタンスはノードと呼ばれます

  • 集まる

    クラスターは、同じクラスター名を持つ 1 つ以上のノードで構成され、データと負荷の圧力を共有します。ノードがクラスターに追加またはクラスターから削除されると、クラスターはすべてのデータを均等に再分散します。

  • マスターノード

    ノードがマスター ノードとして選択されると、そのノードはインデックスの追加と削除、ノードの追加と削除など、クラスター全体のすべての変更を管理する責任を負い、通常はドキュメント レベルでのマスター ノードは関与しません。このように構成すると、クラスターにマスター ノードが 1 つしかない場合でも、トラフィックの増加がボトルネックになることはなく、任意のノードがマスター ノードになることができます。

ユーザーは、マスター ノードを含むクラスター内の任意のノードにリクエストを送信できます。各ノードはあらゆるドキュメントの場所を認識しており、ユーザー要求を、ユーザーが必要とするドキュメントを保存しているノードに直接転送できます。ユーザーがどのノードにリクエストを送信しても、必要なドキュメントを含むデータを各ノードから収集し、最終結果をクライアントに返す責任があります。Elasticsearch はこれらすべてを透過的に管理します。

4.2.2 クラスターのデプロイ

この例では、Windows 環境に単一マシンのクラスターをデプロイします。

具体的な手順は次のとおりです。

  1. 適切なディスク領域に、ElasticSearch-cluster フォルダーを作成します。

  2. ElasticSearch-cluster フォルダーに、es-7.8.0 解凍バージョンのコピーを 3 つコピーします。

ここに画像の説明を挿入します

  1. 各 ES の設定を変更します。設定ファイルのパスは、ES のインストール パス/config/elasticsearch.yml です。

    ノード-9201の主要構成

    #集群名称,同一个集群中的各个节点的这个配置项需要保持一致
    cluster.name: my-es
    #节点名称,同一个集群中的各个节点的这个配置项需要保证唯一
    node.name: node-9201
    #是否是主节点
    node.master: true
    #是否是数据节点,为false则表示不存储数据
    node.data: true
    #ip地址,由于是本机测试,所以指定为localhost
    network.host: localhost
    #http端口号
    http.port: 9201
    #tcp监听端口,同一个集群中的各个节点之间通过tcp协议进行相互通信
    transport.tcp.port: 9301
    #集群内可以发现的其他节点的tcp路径
    discovery.seed_hosts: ["localhost:9302","localhost:9303"]
    discovery.zen.fd.ping_timeout: 1m
    discovery.zen.fd.ping_retries: 5
    #初始化时被指定的主节点
    cluster.initial_master_nodes: ["node-9201"]
    #跨域配置
    http.cors.enabled: true
    http.cors.allow-origin: "*"
    

    ノード-9202の主要構成

    #集群名称,同一个集群中的各个节点的这个配置项需要保持一致
    cluster.name: my-es
    #节点名称,同一个集群中的各个节点的这个配置项需要保证唯一
    node.name: node-9202
    #是否是主节点
    node.master: true
    #是否是数据节点,为false则表示不存储数据
    node.data: true
    #ip地址,由于是本机测试,所以指定为localhost
    network.host: localhost
    #http端口号
    http.port: 9202
    #tcp监听端口,同一个集群中的各个节点之间通过tcp协议进行相互通信
    transport.tcp.port: 9302
    #集群内可以发现的其他节点的tcp路径
    discovery.seed_hosts: ["localhost:9301", "localhost:9303"]
    discovery.zen.fd.ping_timeout: 1m
    discovery.zen.fd.ping_retries: 5
    #初始化时被指定的主节点
    cluster.initial_master_nodes: ["node-9201"]
    #跨域配置
    http.cors.enabled: true
    http.cors.allow-origin: "*"
    

    ノード-9203の主要構成

    #集群名称,同一个集群中的各个节点的这个配置项需要保持一致
    cluster.name: my-es
    #节点名称,同一个集群中的各个节点的这个配置项需要保证唯一
    node.name: node-9203
    #是否是主节点
    node.master: true
    #是否是数据节点,为false则表示不存储数据
    node.data: true
    #ip地址,由于是本机测试,所以指定为localhost
    network.host: localhost
    #http端口号
    http.port: 9203
    #tcp监听端口,同一个集群中的各个节点之间通过tcp协议进行相互通信
    transport.tcp.port: 9303
    #集群内可以发现的其他节点的tcp路径
    discovery.seed_hosts: ["localhost:9301", "localhost:9302"]
    discovery.zen.fd.ping_timeout: 1m
    discovery.zen.fd.ping_retries: 5
    #初始化时被指定的主节点
    cluster.initial_master_nodes: ["node-9201"]
    #跨域配置
    http.cors.enabled: true
    http.cors.allow-origin: "*"
    

4.2.3 クラスタの起動

  • 起動する

    セクション 2.1 を参照して、node-9201、node-9202、node-9203 を順番に起動します。

  • テスト(http)

ここに画像の説明を挿入します

{
    
    
    "cluster_name": "my-es", // 集群名称
    "status": "green",       // 当前节点的状态
    "timed_out": false,      // 是否超时
    "number_of_nodes": 3,    // 节点总数  
    "number_of_data_nodes": 3, // 数据节点总数
    "active_primary_shards": 0,
    "active_shards": 0,
    "relocating_shards": 0,
    "initializing_shards": 0,
    "unassigned_shards": 0,
    "delayed_unassigned_shards": 0,
    "number_of_pending_tasks": 0,
    "number_of_in_flight_fetch": 0,
    "task_max_waiting_in_queue_millis": 0,
    "active_shards_percent_as_number": 100.0
}

4.2.4 フェイルオーバー

  • その後の学習を容易にするために、クラスター内に次のインデックスを作成します。

    ユーザー インデックスを作成し、3 つのプライマリ シャードと 1 つのレプリカ (プライマリ シャードごとに 1 つのレプリカ) を割り当てます。

    {
          
          
     "settings" : {
          
          
     "number_of_shards" : 3,
     "number_of_replicas" : 1
     }
    }
    
  • ブラウザプラグインを使用してクラスタの全体的なステータスを表示します。

    ノードnode-9201とノードnode-9202のみを起動します。

    elasticsearch-head プラグインを使用して、指定したクラスターのステータスをブラウザーから直接表示します。

    ここに画像の説明を挿入します

    上の図からわかるように、この時点ではクラスターの健全性の値は緑色です。これは、現在のクラスターでは 3 つのプライマリ シャードと 3 つのレプリカが異なるノードに正しく割り当てられていることを意味します (以前に紹介したことに注意してください)。プライマリ シャードとそのレプリカが同じノード上にある場合は安全ではありません)。

    これは、クラスター内のいずれかのノードに問題があった場合でも、データはそのまま残ることを意味します。最近インデックス付けされたすべてのドキュメントはプライマリ シャードに保存され、対応するレプリカ シャードに並行してコピーされます。これにより、プライマリ シャードとレプリカ シャードの両方からドキュメントを取得できるようになります。

    つまり、上記ノードnode-9201がダウンしても、ESのクエリ機能には影響せず、コピーから文書データを取得することができます。

4.2.5 水平方向の拡張

アプリケーションが一定期間実行され、ES 内のデータ量が徐々に増加した場合、ES クラスターに新しいノードを追加することで水平方向の拡張を実現できます。3 番目のノードが開始されると、クラスターには 3 つのノードが含まれ、負荷を分散するためにシャードが再割り当てされます。

この時点で、ノードnode-9203を起動し、クラスターのシャード割り当てを再度確認します。

ここに画像の説明を挿入します

上の図からわかるように、新しいノードがクラスターに参加すると、クラスターはシャードを再配布します。このとき、各ノードのハードウェア リソース (CPU、RAM、I/O) がより少ないシャードで共有されることになり、各シャードのパフォーマンスが向上します。

シャーディングは、ノード上のすべてのリソースを使用できる、完全に機能する検索エンジンです。6 つのシャード (3 つのプライマリ シャードと 3 つのレプリカ シャード) を含むインデックスは、最大 6 つのノードまで拡張できます。各ノードには 1 つのシャードがあり、各シャードには、配置されているノードのすべてのリソースが含まれます。

では、6 ノードを超えて拡張したい場合はどうすればよいでしょうか?

プライマリ シャードの数は、インデックスの作成時に決定されます実際、この数値は、このインデックスが保存できるデータの最大量を定義します。(実際のサイズは、データ、ハードウェア、および使用シナリオによって異なります。) ただし、読み取り操作 (データの検索と返し) は、プライマリ シャードまたはレプリカ シャードのいずれかで同時に処理できるため、レプリカ シャードが多いほど優れています。スループットが高くなります。

したがって、ES を使用すると、ユーザーは実行中のクラスター上のレプリカ シャードの数を動的に調整でき、オンデマンドでクラスターをスケールするためにレプリカの数を調整できます。

  • レプリカの数を 2 に調整します (プライマリ シャードごとに 2 つのレプリカ シャード)。

    ES クラスター http/localhost:9201/index name/_settings にPUTリクエストを送信し、リクエスト本文に次の内容を追加します。

    {
          
          
        "number_of_replicas":2
    }
    

    ここに画像の説明を挿入します

  • クラスターのステータスを表示する

    ここに画像の説明を挿入します

    ユーザー インデックスには、3 つのプライマリ シャードと 6 つのレプリカ シャードの 9 つのシャードが含まれるようになりました。これは、各ノードに 1 つのシャードを備えたクラスターを 9 ノードまで拡張できることを意味します。元の 3 ノードと比較して、クラスター検索パフォーマンスを 3 倍向上させることができます。もちろん、同じ数のノードを持つクラスターにレプリカ シャードを追加するだけでは、各シャードがノードから取得するリソースが少なくなるため、パフォーマンスは向上しません。現時点では、スループットを向上させるために、より多くのハードウェア リソースを追加する必要がありますただし、レプリカ シャードが増えるとデータの冗長性が高まります。上記のノード構成によれば、データを失うことなく 2 つのノードを失う可能性があります。

4.2.6 障害への対処

ES クラスター内のマスター ノードがダウンすると (node-9201 がシャットダウンされる)、ES クラスターは新しいノードを選択します(これらの代替ノードは、構成ファイル内の node.master 構成項目が true であるノードです。以前にクラスター環境を構成した場合、3 つのノードのこの構成項目は true であるため、この時点で ES クラスターはノード 9202 とノード 9203 から 1 つのノードを新しいマスター ノードとして選択します)。

この時点での ES クラスター環境のステータスは、次のようにプラグインを通じて確認できます。

ここに画像の説明を挿入します

上の図からわかるように、現時点ではプライマリ ノードはノード 9203 です。ノード 9201 上の元のシャード 0 と 1 は両方ともプライマリ シャードです。新しいプライマリ ノードは、ノード上のこれらのシャードの対応するコピーを直ちにコピーします。 -9202。シャードはメイン シャードに昇格し、この時点でクラスターのステータスは黄色になります。**プライマリ シャードを昇格するこのプロセスは、スイッチを押すのと同じように瞬時に行われます。**3 つのプライマリ シャードがすべてありますが、各プライマリ シャードが 2 つのレプリカ シャードに対応する必要があるように設定しました。現時点では、レプリカ シャードは 1 つだけなので、クラスタは黄色の状態ですが、黄色の状態ですが、ESクラスタの機能は通常通り利用できます。

ノード 9201 を再起動すると、クラスターは不足しているレプリカ シャードを再度割り当てることができ、クラスターのステータスは以前の状態に復元されます。ノード 9201 が以前のシャードをまだ所有している場合は、それらを再利用しようとし、プライマリ シャードから変更されたデータ ファイルのみをコピーしようとします。以前のクラスターと比較すると、マスター ノードのみが切り替わりました。

ここに画像の説明を挿入します

上の図は、node-9201 を再起動した後のクラスターの状態を示しています。

注: 読者は、フェイルオーバー、水平拡張、障害対応に関するこれらの章を手動で操作して、ES クラスターの設計概念を理解するよう最善を尽くしてください。

4.2.7 ルート計算

  • ルーティングアルゴリズム

    ES クラスターにドキュメントを追加すると、ドキュメントはプライマリ シャードに保存されます。クラスター環境には複数のプライマリ シャードが存在するため、Elasticsearch はどのプライマリ シャードにこのドキュメントを配置すべきかをどのように認識するのでしょうか? ?

    上記の問題を解決するために、Elasticsearch はアルゴリズムを使用してルーティング計算を実行し、ドキュメントをどのシャードに配置するかを決定します。また、このアルゴリズムを使用して、クエリ時にドキュメントを保存するシャードを取得します。

    アルゴリズムは次のとおりです。

    shard = hash(routing) % number_of_primary_shards
    

    routing は変数値で、デフォルトはドキュメントの _id で、ユーザーが定義することもできます。

    このアルゴリズムの意味は次のとおりです: ルーティングのハッシュ値を取得し、それをプライマリ シャードの数で割って余りを取得します。結果の値は 0 (プライマリ シャードの数 - 1) の間の数値になります (カウントは 0 から始まります。3 つのプライマリ シャードとして) シャーディングの場合、範囲は 0 2) で、これはドキュメントが保存されるシャーディングの場所です。

    これは、インデックスを作成するときにプライマリ シャードの数を決定し、この数を決して変更しないことが重要である理由を説明しています。番号が変更されると、以前のすべてのルーティング値が無効になり、ドキュメントが見つからなくなるからです。

  • カスタムルーティング

    すべてのドキュメント API (get、index、delete、bulk、update、および mget) は、ルーティングと呼ばれるルーティング パラメーターを受け入れます。これにより、シャードへのドキュメントのマッピングをカスタマイズできます。カスタム ルーティング パラメーターを使用すると、すべての関連ドキュメント (同じユーザーに属するすべてのドキュメントなど) が同じシャードに保存されるようにすることができます。

    この部分については、後続の章で詳しく説明します。

4.3 シャーディング制御

このセクションを説明するときは、 3 つのプライマリ シャードと 1 つのレプリカがあるクラスター環境で次のクラスター テスト インデックスを使用します

ここに画像の説明を挿入します

このクラスターでは、各ノードはあらゆるリクエストを処理できます。各ノードはクラスター内のドキュメントの場所を認識しているため、要求を必要なノードに直接転送できます。次の例では、すべてのリクエストを調整ノードと呼ばれるノード 9201 に送信します

注: 作業では、負荷分散を実現するために、通常、すべてのリクエストを同じノードに送信するのではなく、クラスター内のすべてのノードがポーリングされ、リクエストを共同で送信できるようになります。

4.3.1 書き込み手順(大まかな手順)

Elasticsearch では、(完全な) ドキュメントの追加、削除、および変更のリクエストは書き込みプロセスに属します。書き込みプロセスは、レプリカ シャードに同期される前に、プライマリ シャードで完了する必要があります。

たとえば、次のようにリクエストします。

PUT/DELETE http://localhost:9200/cluster-test/_doc/1001

特定のドキュメントを追加、完全に更新、または削除する

ドキュメントの追加時に主キーが指定されていない場合、ES は主キーを自動的に生成し、自動生成された主キーに基づいてルーティング計算を実行します。

次に、例を使用して、Elasticsearch での書き込みプロセスが ES クラスターでどのように実行されるかを学習します。

(完全な) ドキュメントを追加、削除、変更するリクエストをノード 9201 に送信すると、ES は次の処理を実行します。

  1. ノード 9201 は、ドキュメントの _id (ルーティング パラメーターが指定されている場合は、対応するパラメーターが使用されます) を使用してルート計算を実行し、ドキュメントが属するシャードを取得します。たとえば、ドキュメントがシャード 0 に属している場合、ノードは-9201 ノードはリクエストをノード 9202 に転送します (プライマリ シャード 0 がノード 9202 上にあるため)。
  2. ノード 9202 はプライマリ シャード 0 でリクエストを処理します。成功した場合は、リクエストをノード 9203 に転送し、レプリカ シャード 0 に同じ処理を実行させます。レプリカ シャード 0 が正常に処理されると、ノード 9202 に通知され、次にノード 9202 が処理の成功結果を通知します。 .ノード-9201。
  3. node-9201 はクライアント要求の結果を返します。

具体的な図は次のとおりです。

ここに画像の説明を挿入します

クライアントが成功の応答を受信すると、ドキュメントの変更はプライマリ シャードとすべてのレプリカ シャードで実行されており、変更は安全です。もちろん、Elasticsearch は、ユーザーがこのプロセスに介入するためのいくつかのパラメーターも提供します (これにより、データのセキュリティを犠牲にしてパフォーマンスをさらに向上させることができます) もちろん、Elasticsearch はすでに十分に高速であるため、これらのパラメーターはめったに使用されません。

次の表に、このプロセスに介入できるいくつかのパラメータとその意味を示します。

パラメータ 意味
一貫性 一貫性、つまり一貫性整合性パラメータ値は、 1 (プライマリ シャードのステータスが正常である限り、書き込み操作は実行されます)、すべて(書き込み操作を実行する前に、すべてのプライマリ シャードとレプリカ シャードのステータスが正常である必要があります)に設定できます。およびクォーラム(大部分のシャードは通常の状態であり、書き込み操作が許可されます)、デフォルト値はクォーラムです。これは、デフォルト設定では、書き込み操作を実行する前であっても、プライマリ シャードには指定された数が必要であることを意味します(クォーラム) 書き込み操作は、シャード コピーがアクティブで使用可能な状態にある場合にのみ実行されます。これは、ネットワーク障害が発生した場合に書き込み操作が行われ、データの不整合が発生する可能性を回避するためです。指定された数量 (クォーラム) の計算式は、 int((primary +number_of_replicas) / 2) + 1です。このうち、number_of_replicas は、現在アクティブなレプリカの数ではなく、インデックス設定で設定されたレプリカの数を指します。
タイムアウト 十分なレプリカ シャードがない場合はどうなりますか? Elasticsearch はさらにシャードが表示されるまで待機します。デフォルトでは最大 1 分間待機します。ユーザーは、タイムアウト パラメーターを使用して待機時間を調整できます。

注: 新しいインデックスを作成するとき、インデックス レプリカの数はデフォルトで 1 に設定されます。これは、指定された数を満たすために 2 つのアクティブなシャード レプリカが必要であることを意味します。これらのデフォルト設定により、単一ノードで書き込み操作を実行できなくなります。したがって、ES では、指定された数量は、number_of_replicas が 1 より大きい場合にのみ有効になると規定しています。

4.3.2 読み取り処理(大まかな処理)

読み取り処理、ここで説明するのは、ルーティングまたは ID に基づいて指定された文書を読み取る処理です。(検索データ処理とは区別することに注意してください)。

たとえば、リクエストは GET http://localhost:9201/cluster-test/_doc/1001 です。

次に、例を使用して、Elasticsearch の読み取りプロセスが ES クラスターでどのように実行されるかを学習します。

データを読み取るリクエストをノード 9201 に送信すると、ES は次の処理を実行します。

  1. ノード 9201 は、ドキュメントに対してルーティング計算を実行し、ドキュメントが属するシャードを取得します。たとえば、シャード 0 に属し、ラウンドロビン ランダム ポーリング アルゴリズムを使用して、プライマリ シャード 0 とそのすべてのシャードの中から 1 つをランダムに選択します。レプリカシャード。読み取りリクエストの負荷分散を行い、ノード 9201 ノードはリクエストをノード 9203 などの特定のノードに転送します。

    ルーティング パラメーターを使用するか、ID を直接使用してルートを計算し、データを読み取ります。

  2. ノード-9203 はレプリカ シャード 0 でリクエストを処理し、クエリ結果をノード-9201 に返します。

  3. ノード-9201 はクエリ結果をクライアントに返します。

具体的な図は次のとおりです。

ここに画像の説明を挿入します

4.3.3 アップデート手順(大まかな手順)

ドキュメントの部分的な更新では、前に説明した読み取りプロセスと書き込みプロセスを組み合わせます。

次に、例を使用して、Elasticsearch の更新プロセスが ES クラスターでどのように実行されるかを学習します。

データを更新するリクエストをノード 9201 に送信すると、ES は次の処理を実行します。

  1. ノード 9201 ノードは、ドキュメントに対してルート計算を実行し、ドキュメントが属するシャード (たとえば、シャード 0 に属します) を取得します。

  2. ノード 9201 ノードは、リクエストをノード 9202 ノードに転送します (プライマリ シャード 0 はこのノード上にあります)。

  3. ノード 9202 ノードは、更新リクエストを処理し、ドキュメントを読み取り、_source フィールドの JSON データを変更し、ドキュメントのインデックスを再作成しようとします(この時点で別のプロセスがドキュメントを変更している場合は、ステップ 3 が再試行されます) retry_on_conflict 回数を超えました) 諦めます)。

    前述のドキュメントの再インデックス付けとは、実際には、ドキュメントの古いバージョンに削除のマークを付け (つまり、.del ファイル内のドキュメントの古いバージョンにマークを付け)、その後ドキュメントの新しいバージョンを生成し、この新しいバージョンを書き込むことを意味します。ドキュメントのドキュメント。

  4. ノード 9202 ノードがドキュメントの更新に成功すると、ドキュメントの新しいバージョンがノード 9203 ノードに転送され、ノード 9203 ノードはドキュメントの新しいバージョンのインデックス (逆インデックス) を再構築します。

    このステップでは、セカンダリ ノードはプライマリ ノードと同じことを行います。(ドキュメントの古いバージョンを削除済みとしてマークし、ドキュメントの新しいバージョンを書き込みます)

  5. ノード 9203 ノードが正常に更新されると、応答がノード 9202 ノードに返されます。

  6. ノード 9202 ノードは、成功した更新結果をノード 9201 ノードに返します。

  7. node-9201 ノードは結果をクライアントに返します。

具体的な図は次のとおりです。

ここに画像の説明を挿入します

:

プライマリ シャードが変更をレプリカ シャードに転送する場合、更新リクエストは転送されません。代わりに、完全なドキュメントの新しいバージョンが転送されます。これらの変更はレプリカ シャードに非同期的に転送され、送信されたのと同じ順序で到着するという保証はないことに注意してください。Elasticsearch が変更リクエストを転送するだけの場合、変更が間違った順序で適用され、ドキュメントが破損する可能性があります。

4.3.4 複数文書操作処理(大まかな処理)

ここでの複数ドキュメント操作プロセスとは、mget リクエストとバルク リクエストを指します。

mgetリクエストの処理フロー:

  1. クライアントは、mget リクエストをノード 9201 ノードに送信します。

  2. ノード 9201 ノードは、ノードごとに複数ドキュメントのフェッチ要求を作成し、これらの要求をすべてのノード (ノード 9202 やノード 9203 など) に並行して転送します。

  3. ノード 9202 ノードとノード 9203 ノードがリクエストを処理した後、結果がノード 9201 ノードに応答されます。

  4. ノード 9201 ノードは、要求結果をクライアントに応答します。

    全体の処理は get リクエストのバッチに相当します。各ノードによるリクエストの処理については、先に紹介した読み取り処理を参照してください。

一括リクエストの処理フロー:

  1. クライアントは一括リクエストをノード 9201 ノードに送信します。

  2. node-9201 ノードは、各ノードのバッチ リクエストを作成し、これらのリクエストをプライマリ シャードを含む各ノードに並行して転送します。

  3. すべてのノードがリクエストを処理した後、結果がノード 9201 ノードに応答されます。

  4. ノード 9201 ノードは、要求結果をクライアントに応答します。

    全体の処理は新規リクエスト、削除リクエスト、更新リクエストの一括処理に相当しますが、各ノードによるリクエストの処理については先に紹介した書き込み処理を参照してください。

4.4 シャーディングの原則

4.4.1 文書検索(段落単位で検索)
  • 不変の逆インデックス

    早期の全文検索では、ドキュメント コレクション全体に対して大規模な転置インデックスが作成され、それがディスクに書き込まれます。新しいドキュメントに対して転置インデックスを作成する必要がある場合は、転置インデックス全体、つまり転置インデックスを置き換える必要があります。一度ディスクに書き込まれた後は変更できず、完全に置き換えることしかできません。

    この利点は次のとおりです。

    1. ロックは必要ありません。インデックスを更新しない場合は、複数のプロセスが同時にデータを変更することを心配する必要はありません。

    2. インデックスがカーネルのファイル システム キャッシュに読み込まれると、その不変性によりインデックスはそこに残ります。ファイル システム キャッシュに十分なキャッシュがある限り

      スペースがある場合、ほとんどの読み取りリクエストはディスクにアクセスせずに直接メモリをリクエストします。これにより、パフォーマンスが大幅に向上します。

    3. 単一の大きな逆インデックスを書き込むと、データが圧縮され、ディスク I/O の量と、メモリにキャッシュする必要があるインデックスの使用量が削減されます。

    この欠点も非常に明白です。新しいドキュメントを検索可能にする必要がある場合は、転置インデックス全体を再構築する必要があり、転置インデックスに含めることができるデータ量やインデックスに大きな制限が課せられます。更新頻度には大きな制限があります。

  • 転置インデックスを動的に更新する

    転置インデックスの不変性を保ちながら転置インデックスを更新するために、Elasticsearch は転置インデックス全体を直接書き換えるのではなく、新しい補助インデックスを追加することで最近の変更を反映するように転置インデックスを補完する方法を採用しています取得中、各転置インデックスは順番にクエリされ、最も早いクエリが完了した後に結果がマージされます。これにより、転置インデックスの頻繁な再構築によるパフォーマンスの低下を回避できます。

  • セグメントから探す

    Elasticsaerch は Lucene をベースに開発されており、セグメントごとに検索するという概念があり、各セグメント自体が転置インデックスになります。セグメントに加えて、コミット ポイントの概念もあり、現在利用可能なすべてのセグメントを記録します。上記の新しい追加の転置インデックスは、実際には新しいセグメントです。

    セグメントと提出ポイントの関係を次の図に示します。

ここに画像の説明を挿入します

  • セグメンテーション思考でデータを書き込む

    新しいドキュメントがインデックスに追加されると、次のプロセスが実行されます (ここでは、セグメントとサブミッション ポイントの使用のみに焦点を当てます)。

    1. 新しいドキュメントがメモリ キャッシュに追加されます。

      この時のサブミッションポイント、セグメント、メモリキャッシュの模式図は以下の通り

      ここに画像の説明を挿入します

    2. 時々 [デフォルトでは、一定期間後、またはメモリ内のデータ量が一定の段階に達したとき、データはバッチでディスクに送信されます。(具体的な詳細については、書き込みプロセスの基本原理で後述します)]、キャッシュが送信されます。

      • 新しいセグメント (補足逆索引) がディスクに書き込まれます。

      • 新しいセグメントを含む新しいコミット ポイントが生成され、ディスクに書き込まれます。

        セグメントにコミット ポイントがあると、そのセグメントは読み取り権限のみを持ち、書き込み権限を失ったことを意味します。逆に、セグメントがメモリ内にある場合は、データの書き込み権限だけがあり、データの読み取り権限はありません。 , したがって、「取得できません」となります。

      • ディスクは同期されています - ファイル システム キャッシュで待機しているすべての書き込みはディスクにフラッシュされ、確実に物理ファイルに書き込まれます。

    3. 新しいセグメントが開かれ、そこに含まれるドキュメントを取得できるようになります。

    4. メモリ キャッシュがクリアされ、新しいドキュメントの受信を待機します

      この時のサブミッションポイント、セグメント、メモリキャッシュの模式図は以下の通り

      ここに画像の説明を挿入します

  • セグメンテーション思考によるデータの削除・更新

    データを削除する必要がある場合、データが配置されているセグメントは不変であるため、ドキュメントを古いセグメントから直接削除することはできません。この時点で、各送信ポイントには、削除されたデータ ID を保存する .del ファイルが含まれます。(論理削除)

    データを更新する必要がある場合、最初に削除操作が実行され、次に新しい操作が実行されます。つまり、古いデータが最初に .del ファイルに記録され、その後、更新されたデータが追加されます。新しいセグメントへ。

  • セグメンテーション思考に基づいてデータをクエリする

    すべてのセグメントでクエリ条件を満たすデータをクエリし、各セグメントのクエリ結果セットをマージして大きな結果セットを取得し、.del ファイルに記録されている削除されたデータを削除してクライアントに返します。

4.4.2 ほぼリアルタイムの検索

前のセクションで紹介したセグメンテーションの考え方に基づく新しいデータ プロセスから、新しいドキュメントが作成されるとき、データはまだメモリ キャッシュ内にあることがわかります。この時点では、このデータはクエリできないため、Elasticsearch のクエリはほぼリアルタイムで検索されます

新しいセグメントをディスクにコミットするときは、停電後にデータが失われないように、fsyncシステム コールを使用してデータが物理的にディスクに書き込まれるようにする必要があります。ただし、fsyncは非常に高価であるため、新しいデータや変更されたデータが追加されるたびにfsync を使用して物理的にデータをディスクに書き込むと、パフォーマンスが大幅に低下します。

Elasticsearch では、より軽量なアプローチを使用してドキュメントを取得可能にします。つまり、パフォーマンスを向上させるために、ドキュメントの書き込みから取得可能になるまでのプロセスからfsyncが削除されます。この目標を達成するために、Elasticsearch とディスクの間にはオペレーティング システムのファイル システム キャッシュ (OS キャッシュ)があります。

Elasticsearch のメモリ キャッシュ (Memory) とハードディスク (Disk) の間には、オペレーティング システムのファイル システム キャッシュ (OS キャッシュ) があります。

ここに画像の説明を挿入します

前のセクションで説明したように、メモリ インデックス バッファ内のドキュメントは新しいセグメントに書き込まれますが、ここでは新しいセグメントが最初にファイル システム キャッシュに書き込まれます** (この手順は低コストです) 。後でバッチでディスクにフラッシュされます(このステップは比較的高価です)**。ファイルがファイル システム キャッシュに既に存在する限り、他のファイルと同じように開いて読み取ることができます。つまり、取得することができます。

上で紹介したように、メモリ バッファ内のデータをファイル システム キャッシュに書き込むプロセスは、リフレッシュと呼ばれます。この操作は、デフォルトでは毎秒、またはメモリ バッファ内のデータが一定量のデータに達したときに実行されます (セクション 4.4.1 と同様)で説明されている)、これが、Elasticsearch がほぼリアルタイムの検索であると言われる理由です (ドキュメントの変更は 1 秒後に表示されるため、リアルタイムではありませんが、ほぼリアルタイムです)。

もちろん、Elasticsearch は、ユーザーがリクエスト/インデックス名/_refresh の送信などの更新操作を手動で実行するための更新 API を提供します。

フラッシュはコミットよりもはるかに軽い操作ですが、それでもパフォーマンスのオーバーヘッドが発生します。手動更新はテストを作成する場合には便利ですが、運用環境でドキュメントにインデックスを付けるたびに実行する必要はありません。代わりに、アプリケーションは Elasticsearch のほぼリアルタイムの性質を認識し、その欠点を受け入れる必要があります。

一部のシナリオでは、毎秒更新する必要はありません (ES に大量のログ ファイルを追加するなど)。上記のシナリオのニーズを満たすにはどうすればよいですか?

インデックスのrefresh_intervalを設定することで、リフレッシュ操作を実行する時間間隔を調整できます。

{
    
    
 "settings": {
    
    
 "refresh_interval": "30s" 
 }
}

fresh_interval は既存のインデックスを動的に更新できます。運用環境では、大規模な新しいインデックスを構築するときに自動更新をオフにし、インデックスの使用を開始するときに元に戻すことができます。

# 关闭自动刷新
PUT /索引名/_settings
{
    
     "refresh_interval": -1 } 
# 每一秒刷新
PUT /索引名/_settings
{
    
     "refresh_interval": "1s" }

このときのElasticsearchの書き込み処理は下図のようになります。(このフローチャートの目的は、Elasticsearch の書き込みプロセス設計のアイデアを段階的に提示することです。ここでのフローチャートは完全ではありません)

ここに画像の説明を挿入します

4.4.3 永続的な変更

前のセクションでは、リフレッシュ操作を通じてメモリ キャッシュからファイル システム キャッシュにドキュメント データを書き込む Elasticsearch の軽量クエリ メカニズムを紹介しました。このプロセスでは、fsync システム コールが削除されます。fsync がデータの書き込みに使用されていない場合ファイル システム キャッシュがハードディスクに書き込まれるとき(ファイル システム キャッシュのデータをハードディスクに書き込む操作をフラッシュと呼びます)、停電後やプログラムが終了した後でもキャッシュがまだ存在しているという保証はありません。通常は (つまり、永続性はありません)

信頼性を確保するために、Elasticsearch はデータの変更がディスクに永続化されることを保証する必要があります。この要件を達成するために、Elasticsearch はデータ損失を防ぐための補償メカニズムとしてトランスログ(トランザクション ログ) を追加します。行われていないすべての変更は次のとおりです。トランスログに記録され、データはディスクに保存されます。

translogに関しては、次の 3 つの質問を理解する必要があります。

  • データはいつトランスログに書き込まれますか?

    データがメモリ キャッシュに書き込まれると、データのコピーがトランスログに追加されます。(この部分は後ほど詳しく紹介します)

  • translog のデータをいつ使用するか?

    Elasticsearch が開始されると、最新の送信ポイントに基づいて永続化されたセグメントがロードされるだけでなく、トランスログ内のデータに基づいて永続化されていないデータがディスクに再永続化されます。

  • translog 内のデータはいつクリアする必要がありますか?

    ファイル システム キャッシュ内のデータがディスクにフラッシュされると、古いトランスログが削除され、新しい空のトランスログが生成されます。

    **デフォルトでは、フラッシュ操作は 30 分ごと、またはトランスログが大きすぎる場合 (デフォルトは 512MB) に実行されます。**通常は自動更新で十分です。Elasticsearch がインデックスを復元または再オープンしようとすると、トランスログ内のすべての操作を再実行する必要があるため、ログが短いほどリカバリが速くなります。

    トランスログの最大容量は、 index.translog.flush_threshold_size構成パラメータを通じて指定できます

トランスログを追加した後の Elasticsearch の書き込みプロセスは次の図に示されます (詳細なプロセスは、書き込みプロセスの基本原理のセクションで詳しく説明します)

ここに画像の説明を挿入します

translog はデータ損失を防ぐために使用されますが、データ損失のリスクもあります

  • トランスログの書き方を詳しく解説

    上記の書き込みフローチャートからわかるように、トランスログはメモリ キャッシュとディスク上にコピーを持っており、メモリ内のトランスログが fsync システム コールを通じてディスクにフラッシュされる場合にのみ信頼できます。

    トランスログ フラッシュ操作の実行には、非同期と同期の 2 つのモードがあります。デフォルトは、同期モードです。このモードは、パラメータindex.translog.durabilityを通じて調整でき、自動フラッシュ実行の時間はパラメータindex.translogを通じて制御できます。 .sync_interval .間隔。

    #异步模式
    index.translog.durability=async
    #同步模式
    index.translog.durability=request
    

    同期モードの場合、デフォルトでは、各書き込みリクエストの後に fsync 操作が実行されます。このプロセスは、プライマリ シャードとレプリカ シャードの両方で発生します。これは、リクエスト全体がプライマリ シャードとレプリカ シャードに fsync されることを意味します。クライアントトランスログがスライスのディスクに存在するまで、200 応答は得られません。(つまり、このモードでは、書き込み要求が成功した場合、このデータがディスク上のトランスログに書き込まれたことを意味し、データの信頼性が保証されます)。

    非同期モードの場合、fsync 操作はデフォルトで 5 秒ごとに実行され、このアクションは非同期です。これは、書き込みリクエストが 200 レスポンスを取得したとしても、このリクエストのデータが削除されたことを意味するものではないことを意味します.disk をディスク上のトランスログに変換する、つまり、この操作は信頼できません。(5 秒以内に電源が切れると、この部分のデータは失われます。)

    知らせ

    Elasticsearch のトランスログ フラッシュ操作はデフォルトで同期モードに設定されています。トランスログ フラッシュ操作はデータが変更されるたびに実行されますが、コストはデータが変更されるたびにセグメント フラッシュ操作を実行するよりもはるかに低いため、トランスログ補償メカニズムが使用されます。パフォーマンスとデータセキュリティのバランスをとるソリューションです。特別な要件がない限り、デフォルトでは同期モードが使用されます

4.4.4 セグメントの結合
  • 導入とプロセス

    セクション 4.4.2 で、1 秒ごとに実行されるリフレッシュ操作によって新しいセグメントが作成されることを紹介しましたが、長期間蓄積すると、インデックス内に多数のセグメントが存在します。サーバー リソースを過剰に占有するだけでなく、取得パフォーマンスにも影響します。

    前述したように、検索するたびに、すべてのセグメントでクエリ条件を満たすデータがクエリされ、その後、各セグメントでクエリされた結果セットがマージされるため、取得に時間がかかります。

    Elasticsearch は、セグメントが多すぎる問題を解決するためにセグメントのマージを使用します。Elasticsearch にはセグメントのマージを特に担当するバックグラウンド プロセスがあり、セグメントのマージ操作を定期的に実行します。

    セグメント結合の操作プロセスは次のとおりです。

    1. 複数の小さなセグメントを新しい大きなセグメントにマージします。マージ中、削除されたドキュメント (.del ファイルに保存されているドキュメント ID に対応するドキュメント) または更新されたドキュメントの古いバージョンは、新しいドキュメントに書き込まれません。段落内。
    2. 新しいセグメント ファイルをディスクにフラッシュします
    3. このコミット ポイント内のすべての新しいセグメント ファイルを特定し、古いセグメント ファイルとマージされたセグメント ファイルを除外します。
    4. 検索用に新しいセグメント ファイルを開きます
    5. すべての取得要求が小さいセグメント ファイルから大きいセグメント ファイルに転送されたら、古いセグメント ファイルを削除します。

    上記のプロセスはユーザーに対して透過的であり、Elasticsearch はドキュメントのインデックス作成およびドキュメントの検索時に自動的に実行します。マージされるセグメントには、ディスク上で送信されたインデックス、またはメモリ内でまだ送信されていないセグメントを使用できます。マージ プロセス中、現在のインデックス作成および検索機能は中断されません

  • セグメント統合による業績への影響

    セグメント マージ プロセスの上記の説明から、セグメント マージ プロセスには、セグメントの読み取りと新しいセグメントの生成だけでなく、セグメントのフラッシュ操作も含まれることがわかります。大量の I/O リソースと CPU リソースを消費し、検索パフォーマンスにも影響します。

    Elasticsearch では、デフォルトで一度にマージできるセグメントは 10 個のみです。セグメント容量が 5GB を超える場合、セグメントのマージには参加せず、マージ スレッドのデフォルト速度は 20MB/S です。

    次のパラメータを使用してセグメント結合ルールを調整できます。

    #更改配速为100MB/s
    {
          
          
        "persistent" : {
          
          
            "indices.store.throttle.max_bytes_per_sec" : "100mb"
        }
    }
    #设置优先被合并的段的大小,默认为2MB
    index.merge.policy.floor_segment
    #设置一次最多合并的段数量,默认为10个
    index.merge.policy.max_merge_at_once
    #设置可被合并的段的最大容量,默认为5GB
    index.merge.policy.max_merged_segment
    
4.4.5 書き込み処理の詳細説明

セクション 4.2.8.1 では、書き込みプロセスの一般的なプロセスを学び、クラスター環境全体でクライアントによって開始された書き込みリクエストを Elasticsearch がどのように処理するかを学びました。このセクションでは、ブロガーが書き込みリクエストを受信した後の各ノードの具体的な処理に基づいて書き込みプロセスを要約します。

執筆プロセスを要約すると次のようになります。

  1. クライアントは調整ノードに書き込みリクエストを送信します。
  2. 調整ノードは、ルーティング パラメーター (指定されていない場合、デフォルトはドキュメントの ID) に基づいてルーティング計算 (詳細についてはセクション 4.2.7 を参照) を実行し、ドキュメントが属するプライマリ シャードの場所を計算します。
  3. 調整ノードは、プライマリ シャードが配置されているノードに書き込みリクエストを転送します。
  4. プライマリ シャードが配置されているノードは書き込みリクエストを受信すると、単一ノードの書き込みプロセスに入ります。
  5. プライマリ シャードが配置されているノードが書き込みリクエストを処理した後、そのレプリカ シャードが配置されているすべてのノードに書き込みリクエストを並行して転送し、これらのノードがリクエストを受信した後、同じ処理を実行します。
  6. すべてのレプリカ シャードが配置されているノードが書き込みリクエストを処理した後、処理結果はプライマリ シャードが配置されているノードに返され、プライマリ シャードが配置されているノードは処理結果を調整ノードに返します。
  7. 調整ノードは結果をクライアントに返します。

Elasticsearch の単一ノードの書き込みプロセスの詳細を次の図に示します。

ここに画像の説明を挿入します

テキストの説明は次のとおりです。

  1. メモリ キャッシュ (**インデックス バッファ)** へのデータの書き込み

  2. トランザクション ログにデータを追加する ( translog )

  3. デフォルトでは、リフレッシュ操作は1 秒に 1 回実行され、メモリ キャッシュ内のデータを **ファイル システム キャッシュ (OS キャッシュ)** にリフレッシュし、セグメント (セグメント) を生成し、ユーザー検索用にセグメントを開きます。同時にメモリキャッシュ(インデックスバッファ)も行います。

  4. デフォルトでは、データが書き込まれるたびに、メモリ内のトランスログがfsync システム コールを通じてディスクに書き込まれます (フラッシュ)。

    同期モードでは、データが書き込まれるたびにディスクに fsync が行われます。

    非同期モードは 5 秒ごとにディスクに fsync します。

  5. デフォルトでは、30 分ごと、またはトランスログ サイズが 512M を超えた後、フラッシュが実行され、ファイル システム内のデータがディスクに書き込まれます。

    1. 新しいセグメントを生成してディスクに書き込みます
    2. 新しいセグメントを含む新しいコミット ポイントを生成し、ディスクに書き込みます。
    3. 古いトランスログを削除し、新しいトランスログを生成します
  6. Elasticsearch はマージ プロセスを開始し、バックグラウンドで小規模および中規模のセグメントをマージし、インデックス セグメントの数を減らします。このプロセスはファイル システムのキャッシュとディスクで実行されます。

4.4.6 読み込み処理の詳細説明

読み取りプロセスは次のように要約されます。

  1. クライアントは読み取りリクエストを調整ノードに送信します。
  2. 調整ノードは、ルーティング パラメーター (指定されていない場合、デフォルトはドキュメントの ID) に基づいてルーティング計算(詳細についてはセクション 4.2.7 を参照) を実行し、ドキュメントが属するシャードの場所を計算します。
  3. ラウンドロビン ランダム ポーリング アルゴリズムを使用して、ドキュメントが属するシャードの 1 つ (プライマリ シャードまたはレプリカ シャード) をランダムに選択し、そのシャードが配置されているノードにリクエストを転送します。
  4. ノードはリクエストを受信すると、単一ノードの読み取りプロセスに入ります。
  5. このノードは、クエリ結果を調整ノードに返します。
  6. 調整ノードはクエリ結果をクライアントに返します。

Elasticsearchの単一ノードの読み取りプロセスを次の図に示します。

ここに画像の説明を挿入します

テキストの説明は次のとおりです。

  1. ノードはデータ読み取りリクエストを受信します
  2. リクエストの doc ID フィールドに従ってトランスログ キャッシュのデータをクエリします。データがクエリされると、結果が直接返されます。
  3. 手順 2 で結果が見つからなかった場合は、ディスク上のトランスログからデータが照会され、データが照会された場合は、結果が直接返されます。
  4. 手順 3 で結果が見つからなかった場合は、ディスク内の各セグメントから結果が照会され、データが見つかった場合は結果が直接返されます。
  5. 前の手順の後、結果が見つからない場合は、null が返されます。

Elasticsearch がデータを読み取るとき、最初にトランスログからデータを取得しようとし、次に セグメント から取得しようとすることに注意してください。これは、前述したように、すべてのドキュメントの書き込み/変更/削除操作がトランスログに記録されるためです。その後、リフレッシュとフラッシュ操作によってセグメントに書き込まれます。したがって、最新の文書データがトランスログに記録されます。したがって、トランスログから目的のデータが見つかった場合は、そのまま返します。そうでない場合は、取得してみてください。セグメントからです。

4.4.7 検索処理の詳細説明

ここでの検索処理はsearchを指しますが、上で紹介した読み取り処理とは区別してください。読み取りプロセスとは、ドキュメント ID を取得して、前方インデックスを介してデータを検索することを指します検索プロセスは、検索プロセスと searchType に関連します

searchType のデフォルト値は、Query の後に Fetchです。

これは簡単に理解できます。まず転置インデックスを使用して doc ID を取得し、次に doc ID に基づいて順方向インデックスを使用してデータを検索します。

次の 4 つの searchType があります。

  • クエリとフェッチ

    インデックスのすべてのシャードに対してクエリリクエストを発行し、各シャードが戻る際に要素ドキュメント(ドキュメント)と計算されたランキング情報を合わせて返します。

    この検索方法が最も高速です。以下の検索方法と比較して、このクエリ方法はシャードを 1 回クエリするだけで済むためです。ただし、各シャードから返される結果の数の合計は、ユーザーが必要とするサイズの n 倍になる場合があります。

  • クエリしてフェッチ(デフォルト)

    この検索モードは 2 段階のプロセスです。

    1. すべてのシャードにリクエストを送信すると、各シャードは「十分な」(並べ替え、ランキング、スコアに関連すると推定される)情報のみを返します(注、文書ドキュメントは含まれていません)。その後、スコアに従って並べ替えて合計します。各シャードによって返されるランキング、最初のサイズのドキュメントを取得します。
    2. 関連するシャードに移動してドキュメントを取得します。この方法で返されるドキュメントは、ユーザーが要求したサイズと同じです。
  • DFS クエリとフェッチ

    この方法では、最初の方法よりも最初のスキャッター フレーズのステップが 1 つ多く、このステップによりスコアの精度が高くなります。

  • DFS クエリを実行してからフェッチする

    この方法には、2 番目の方法よりも最初のスキャッター フレーズ ステップが 1 つ多くあります。

通常はデフォルトモードを使用できます。

次に、 Query then Fetchモードを使用した検索プロセスを学習します

検索プロセスは、Query (クエリ ステージ)Fetch (取得ステージ)の 2 つのステージに分かれています。

  • クエリ

    1. 調整ノードは検索リクエストを受信すると、そのリクエストをすべてのシャード (プライマリ シャードとレプリカ シャードを含む) にブロードキャストします。

    2. 各シャードは独立して検索を実行し、照合に逆インデックスを使用し、優先順位付けされた結果キュー (ドキュメントの IDと、 _score などの並べ替えに関係するすべてのフィールドの値を含む) を構築します。

      この段階では、OS キャッシュ内のセグメント キャッシュが照会されます。この時点では、一部のデータがまだメモリ内にある可能性があるため、Elasticsearch はほぼリアルタイムの検索です。(理解するには前の紹介を参照してください)

    3. 各シャードは、優先順位付けされた結果のキューを調整ノードに返します。

    4. 調整ノードは、新しい優先順位の並べ替え結果キューを作成し、グローバル結果を並べ替えて、並べ替え結果リスト(並べ替えられたすべてのフィールド値とドキュメント ID を含む) を取得します。

    5. フェッチステージに入ります。

  • フェッチ

    1. 調整ノードは、ソートされた結果リストに基づいて、関連するシャードに複数の GET リクエストを送信します。
    2. 各シャードはGETリクエストを受信すると、前述の読み込み処理を実行し、文書IDに基づいて詳細な文書情報を取得し、調整ノードに返します。
    3. 調整ノードは結果をクライアントに返します。

参考

[シリコンバレー] ElasticSearch の入門から習得までのチュートリアル (ELK テクノロジー スタック elasticsearch 7.x+8.x の新機能に基づく)

おすすめ

転載: blog.csdn.net/weixin_42584100/article/details/131904555