FlinkがIcebergデータレイクのCDCデータをリアルタイムで分析する方法

この記事はLiJinsongとHuZhengによって共有され、コミュニティボランティアのYangWeihaiとLiPeidianによって組織されました。主に、データレイクのアーキテクチャにおけるCDCデータのリアルタイムの読み取りと書き込みのスキームと原理を紹介します。この記事は主に4つの部分に分かれています。

  1. 一般的なCDC分析ソリューション
  2. Flink + Icebergを選ぶ理由
  3. リアルタイムで読み書きする方法
  4. 未来の計画

1.一般的なCDC分析プログラム

まず、今日のトピックのために何を設計する必要があるかを見てみましょう。入力はCDCまたはアップサートデータであり、出力はビッグデータOLAP分析用のデータベースまたはストレージです。

私たちの一般的な入力には主に2種類のデータが含まれます。最初のデータはデータベースのCDCデータであり、changeLogを継続的に生成します。もう1つのシナリオは、ストリームコンピューティングによって生成されたアップサートデータです。最新のFlink1.12バージョンはすでにアップサートデータをサポートしています。

1.1オフラインHBaseクラスター分析CDCデータ

私たちが通常考える最初の解決策は、Flinkを介してCDCアップサートデータを処理し、それをHBaseにリアルタイムで書き込むことです。HBaseは、オンライン照会機能を提供できるオンラインデータベースです。非常に高いリアルタイムパフォーマンスを備え、書き込み操作が非常に簡単で、小規模なクエリもサポートでき、クラスターはスケーラブルです。

この種のスキームは、実際にはポイントチェック用の通常のリアルタイムリンクと同じですが、ビッグデータのOLAPクエリ分析にHBaseを使用する場合の問題は何ですか?

まず、HBaseは、ポイントチェックとオンラインサービス用に設計されたデータベースであり、その行に格納されたインデックスは分析タスクには適していません。圧縮効率とクエリ効率が高くなるように、一般的なデータウェアハウスの設計をリストする必要があります。第二に、HBaseのクラスター保守コストは比較的高いです。最後に、HBaseのデータはHFileであり、ビッグデータウェアハウス内の一般的なParquet、Avro、Orcなどと組み合わせるのは不便です。

1.2 ApacheKuduはCDCデータセットを維持します

HBaseの比較的弱い分析機能に対応して、数年前にコミュニティに新しいプロジェクト、ApacheKuduプロジェクトが登場しました。KuduプロジェクトにはHBaseがチェックする機能がありますが、列ストレージも使用するため、列ストレージの高速化はOLAP分析に非常に適しています。

このスキームの問題は何ですか?

まず、Kuduは比較的小さく、独立したクラスターであり、そのメンテナンスコストは比較的高く、HDFS、S3、およびOSSからより細分化されています。第二に、Kuduはデザインをチェックインする機能を保持しているため、バッチスキャンのパフォーマンスは寄木細工ほど良くありません。さらに、Kuduの削除のサポートは比較的弱く、最終的にはインクリメンタルプルをサポートしていません。

1.3CDCをHive分析に直接インポートする

データウェアハウスでも一般的に使用されている3番目のソリューションは、MySQLデータをHiveに書き込むことです。プロセスは、完全なパーティションを維持し、毎日増分パーティションを作成し、最後に増分パーティションを書き込むことです。その後、新しいパーティションをマージして書き込みます。これはプロセスでうまく機能します。Hiveの前の完全なパーティションは、増分の影響を受けません。増分マージが成功した後でのみ、パーティションを確認でき、それは新しいデータです。この種の純粋にリストされた追加データは、分析に非常に適しています。

このスキームの問題は何ですか?

インクリメンタルデータとフルデータのマージには遅延があり、データはリアルタイムで書き込まれません。通常、マージは1日に1回実行されます。これは、T +1データです。したがって、適時性は非常に低く、リアルタイムのアップサートはサポートされていません。各マージでは、すべてのデータを再読み取りおよび再書き込みする必要がありますが、これは比較的非効率的であり、リソースを浪費します。

1.4 Spark + Delta分析CDCデータ

この問題に対応して、Spark + Deltaは、CDCデータを分析するときにMERGEINTO構文を提供します。これは、Hiveデータウェアハウスの構文を単純化しただけではありません。新しいデータレイクアーキテクチャ(Iceberg、Hudiなど)としてのSpark + Deltaは、パーティションではなくファイルを管理します。したがって、DeltaはMERGEINTO構文とスキャンのみ。変更されたファイルを書き換えるだけなので、はるかに効率的です。

このソリューションを評価してみましょう。その利点は、Spark + Deltaのみに依存し、アーキテクチャがシンプルで、オンラインサービスや列ストレージがなく、分析速度が非常に速いことです。MERGEINTOの最適化された構文速度は十分に高速です。

このプログラムは、ビジネスにおけるコピーオンライトプログラムです。少数のファイルをコピーするだけで済み、遅延を比較的低くすることができます。理論的には、更新されたデータが既存の在庫と重複しない場合、日レベルの遅延は時間レベルの遅延として実現でき、パフォーマンスを維持できます。

このソリューションは、Hiveウェアハウスでアップサートデータを処理する方法を少し前進させました。ただし、1時間ごとの遅延は結局のところリアルタイムほど効果的ではないため、このソリューションの最大の欠点は、コピーオンライトのマージに特定のオーバーヘッドがあり、遅延を低くしすぎることができないことです。

最初の部分にはおそらく非常に多くの既存のソリューションがありますが、同時に、アップサートが非常に重要である理由は、データレイクソリューションでは、アップサートが準現実を実現するための重要なテクノロジーポイントであるということを強調する必要があります。 -湖へのリアルタイムおよびリアルタイムのデータベースアクセス。

2. Flink + Icebergを選択する理由

2.1CDCデータ消費に対するFlinkのサポート

まず、FlinkはCDCデータの消費をネイティブにサポートしています。以前のSpark + DeltaソリューションであるMARGEINTOの文法では、ユーザーはCDC属性の概念を認識してから、マージの文法を記述する必要があります。ただし、FlinkはCDCデータをネイティブにサポートしています。ユーザーはDebeziumまたは他のCDC形式を宣言するだけでよく、Flink上のSQLはCDCまたはアップサート属性を認識する必要はありません。Flinkには、CDCタイプのデータを識別するための非表示列が組み込まれているため、ユーザーにとってより簡潔です。

次の図の例として、CDC処理では、FlinkはMySQL Binlog DDLステートメントのみを宣言し、次のselectはCDC属性を認識する必要はありません。

2.2変更ログストリームに対するFlinkのサポート

次の図は、Flinkが変更ログストリームをネイティブにサポートしていることを示しています。Flinkが変更ログストリームに接続された後、トポロジは変更ログフラグのSQLを気にする必要がありません。トポロジは独自のビジネスロジックに従って完全に定義されており、最後までIcebergに書き込まれるため、変更ログフラグを認識する必要はありません。

2.3 Flink + IcebergCDC輸入計画の評価

最後に、Flink + IcebergのCDCインポートソリューションの利点は何ですか?

前のスキームと比較して、コピーオンライトとマージオンリードはどちらも、焦点が異なる適用可能なシナリオを持っています。コピーオンライトは、一部のファイルを更新するシーンでファイルの一部のみを書き換える必要がある場合に非常に効率的です。生成されるデータは、純粋な追加の完全なデータセットであり、データ分析に使用する場合にも最速です。コピーオンライトの利点。

もう1つは、Merge On Readです。つまり、データとCDCフラグがIcebergに直接追加されます。マージ中に、増分データは、特定の組織形式と特定の効率的な計算方法で、以前のデータの全量とマージされます。 。これの利点は、ほぼリアルタイムのインポートとリアルタイムのデータ読み取りをサポートすることです。このコンピューティングソリューションのFlink SQLは、CDCの取り込みをネイティブにサポートし、追加のビジネスフィールドの設計は必要ありません。

Icebergは統合データレイクストレージであり、多様なコンピューティングモデルをサポートし、分析用のさまざまなエンジン(Spark、Presto、hiveを含む)もサポートします。生成されたファイルは純粋な列ストレージであり、後続の分析に非常に高速です。Icebergはスナップショットです-データレイクのベース設計とインクリメンタル読み取りをサポートします。Icebergアーキテクチャは十分にシンプルで、オンラインサービスノードがなく、純粋なテーブル形式であるため、アップストリームプラットフォームは独自のロジックとサービスをカスタマイズできます。

3、リアルタイムで読み書きする方法

3.1バッチ更新シーンとCDC書き込みシーン

まず、データレイク全体でのバッチ更新の2つのシナリオを見てみましょう。

  • これは最初のバッチ更新シナリオです。このシナリオでは、SQLを使用して、ヨーロッパのGDPRポリシーなど、数千行のデータを更新します。ユーザーがアカウントをログアウトすると、バックエンドシステムはこのすべての関連データを変更する必要があります。ユーザーのが物理的に削除されます。
  • 2番目のシナリオは、日付レイクで共通の特性を持つ一部のデータを削除する必要があるというものです。このシナリオは、バッチ更新のシナリオでもあります。このシナリオでは、削除条件は任意の条件であり、主キー(主キー)はありません。 )関係に関係なく、同時に、更新されるデータセットは非常に大きくなります。この種のジョブは、時間のかかる低頻度のジョブです。

もう1つは、CDCによって作成されたシナリオです。Flinkの場合、一般的に使用されるシナリオは2つあります。最初のシナリオは、アップストリームのBinlogをデータレイクにすばやく書き込み、さまざまな分析エンジンで分析に使用できることです。2番目のシナリオはFlinkを使用して、いくつかの集計操作を実行します。出力ストリームはアップサートタイプのデータストリームであり、リアルタイムで分析するためにデータレイクまたはダウンストリームシステムに書き込むことができる必要もあります。次の図の例に示すように、CDCはシーンにSQLステートメントを書き込みます。単一のSQLを使用してデータの行を更新します。この計算モードはストリーミング増分インポートであり、高頻度の更新です。

3.2CDCライティングソリューションを設計する際にApacheIcebergが考慮する必要のある問題

次に、CDC作成のシナリオを設計するときにicebergが考慮する必要のある問題を見てみましょう。

  • 1つ目は正確性です。つまり、セマンティクスとデータの正確性を保証する必要があります。たとえば、氷山へのアップストリームデータのアップサート。アップストリームアップサートが停止すると、アイスバーグのデータはアップストリームシステムのデータと一致する必要があります。
  • 2つ目は効率的な書き込みです。アップサートの書き込み頻度が非常に高いため、高いスループットと高い同時書き込みを維持する必要があります。
  • 3つ目は高速読み取りです。データを書き込むときに、データを分析する必要があります。これには2つの問題があります。1つ目の問題は、きめ細かい同時実行をサポートする必要があることです。ジョブが複数のタスクを使用して読み取る場合、次のことを確認できます。各タスクは、データの計算を高速化するためにバランスの取れた方法で割り当てられます。2番目の問題は、読み取りを高速化するために列型ストレージの利点を十分に活用する必要があることです。
  • 4つ目は、従来のデータウェアハウスでのETLなどの増分読み取りを、さらにデータ変換するための増分読み取りを通じてサポートすることです。

3.3 Apache Iceberg Basic

特定のプログラムの詳細を紹介する前に、まずファイルシステム内のIcebergのレイアウトを理解しましょう。一般的に、Icebergはデータの2つの部分に分割されます。最初の部分はデータファイルです。下図の寄木細工のファイル。各データファイル学校に対応します。検証ファイル(.crcファイル)。2番目の部分は、スナップショットファイル(snap -.avro)、マニフェストファイル( .avro)、TableMetadataファイル(* .json)などを含むテーブルメタデータファイル(メタデータファイル)です

次の図は、icebergのスナップショット、マニフェスト、およびパーティションファイル間の対応を示しています。次の図には3つのパーティションが含まれています。最初のパーティションには2つのファイルf1とf3があり、2番目のパーティションには2つのファイルf4とf5があり、3番目のパーティションにはファイルf2があります。書き込みごとに、今回書き込まれたファイルとパーティションの対応を記録したマニフェストファイルが生成されます。上位レベルへのスナップショットの概念があります。スナップショットは、テーブル全体の全量のデータにすばやくアクセスするのに役立ちます。スナップショットは複数のマニフェストを記録します。たとえば、2番目のスナップショットにはmanifest2とmanifest3が含まれます。

3.4 INSERT、UPDATE、DELETE書き込み

基本的な概念を理解した後、以下では、氷山での挿入、更新、および削除操作の設計を紹介します。

次の図のSQLの例に示されているテーブルには、idとdataの2つのフィールドが含まれており、どちらもint型です。トランザクションでは、図に示すデータフロー操作を実行しました。最初にレコード(1、2)が挿入され、次にこのレコードが(1、3)に更新されました。氷山では、更新操作は次のように分割されます。削除2つの操作を挿入します。

これは、icebergをストリーミングバッチの統合ストレージレイヤーと見なし、更新操作を削除操作と挿入操作に逆アセンブルすると、ストリーミングバッチシーンが更新されたときに読み取りパスを確実に統合できるためです。たとえば、バッチ削除シナリオでは、Hiveは次のように使用されます。たとえば、Hiveは削除する行のファイルオフセットをデルタファイルに書き込み、読み取り時にマージを実行します。これにより高速になるためです。マージが実行されると、元のファイルとデルタ位置を介してマッピングされ、削除されたレコードを除くすべてのレコードがすばやく取得されます。

次に、レコード(3、5)を挿入し、レコード(1、3)を削除し、レコード(2、5)を挿入します。最後のクエリは、レコード(3、5)(2、5)を取得することです。

上記の操作は非常に単純に見えますが、実装にはいくつかのセマンティックな問題があります。次の図に示すように、トランザクションでは、最初にレコード(1、2)を挿入する操作が実行されます。この操作では、データfile1ファイルにINSERT(1、2)が書き込まれ、次に削除する操作が実行されます。レコード(1、2)。この操作は、イコライズ削除ファイル1にDELETE(1、2)を書き込み、次にレコードの挿入(1、2)操作を実行します。これにより、データファイル1ファイルにINSERT(1、2)が書き込まれます。次に、クエリ操作を実行します。

通常の状況では、クエリ結果はレコードINSERT(1、2)を返すはずですが、実装では、DELETE(1、2)操作は、データfile1ファイルのどの行が削除されたかを認識できないため、INSERT(1 、2))すべてのレコードが削除されます。

したがって、この問題を解決する方法として、コミュニティの現在の方法は、混合位置削除と平等削除を採用することです。Equality-deleteは、1つ以上の列を指定して削除することであり、position-deleteは、ファイルパスと行番号に基づいて削除することです。2つの方法を組み合わせて、削除操作の正確性を確保します。

次の図に示すように、最初のトランザクションで3行のレコード(INSERT(1、2)、INSERT(1、3)、INSERT(1、4))を挿入してから、コミット操作を実行して送信します。次に、新しいトランザクションを開始し、データの行(1、5)の挿入を実行します。これは新しいトランザクションであるため、新しいデータファイル2を作成し、INSERT(1、5)レコードを書き込んでから、レコードの削除を実行します。 (1、5)実際にdeleteを書き込むと、次のようになります。

位置deletefile1 fileに(file2、0)を書き込みます。これは、データfile2の行0のレコードを削除することを意味します。これは、同じトランザクションで同じ行のデータを繰り返し挿入および削除するというセマンティック問題を解決するためです。
等式削除ファイル1ファイルにDELETE(1,5)を書き込みます。この削除を書き込む理由は、このtxnの前に書き込まれた(1,5)を正しく削除できるようにするためです。

次に、削除(1、4)操作を実行します。現在のトランザクションには(1、4)が挿入されていないため、この操作では等式削除操作が使用されます。つまり、(1、4)レコードが等式に書き込まれます。 file1を削除します。上記のプロセスでは、現在のソリューションには、データファイル、位置削除ファイル、等式削除ファイルの3種類のファイルがあることがわかります。

書き込みプロセスを理解した後、それを読む方法。下図のように、位置削除ファイルのレコード(file2、0)は、現在のトランザクションのデータファイルのみを結合する必要があり、等式削除ファイル(1、4)のレコードとデータ前のトランザクションのファイルが結合されます。最後に、レコードINSERT(1、3)およびINSERT(1、2)が取得され、プロセスの正確性が保証されます。

3.5マニフェストファイルの設計

挿入、更新、削除は上記で紹介しましたが、タスクの実行プランを設計する際に、いくつかのマニフェストを設計しました。目的は、マニフェストからデータファイルをすばやく見つけ、データサイズに応じて分割して確実にすることです。各タスクによって処理されるデータを可能な限り均等に分散します。

次の図に示す例には、4つのトランザクションが含まれています。最初の2つのトランザクションはM1とM2に対応するINSERT操作、3番目のトランザクションはM3に対応するDELETE操作、4番目のトランザクションは2つのマニフェストファイルを含むUPDATE操作です。つまり、データマニフェストと削除マニフェストです。

マニフェストファイルがデータマニフェストと削除マニフェストに分割される理由については、基本的に、各データファイルに対応する削除ファイルリストをすばやく見つける必要があります。次の図に例を示します。パーティション2を読み取るときは、deletefile-4とdatafile-2およびdatafile-3の間で結合操作を実行する必要があります。また、deletefile-5とdatafile-を組み合わせる必要があります。 2およびデータファイル-3。結合操作を実行します。

例としてdatafile-3を取り上げます。deletefileリストには、deletefile-4とdeletefile-5の2つのファイルが含まれています。対応するdeletefileリストをすばやく見つける方法は?上位レベルのマニフェストに従ってクエリを実行できます。マニフェストファイルをに分割すると、データマニフェスト削除マニフェストとM2(データマニフェスト)をM3とM4(削除マニフェスト)と最初に結合した後、データファイルに対応する削除ファイルリストをすばやく取得できます。

3.6ファイルレベルの同時実行性

もう1つの問題は、十分に高い同時読み取りを確保する必要があることです。これは、氷山で非常にうまく行われます。ファイルレベルの同時読み取りはicebergで実現でき、ファイル内のセグメントのさらにきめ細かい同時読み取りを実現できます。たとえば、256MBのファイルを2つの128MBに分割して同時読み取りを行うことができます。次に例を示します。次の図に示すように、挿入ファイルと削除ファイルが2つのバケットに配置されているとします。

マニフェストを比較したところ、datafile-2のファイル削除リストにはdeletefile-4しかないため、これら2つのファイルを1つのタスク(図のタスク2)として実行でき、他のファイルも同様であることがわかりました。 、保証できるように各タスクのデータはバランスの取れた方法でマージされます。

次の図に示すように、このスキームの簡単な要約を作成しました。まず、このスキームの利点は正確さを満たし、高スループットの書き込みと同時かつ効率的な読み取りを実現できます。さらに、スナップショットレベルのインクリメンタルプルを実現できます。

現在のスキームはまだ比較的ラフであり、以下で最適化できるいくつかのポイントがあります。

  • 最初のポイントは、同じタスク内の削除ファイルが複製された場合、それをキャッシュできることです。これにより、結合の効率が向上します。
  • 2つ目のポイントは、削除ファイルが比較的大きく、ディスクに上書きする必要がある場合に最適化にkv libを使用できることですが、外部サービスやその他の重いインデックスには依存しません。
  • 第3に、無効なIOをフィルタリングするブルームフィルターを設計できます。これは、Flinkで一般的に使用されるアップサート操作によって削除操作と挿入操作が生成され、氷山のデータファイルと削除ファイルのサイズにつながるためです。違いはありません。そのため、結合の効率はそれほど高くありません。ブルームフィルターを使用すると、アップサートデータが到着すると、挿入操作と削除操作に分割されます。ブルームフィルターが、以前にデータを挿入したことがない削除操作をフィルターで除外する場合(つまり、このデータが以前に挿入されていない場合は、削除する必要はありませんレコードは削除ファイルに書き込まれます)。これにより、アップサートの効率が大幅に向上します。
  • 4つ目のポイントは、削除ファイルのサイズを制御するために、いくつかのバックグラウンド圧縮戦略が必要であるということです。削除ファイルが小さいほど、分析の効率が高くなります。もちろん、これらの戦略は通常の読み取りと書き込みには影響しません。

3.7増分ファイルセットのトランザクション送信

前のセクションでは、ファイルの書き込みを紹介しました。次の図では、icebergのセマンティクスに従って書き込み、ユーザーが利用できるようにする方法を紹介します。データとメタストアの2つに大きく分けられます。まず、データを書き込むためのIcebergStreamWriterがありますが、現時点では、書き込まれたデータのメタデータ情報はメタストアに書き込まれないため、外部からは見えません。2番目の演算子はIcebergFileCommitterで、データファイルを収集し、最終的にコミットトランザクションを介して書き込みを完了します。

Icebergには他のサードパーティのサービス依存関係はなく、Hudiは、メタストアを独立したタイムラインに抽象化するなど、いくつかの側面でサービスの抽象化を行っています。これは、いくつかの独立したインデックスや他の外部サービスに依存する場合があります。

4、将来の計画

以下は、将来の計画の一部です。1つ目は、計画に含まれる完全なリンク安定性テストとパフォーマンスの最適化を含む、Icebergカーネルのいくつかの最適化であり、CDCインクリメンタルプル用の関連するTableAPIインターフェイスを提供します。

Flink統合では、CDCデータのデータファイルを自動および手動でマージする機能が実現され、CDCデータを段階的にプルするFlinkの機能が提供されます。

その他のエコロジカル統合では、Spark、Presto、その他のエンジンを統合し、Alluxioを使用してデータクエリを高速化します。

 

元のリンク

この記事はAlibabaCloudのオリジナルのコンテンツであり、許可なく複製することはできません。

おすすめ

転載: blog.csdn.net/weixin_43970890/article/details/114120344