ES 5 億注文クエリの進化プロセス

JD Daojia の注文センター システムのビジネスでは、外部販売業者の注文生産であっても、社内の上流および下流システムへの依存であっても、注文クエリの呼び出し量が非常に多く、その結果、読み取りが多く書き込みが少ないという状況が発生します。注文データ。

 

注文データは MySQL に保存しますが、DB のみを介して大量のクエリをサポートすることは明らかにお勧めできません。同時に、一部の複雑なクエリに対して MySQL は十分に使いやすいものではないため、注文センター システムは Elasticsearch を使用して注文クエリの主要なプレッシャーを担っています。

 

 

Elasticsearch は強力な分散検索エンジンとして、ほぼリアルタイムのストレージと検索データをサポートしており、JD Daojia の注文システムで大きな役割を果たしています。現在、注文センターの ES クラスターには 10 億のドキュメントが保存されており、1 日の平均クエリ量は5億に達しました。

 

近年のJD Daojiaのビジネスの急速な発展に伴い、注文センターのES構築スキームも進化を続けており、これまでESクラスター構築はリアルタイムの相互バックアップスキームのセットであり、安全性が十分に保証されています。 ES クラスターの読み取りと書き込みの安定性については、次のとおりです。このプロセスと、そのプロセスで遭遇するいくつかの落とし穴を紹介します。

 

ESクラスタアーキテクチャの進化の道

 

1. 初期段階

 

オーダーセンターESの初期段階は白紙のようなもので、基本的に構築計画はなく、クラスタのデフォルト構成を維持する構成が多い。クラスター全体がグループのエラスティック クラウドにデプロイされており、ES クラスター内のノードとマシンのデプロイは混沌としています。同時に、クラスターの次元によると、ES クラスターには単一点問題が発生しますが、これは明らかにオーダー センター ビジネスでは許可されません。

 

2. クラスター分離段階

 

多くの企業と同様に、ES クラスターは混合分散方式を採用しています。ただし、注文センター ES にはオンライン注文データが保存されているため、時折混在分散クラスターが大量のシステム リソースを占有し、注文センター ES 全体のサービスが異常になる可能性があります。

 

注文クエリの安定性に影響を与える状況は当然許容できないため、この状況では、注文センター ES が配置されているエラスティック クラウドが、大量のシステム リソースを占有するクラスター ノードからまず移動されます。 ESクラスター状況は若干改善されました。しかし、クラスター データが増加し続けるにつれて、柔軟なクラウド構成は ES クラスターにとって十分ではなくなり、完全に物理的に分離するために、最終的にはオーダー センター ES クラスターが高構成の物理マシンにデプロイされ、ES クラスターのパフォーマンスが向上します。 。

 

3. ノードコピーのチューニング段階

 

ES のパフォーマンスはハードウェア リソースと大きく関係しています。ES クラスターが物理マシンのみにデプロイされている場合、クラスター内のノードが物理マシン全体のリソースを独占しません。クラスターが実行されているとき、その上のノードは同じ物理マシンが依然としてリソースを占有するという問題があります。したがって、この場合、単一の ES ノードが最大のマシン リソースを使用できるようにするために、各 ES ノードは個別の物理マシンにデプロイされます。

 

しかし、単一のノードにボトルネックがある場合はどうなるのかという問題が再び発生しました。どのように最適化すればよいでしょうか?

 

ES クエリの原理は、リクエストが特定の番号のシャードにヒットした場合、シャード タイプ (Preference パラメータ) クエリが指定されていない場合、リクエストは対応するシャード番号の各ノードにロードされるというものです。クラスタのデフォルトのレプリカ構成は1マスタ、1レプリカですが、この状況に対し、デフォルトの1マスタ、1レプリカから1マスタ、2レプリカに変更し、対応する物理マシンを追加することでレプリカを拡張する方法を考えました。同じ時間です。

 

オーダーセンターESクラスタセットアップの概略図

 

図に示すように、セットアップ方法全体では VIP を使用して外部リクエストの負荷分散を行います。

 

クラスター全体には、1 組のプライマリ シャードと 2 組のセカンダリ シャード (1 つのプライマリと 2 つのセカンダリ) があり、ゲートウェイ ノードから転送されたリクエストは、データ ノードに到達する前にポーリングによってバランスがとられます。クラスターに一連のレプリカを追加してマシンの容量を拡張する方法では、クラスターのスループットが向上し、クラスター全体のクエリ パフォーマンスが向上します。

 

次の図は、オーダー センター ES クラスターの各ステージのパフォーマンスの概略図であり、最適化の各ステージ後の ES クラスターのパフォーマンスが大幅に向上していることを直感的に示しています。

 

 

もちろん、シャードの数とシャードのコピーの数は、できるだけ良いものではありませんが、現段階では、適切なシャード数の選択をさらに検討しました。フラグメントの数は、MySQL のサブデータベースとサブテーブルとして理解できます。現在のオーダー センター ES クエリは、主にシングル ID クエリとページング クエリの 2 種類に分類されます。

 

 

シャードの数が増えるほど、クラスターの水平拡張の規模が大きくなり、シャード ルーティングに基づく単一 ID クエリのスループットは大幅に向上しますが、集約されたページング クエリのパフォーマンスは低下します。シャードの数が少ないほど、クラスターの水平拡張の規模が大きいほど、小さいほど単一 ID のクエリパフォーマンスは低下しますが、ページングクエリのパフォーマンスは向上します。

 

そこで、シャードの数と既存のクエリ ビジネスのバランスをどのように取るかについて、多くの調整と負荷テストを行い、最終的にクラスターのパフォーマンスがより優れたシャードの数を選択しました。

 

4. マスタ・スレーブクラスタ調整段階

 

これまでのところ、注文センターの ES クラスターは形になり始めていますが、注文センター ビジネスの高い適時性要件により、ES クエリの安定性要件も高くなります。クラスター内のいずれかのノードが異常な場合、クエリはサービスが影響を受けるため、受注生産プロセス全体に影響します。この異常事態は明らかに致命的であるため、この事態に対処するためにスタンバイ クラスタを追加し、メイン クラスタに異常が発生した場合、クエリ トラフィックをリアルタイムでスタンバイ クラスタにダウングレードすることが最初の考えです。

 

バックアップクラスターはどのように設定すればよいですか? マスターとバックアップの間でデータを同期するにはどうすればよいですか? スタンバイ クラスターにはどのような種類のデータを保存する必要がありますか?

 

当面、ES クラスターには適切なマスター/スタンバイ ソリューションがないことを考慮し、ES データの書き込みをより適切に制御するために、ビジネス二重書き込みの方法を採用してマスター/スタンバイ クラスターを設定します。ビジネス操作で ES データを書き込む必要があるたびに、プライマリ クラスター データが同期的に書き込まれ、次にスタンバイ クラスター データが非同期的に書き込まれます。同時に、ES クエリ トラフィックのほとんどは最近の注文から来ており、注文センターのデータベース データには一連のアーカイブ メカニズムがあるため、指定された日数が経過する前にクローズされた注文は履歴データに転送されます。注文データベース。

 

したがって、スタンバイ クラスターのドキュメントを削除するロジックがアーカイブ メカニズムに追加され、新しく構築されたスタンバイ クラスターに保存される注文データが注文センターのオンライン データベースのデータ量と一致するようになります。同時に、ZK を使用してクエリ サービス内でフロー制御スイッチを作成し、クエリ トラフィックをリアルタイムでスタンバイ クラスタにダウングレードできるようにします。ここで、オーダーセンターのマスター・スレーブクラスターが完成し、ESクエリサービスの安定性が大幅に向上しました。

 

 

5. 現在:リアルタイム相互バックアップのデュアルクラスターステージ

 

この期間中、メイン クラスターの ES バージョンは 1.7 未満であり、現在の ES 安定バージョンは 6.x に更新されているため、新しいバージョンの ES はパフォーマンスを大幅に最適化するだけでなく、いくつかの新しくて便利な機能も提供します。メイン クラスターはバージョン アップグレードを受けており、元の 1.7 からバージョン 6.x に直接アップグレードされています。

 

クラスタのアップグレード プロセスは煩雑で時間がかかります。オンライン ビジネスに影響がないこと、アップグレードがスムーズで知覚的でないことを確認する必要があるだけでなく、ES クラスタはクラスタ間でのデータ移行をサポートしていないためです。 1.7 から 6.x までの複数のバージョンでは、インデックスを再構築する必要があります。メイン クラスターをアップグレードするには、ここでは特定のアップグレード プロセスを繰り返しません。

 

メイン クラスタがアップグレードされると、可用性が失われることは避けられませんが、オーダー センター ES クエリ サービスでは、このような状況は許容されません。したがって、アップグレード フェーズでは、スタンバイ クラスターが一時的にプライマリ クラスターとして機能し、すべてのオンライン ES クエリをサポートし、アップグレード プロセスが通常のオンライン サービスに影響を与えないようにします。同時に、オンライン ビジネスについては、2 つのクラスターを再計画して定義し、実行されるオンライン クエリ トラフィックを再分割しました。

 

スタンバイ クラスターは、最近ホット データをオンラインで保存します。そのデータ サイズはメイン クラスターよりもはるかに小さく、メイン クラスター内のドキュメント数の約 10 分の 1 です。クラスターのデータ量は小さく、同じクラスター展開規模では、スタンバイ クラスターのパフォーマンスがプライマリ クラスターよりも優れています。

 

ただし、オンラインの実際のシナリオでは、オンライン クエリ トラフィックのほとんどはホット データからも発生するため、スタンバイ クラスターはこれらのホット データのクエリを伝送するために使用され、スタンバイ クラスターは徐々にホット データ クラスターに進化します。以前のメイン クラスターはデータの全量を保存し、クエリ トラフィックの残りのわずかな部分をサポートするためにこのクラスターを使用しました。クエリのこの部分は主に、全量の注文と内部クエリを検索する必要がある特殊なシナリオ クエリです。メイン クラスターも徐々にコールド データ クラスターに進化します。

 

同時に、バックアップ クラスターには、ワンクリックでプライマリ クラスターにダウングレードする機能が追加され、2 つのクラスターのステータスは同様に重要ですが、どちらも別のクラスターにダウングレードできます。二重書き込み戦略も次のように最適化されます。AB クラスターがあると仮定すると、通常の同期モードはマスター (A クラスター) に書き込み、非同期モードはバックアップ (B クラスター) に書き込みます。クラスタ A で例外が発生した場合、クラスタ B (メイン) に同期的に書き込み、クラスタ A (スタンバイ) に非同期で書き込みます。

 

 

ES注文データの同期方式

 

MySQL データの ES への同期は、大きく 2 つのソリューションに分けることができます。

 

  • 解決策 1: MySQL の Binlog を監視し、Binlog を分析し、データを ES クラスターに同期します。

  • 解決策 2: ES API を通じて ES クラスターにデータを直接書き込みます。

 

注文システムの ES サービスのビジネスの特殊性を考慮すると、注文データのリアルタイム性は比較的高いですが、明らかに Binlog を監視する方法は非同期同期に相当し、大きな遅延が発生する可能性があります。そして、案 1 は案 2 と本質的には似ていますが、新たなシステムが導入され、維持コストも増加します。したがって、注文センター ES は、ES API を通じて注文データを直接書き込む方法を採用しており、この方法はシンプルかつ柔軟であり、注文センターデータと ES の同期のニーズに十分に応えることができます。

 

ES注文データの同期は業務上で記述されるため、文書の作成や更新時に例外が発生した場合、リトライにより業務の通常運用の応答時間に影響が出るのは避けられません。

 

したがって、ES は業務操作ごとに 1 回だけ更新され、エラーまたは例外が発生した場合、修復タスクがデータベースに挿入され、Worker タスクがリアルタイムでデータをスキャンし、データベースに基づいて ES データを再度更新します。注文データ。この補償メカニズムにより、ES データとデータベース順序データの最終的な整合性が保証されます。

 

いくつかのピットに遭遇

 

1. リアルタイム要件の高いクエリは DB に送信されます

 

ES 作成メカニズムを理解している学生は、新しく追加されたドキュメントがインデックス バッファーに収集され、ファイル システム キャッシュに書き込まれ、他のファイルと同様にインデックスを付けることができることを知っているかもしれません。

 

ただし、デフォルトでは、ドキュメントはインデックス バッファからファイル システム キャッシュに毎秒自動的に更新されます (つまり、更新操作)。これが、ES がリアルタイムではなく、ほぼリアルタイムの検索であると言われる理由です。時間: ドキュメント内の変更は検索ではすぐには表示されませんが、1 秒以内に表示されます。

 

現在の注文システム ES はデフォルトの更新構成を採用しているため、比較的リアルタイムの注文データを扱う企業の場合は、データベース クエリを直接使用してデータの正確性を確保します。

 

 

2. 深いページ分割クエリを避ける

 

ES クラスターのページング クエリは、from パラメーターと size パラメーターをサポートしています。クエリを実行するとき、各フラグメントは from+size の長さの優先キューを構築し、それをゲートウェイ ノードに送り返す必要があります。ゲートウェイ ノードはこれらの優先キューを並べ替えます。正しいサイズの書類を見つけるために。

 

6 つのプライマリ シャードを持つインデックスで、from が 10000、サイズが 10 であると仮定すると、各シャードは 10010 件の結果を生成する必要があり、60060 件の結果がゲートウェイ ノードで集約され、最終的に要件を満たす 10 件のドキュメントが見つかります。

 

from が十分に大きい場合、OOM が発生しない場合でも、CPU と帯域幅に影響を及ぼし、クラスター全体のパフォーマンスに影響を与えることがわかります。したがって、深いページング クエリは避け、使用しないようにしてください。

 

3. FieldData と Doc の値

 

フィールドデータ

 

オンライン クエリがタイムアウトになることがあります。クエリ ステートメントをデバッグすることにより、それが並べ替えに関係していることが判明します。es1.x バージョンでは、ソートには FieldData 構造が使用されます。FieldData は JVM ヒープ メモリを占有し、JVM メモリは制限されています。FieldData キャッシュにはしきい値が設定されています。

 

スペースが不十分な場合は、最長未使用 (LRU) アルゴリズムを使用して FieldData を削除し、同時に新しい FieldData Cache をロードします。ロード プロセスはシステム リソースを消費し、時間がかかります。したがって、このクエリの応答時間は急増し、クラスター全体のパフォーマンスに影響を与えることもあります。この種の問題の解決策は、Doc Values を使用することです。

 

ドキュメントの値

 

Doc Values は、FieldData によく似た列形式のデータ ストレージ構造ですが、そのストレージの場所は Lucene ファイル内にあり、JVM ヒープを占有しません。ES バージョンの反復により、Doc Values は FieldData よりも安定しており、2.x 以降は Doc Values がデフォルト設定になっています。

 

要約する

 

構造の急速な反復はビジネスの急速な発展に起因しており、近年の Daojia ビジネスの急速な発展により、注文センターの構造も継続的に最適化およびアップグレードされてきました。

 

最適なアーキテクチャ ソリューションというものはなく、最も適切なものだけが存在します。数年後には、注文センターのアーキテクチャは見直されると思いますが、より優れたスループット、より優れたパフォーマンス、より強力な安定性を備えた注文センターになるでしょう。システムの永遠の追求。

おすすめ

転載: blog.csdn.net/qq_35240226/article/details/108235933