ES は、分散型検索エンジンとして、拡張機能と検索機能の点で比類のないものですが、準リアルタイムのストレージ システムとしては、シャーディングとレプリケーションの設計原則により、OLTP と競合できません。データ遅延と一貫性の観点から (オンライン トランザクション処理) システムを評価します。
このため、そのデータは通常、二次的なフィルタリングと分析のために他のストレージ システムから同期されます。ここで重要なノード、つまり ES データの同期書き込み方式を紹介します。この記事では、MySQL の同期 ES 方式を紹介します。
MySQL データを ES に書き込む場合、最初に思い浮かぶのは、Binlog を使用して ES に直接書き込むことです。しかし、より多くの次元を考慮すると、この方法にはいくつかの欠点が見つかります。そこで、別の方法として、
[RocketMQ
+ Flink Consumer + ES Bulk] を統合したエコロジーが考えられます。この 2 つのアクセス方法を、同期遅延、消費特性、ES 書き込みパフォーマンス、およびシステムの耐災害性の4 つの側面から評価し ます。全員にインスピレーションを与え、ビジネスに合った同期方法を選択してください。
ESの基本的な書き方の原則
ES 書き込みは、最初に特定のサイズのセグメントを形成し、次に小さなデータ セグメントを大きなデータ セグメントに定期的にマージしてメモリの断片化を軽減し、クエリ効率を向上させる追加タイプの書き込みプロセスです。インデックスは N 個のシャードとそのコピーで構成され、そのインデックス付け方法はマッピングによって定義されます。各シャードは完全に機能する完全な Lucene インデックスです。 ES の処理単位。セグメントは ES の最小のデータ処理単位であり、各セグメントは独立した転置インデックスです。
ES の書き込みでは、実際には同じセグメント (メモリ) に継続的にデータが書き込まれ、その後 Refresh がトリガーされてセグメントが OS キャッシュに更新されます (デフォルトは 1 秒)。この時点でデータを照会することができ、OS キャッシュはオペレーティング システムによってフラッシュをトリガーします。操作はディスクに保存されます。
ES はどのようにしてデータが失われないことを保証するのでしょうか?追記書き込みの長所と短所は何ですか?追加書き込みはデータ更新の問題をどのように処理しますか? MySQL はどの記述方式に属しますか?この記事の焦点はここではありません。記事を個別に読むことができます。
ESの基本概念
ESダイレクトライト
ES 直接接続書き込みを使用する利点は、パスが短く、依存するコンポーネントがほとんどないことです。さらに、Dsyncer (異種ストレージ変換システム) は通常、完全な電流制限リトライ メカニズムを提供するため、消費遅延と消費データの整合性の両方が保証されます。保証されています。
欠点:
-
複数のコンピュータ ルームのディザスタ リカバリ展開にアクセスするのは簡単ではありません。現在、ES のディザスタ リカバリ コンピュータ ルームはすべて独立した読み取りおよび書き込みモードで展開されているため、この方法を採用すると、書き込みを制御することが困難になります。複数のコンピュータ室を同時に使用すると、ディザスタリカバリ効果が得られません。 Binlog-->Dsyncer 通常、1 つの MySQL テーブルは 1 つの変換タスクに対応します。複数のコンピュータ ルームを作成するために複数の繰り返し変換タスクを開始するのは、少し愚かなことのように思えます。
-
独自のビジネス シナリオに同じレコードの同時書き込みが含まれるが、書き込みがすべて Binlog から行われるわけではない場合、グローバルに ES に直接書き込むことを検討すると、順序付けられたキューが保証されないため、書き込み競合が発生する可能性が高くなります。
FlinkによるES統合システムの構築
Flink は ES 統合システムを構築します。これは、すべての ES 書き込みが Flink タスクによって完了することを意味します。これにより、データ パーティションの順序性が保証されるだけでなく、ES のバッチ書き込み機能も最大限に活用されます。バッチ書き込み能力は、単一書き込みパフォーマンスよりも何倍も優れています。同時に、Flink 自体の耐障害性により、異常なシナリオでもデータの最終的な一貫性が保証されます。
アドバンテージ
:
-
MQ を使用すると、複数のコンピューター ルームの ES クラスターにより迅速にアクセスでき、単一のコンピューター ルームに障害が発生した場合でも、使用可能なコンピューター ルームがある限り、3 つのコンピューター ルームのコンシューマーは 互いに独立して データを書き込みます。はい、読み取りトラフィックは直接遮断されます。 災害復旧計画はシンプルかつ明確です 。
-
ネットワーク ジッターなどの問題により ES の書き込みが一時的に失敗する場合、RocketMQ は他のクラスターの書き込みに影響を与えることなくメッセージを一時的に保存し、Flink は消費スナップショットを保存して成功するまで再試行を続けるため、 データの最終的な整合性がより確実に保証されます。 . 性別 ;
-
複数のデータ ソースから書き込むことで、グローバル パーティションの一貫性を確保できます。
欠点
:
-
より多くのコンポーネントに依存すると、リンク全体のデータ同期遅延が増加します。テスト後の ES のデフォルトの更新頻度は 1 秒に 1 回であり、通常の状況でのリンクのデータ遅延は 2 番目のレベルであり、完全に許容できないわけではありません。
-
より多くのコンポーネントに依存し、基本コンポーネントの安定性に対する要件が高くなります。RocketMQ 例外または Flink タスク例外により、同期リンクの問題が発生し、ビジネス例外のリスクが増加します。
ここで注意が必要な問題の 1 つは、複数のコンピューター ルーム ES クラスターへの接続を検討する人がいるかもしれないということです。複数のコンピューター ルームが同時に成功することを確認する方法、および書き込みが成功した後にデータを確実にクエリできるようにする方法について説明します。現時点では、複数のコンピュータ室が互いに影響を与えることなく独立して書き込みを行うため、これら 2 つの点を達成することができません。また、ES クラスターはデータ整合性が弱いクラスターであるため、成功した書き込みがすぐに見つかるという保証はありません。
ES Flinkコンシューマ プログラムを構築して実行するための前提条件:
-
Flink 実行環境: まず、Flink タスクの実行環境が必要です。通常、エンタープライズ レベルの Flink タスクは分散システム内の YARN ジョブとしてスケジュールされ、実行用のリソースが割り当てられますが、同時に Flink タスクも実行されます。スタンドアロン プロセスとして使用したり、独立したクラスター操作を構築したりすることもできます。
-
ES メッセージ形式: ES メッセージの送信形式とシリアル化方法について合意する必要があります。一連のパラダイムですべての同期シナリオを解決できます。現在、一般的なシリアル化方法は pb 形式または json 形式の使用を推奨します。 . データ形式 スキーマ定義:
フィールド名
|
値の型
|
必須/オプション
|
説明する
|
_索引
|
弦
|
必須
|
インデックスを作成するドキュメントの名前またはエイリアス
|
_タイプ
|
弦
|
必須/オプション
|
ドキュメントタイプ
|
_on_type
|
弦
|
必須
|
ドキュメント書き込み操作のタイプ
、値の範囲:
インデックス、作成、更新、
更新/挿入
、削除
|
_id
|
弦
|
オプション
|
ドキュメント ID を
指定しない場合、 ES に書き込まれるときに
自動的に生成され
ます。ただし、同じデータが繰り返し消費されて ES に書き込まれると、複数のドキュメントが生成されます。
|
_ルーティング
|
弦
|
オプション
|
ドキュメントの
ルーティング
。指定しない場合、デフォルトで _id フィールド値のルーティングが使用されます。
|
_バージョン
|
int64
|
オプション
|
ドキュメント バージョン
。指定すると、0 より大きくなり
、インデックス/削除操作にのみ有効です。デフォルトでは、
external_gte
バージョン タイプ が使用されます。
|
_ソース
|
物体
|
必須/オプション
|
ドキュメントの内容
。操作タイプが削除の場合は指定する必要はありません。
|
_脚本
|
物体
|
オプション
|
ドキュメント スクリプト
。操作タイプが更新/更新/挿入の場合に有効ですが、_source と同時に存在することはできません
|
syntax = "proto3";
message ESIndexInfo {
string Name = 1; // 文档要写入索引的名称或别名
}
enum ESOPType { // 文档写入操作类型
DELETE = 0; // 删除文档
INDEX = 1; // 创建新文档或更新老文档,只能全量更新 (替换老文档)
UPDATE = 2; // 更新老文档,支持部分更新 (合并老文档)
UPSERT = 3; // 创建新文档或更新老文档,支持部分更新 (合并老文档)
CREATE = 4; // 创建新文档,存在时报错丢弃
}
message ESDocAction {
ESIndexInfo IndexInfo = 1; // 索引信息 (必需)
ESOPType OPType = 2; // 操作类型 (必需)
string ID = 3; // 文档 ID (可选)
string Doc = 4; // 文档内容 (JSON 格式, 删除操作时不需要)
int64 Version = 5; // 文档版本 (可选, 大于 0 且操作为 index/create/delete 有效)
string Routing = 6; // 文档路由 (可选, 非空有效)
string Script = 7; // 文档脚本 (JSON 格式, 操作类型为 update/upsert 有效,但和 Doc 不能同时存在)
}
-
Flinkタスク に必要な設定: RocketMQ トピック情報の監視、ES クラスター情報の書き込み。
-
Flink 実行機能: Flink は、ストリーミング SQL とカスタム アプリケーションの 2 つの方法でストリーミング メッセージを処理します。ストリーミング SQL には、同じ MQ 内で複数のインデックス メッセージをサポートしないなど、独自の制限がいくつかありますが、カスタム プログラミングはより柔軟です。各種管理やログ、エラーコード処理などを追加する場合はこの方法を推奨します。
-
Flink リソース構成: JobManager リソース構成、TaskManager リソース構成など。
-
Flink カスタム パラメータ構成: アプリケーションに密接に関連するいくつかの動的構成をカスタマイズして、次のような Flink 消費機能の動的調整を容易にすることができます。
パラメータ名
|
使用
|
デフォルト値
|
job.writer.connector.bulk-flush.max-actions
|
1 回の一括ドキュメントの最大数。この数を超えるとフラッシュが実行されます (つまり、ES の一括リクエストが実行されます)。
|
デフォルト 300
|
job.writer.connector.bulk-flush.max-size
|
1 つのバルクの最大バイト数。制限を超えるとフラッシュが実行されます (つまり、ES のバルク リクエストが実行されます)。
|
デフォルト10MB
|
job.writer.connector.bulk-flush.interval
|
複数のフラッシュ (つまり、ES バルク リクエストを実行する) の場合の 2 つのバルク間の最大間隔
|
デフォルトは1000ミリ秒
|
job.writer.connector.global-rate-limit
|
グローバル書き込み速度制限値
|
デフォルト -1、速度制限なし
|
job.writer.connector.failure-handler
|
4xx エラー、5xx エラーをさまざまな方法で処理する、常に無限に再試行する 429 などのカスタム失敗ハンドラーを指定します。
|
|
global_Parallelism_num
|
flink タスクのグローバル同時実行
|
rmq はキュー/4、bmq/kafka はパーティション/3
|
max_Parallelism_num
|
フリンクタスクの最大同時実行数
|
mqのキュー/パーティションの数
|
チェックポイント間隔
|
チェックポイントを作成する間隔、単位はミリ秒 (5min=300000)
|
デフォルト 15 分
|
チェックポイントタイムアウト
|
チェックポイント作成のタイムアウト、単位はミリ秒 (5 分 = 300000)
|
デフォルト 10 分
|
リバランス_有効化
|
アウトオブオーダー消費を有効にする
|
デフォルトは false
|
比較の提案
書き方
|
同期遅延
|
プロパティの書き込み
|
ES書き込みパフォーマンス
|
消費者
|
耐災害性
|
直結
|
依存するコンポーネントが少なく、遅延が少ない
|
Binlog 単一キーを注文しました
|
一括書き込み
|
FaaS
|
貧しい
|
ロケットMQ+フリンク+ES
|
依存コンポーネントが多く、遅延が秒レベルで大きい
|
グローバル単一キーの順序
|
一括書き込み
|
かなり
|
良い
|
上記の導入後、ビジネスが第 2 レベルの遅延を許容できる場合、RocketMQ+Flink を使用すると、ストリーミング タスク処理機能の点で FaaS よりもはるかに優れた秩序性と災害復旧機能を実現できますが、直接的な接続方法は明らかに異なります。したがって、ビジネスの特性に基づいて最適なものを選択する必要があります。
ソースチーム|ByteDance電子商取引ビジネスプラットフォーム
{{o.name}}
{{m.name}}