Building ETL data integration based on Flink SQL for streaming and batch integration
データウェアハウスとデータ統合
データウェアハウスとは、統合 (Integrated)、サブジェクト指向 (Subject-Oriented)、時間変動 (Time-Variant)、不揮発 (Nonvolatile) なデータコレクションであり、経営判断を支援するために使用されます。
これは、1990 年にデータウェアハウスの父 Bill Inmon が提唱したデータウェアハウスの概念です。
この概念で最も重要なポイントは「統合」であり、その他の特徴は方法論的なものです。
データウェアハウスが解決すべき最初の課題はデータ統合、つまり散在する複数の異種データソースを統合してデータの孤立を解消し、後続の分析を容易にすることだからです。
これは従来のオフラインデータウェアハウスだけでなく、リアルタイムデータウェアハウスや現在注目されているデータレイクにも当てはまります。
まず最初に解決すべきはデータ統合の課題です。
もし業務データがすべて 1 つのデータベースにあり、そのデータベースが非常に効率的なクエリと分析機能も提供できるのであれば、データウェアハウスやデータレイクは不要です。
データ統合は ETL と呼ばれるプロセスで、データの取得、データクレンジングと変換、そしてデータストレージと保存から構成されます。
これらは 3 つの英単語の頭文字に対応しているため、ETL と呼ばれます。
ETL プロセスはデータウェアハウス構築において最も作業量が多い工程でもあります。
では、Flink はこの ETL プロセスをどのように改善できるのでしょうか。
まず、従来のデータウェアハウスのアーキテクチャを見てみましょう。
従来のデータウェアハウスでは、リアルタイムデータウェアハウスとオフラインデータウェアハウスは 2 つの別々のリンクでした。
たとえば、リアルタイムリンクは Flume と Canal を通じてログデータとデータベースデータをリアルタイムに Kafka に同期し、Kafka 内でデータのクレンジングとワイドニングを行います。
一方、オフラインリンクは Flume と Sqoop を通じてログデータとデータベースデータを定期的に HDFS と Hive に同期し、Hive でデータのクレンジングとワイドニングを行います。
ここでは主にデータウェアハウス構築の前半部分、つまり ODS と DWD レイヤーまでに注目します。
この領域を広義の ETL データ統合の範囲と見なします。
この領域における従来のアーキテクチャの主な課題は、分割されたデータウェアハウス構築により多くの重複作業とリソースの重複消費が発生すること、そしてリアルタイムとオフラインの基盤データモデルが不整合であるため、データの整合性と品質の保証が困難になることです。
同時に、2 つのリンクのデータは分離されており、データの連携と共有が実現されていません。
では、Flink はこのアーキテクチャにどのような変化をもたらせるのでしょうか。
Flink SQL をベースに、ストリームバッチ統合 ETL データ統合を簡単に構築できるようになりました。
従来のデータウェアハウスアーキテクチャとの核心的な違いは、主に以下の点にあります。
Flink SQL は CDC をネイティブにサポートしているため、データベースへの直接接続でも、一般的な CDC ツール経由の接続でも、簡単にデータベースデータを同期できます。
最近のバージョンでは、Flink SQL はディメンションテーブル結合機能を継続的に強化しています。
データベース内のディメンションデータをリアルタイムに関連付けられるだけでなく、Hive や Kafka のディメンションデータも関連付けられるようになり、異なるワークロードと適時性の要件に柔軟に対応できます。
Flink の強力なストリーミング ETL 機能により、リアルタイムレイヤーでデータの取得とデータ変換を統一して行い、詳細レイヤーのデータをオフラインデータウェアハウスに戻すことができます。
Flink の Hive へのストリーミング取り込みでは、既に小ファイル自動マージ機能がサポートされており、小ファイルの課題を解決しています。
したがって、ストリームバッチ統合アーキテクチャにより、以下のメリットが得られます。
*基本共通データの統一
*ストリームとバッチの結果の整合性を保証
*オフラインデータウェアハウスの適時性を向上
*コンポーネントとリンクのメンテナンスコストを削減
次に、このアーキテクチャの各部分について、シナリオとケースを組み合わせて紹介します。
データ取得、データストレージとレイク取り込み、データワイドニングを含みます。
データ取得
データウェアハウスの典型的なデータソースは、主にログとデータベースに由来します。
ログ取得は現時点で非常に成熟しており、Flume、Filebeat、Logstash など、豊富なオープンソース製品から選択でき、Kafka にログを簡単に収集できます。
ここでは詳しく展開しません。
データベース取得はより複雑です。
よく使われる CDC 同期ツールには Canal、Debezium、Maxwell があります。
Flink はこれらの同期ツールと CDC フォーマットを通じて良好に連携し、これらのツールが生成するデータを直接消費できます。
同時に、Flink はネイティブ CDC コネクタも提供しており、データベースに直接接続し、アクセスのしきい値を下げ、データ同期プロセスを簡素化します。
まず CDC フォーマットの使用例を見てみましょう。
現在よく使われるソリューションは、Debezium または Canal を使用して MySQL データベースの binlog をリアルタイムに取得し、行レベルの変更イベントを Kafka に同期して Flink で分析処理する方法です。
Flink が CDC フォーマットをサポートする前は、ユーザーがこの種のデータを消費するのは非常に手間がかかりました。
ユーザーは CDC ツールのデータ形式を理解し、before や after などのフィールドを宣言し、ROW_NUMBER で重複排除を行って最新の 1 行のみをリアルタイムに保持するセマンティクスを実装する必要がありました。
しかし、これは使用コストが高く、DELETE イベントもサポートされていませんでした。
現在、Flink は CDC フォーマットをサポートしています。
たとえば、with パラメーターで format = 'debezium-json' を直接指定し、schema 部分にはデータベース内のテーブルのスキーマを記述するだけで済みます。
Flink は Debezium の INSERT/UPDATE/DELETE イベントを自動的に認識し、Flink 内部の INSERT/UPDATE/DELETE メッセージに変換します。
その後、ユーザーはテーブルに対して集約や結合などの操作を直接実行できます。
MySQL のリアルタイムマテリアライズドビューを操作するようなもので、非常に便利です。
Flink のバージョン 1.12 では、Canal json、Debezium json、Debezium avro、Maxwell など、主要な CDC フォーマットの大部分をネイティブにサポートしています。
同時に、Flink は CDC フォーマットインターフェイスも公開しており、ユーザーは独自の CDC フォーマットプラグインを実装して、自社の同期ツールと連携できます。
さらに、Flink は内部で CDC のセマンティクスをサポートしているため、MySQL の binlog データを直接読み取り、Flink 内部の変更メッセージに変換することが自然にできます。
そこで MySQL CDC コネクタが導入されました。
with パラメーターで connector=mysql-cdc を指定するだけで、追加のコンポーネントやサービスをデプロイせずに、テーブルを選択するだけで MySQL のフルデータと CDC 増分データをリアルタイムで読み取れます。
Flink で定義されたテーブルを MySQL のリアルタイムマテリアライズドビューとして理解できるため、このテーブルに対する集約や結合の結果は、MySQL でリアルタイムに実行した結果と一致します。
先ほど紹介した Debezium や Canal アーキテクチャと比較して、CDC コネクタはより簡単に使用できます。
追加のコンポーネントを学習・メンテナンスする必要がなく、データが Kafka を経由しないため、エンドツーエンドのレイテンシを削減できます。
さらに、まずフルデータを読み取り、シームレスに CDC 増分読み取りに切り替えることをサポートしています。
つまり、ストリームバッチ統合・ストリームバッチ融合アーキテクチャということです。
MySQL CDC コネクタはユーザーに非常に人気があり、特に OLAP エンジンと組み合わせると、リアルタイム OLAP アーキテクチャを迅速に構築できることがわかりました。
リアルタイム OLAP アーキテクチャの特徴の 1 つは、データベースデータを OLAP に同期してアドホッククエリを実行することで、オフラインデータウェアハウスが不要になることです。
以前はどのように行っていたのでしょうか。
以前は、ユーザーが DataX でフルデータ同期を行い、Canal でリアルタイム増分を Kafka に同期し、Kafka から OLAP に同期するのが一般的でした。
このアーキテクチャはより複雑で、リンクも非常に長くなります。
現在、多くの企業が Flink+ClickHouse を使用してリアルタイム OLAP アーキテクチャを迅速に構築しています。
Flink で mysql-cdc ソースと ClickHouse シンクを定義し、insert into クエリを送信するだけで、MySQL から ClickHouse へのリアルタイム同期が完了します。
非常に便利です。
さらに、ClickHouse の課題の 1 つである結合操作が比較的低速であるため、一般的に MySQL データを大きな詳細ワイドテーブルデータにフォーマットしてから ClickHouse に書き込みます。
これは Flink で 1 回の結合操作で完了します。
Flink が MySQL CDC コネクタを提供する前は、フルデータと増分データのリアルタイム同期プロセスでの結合は非常に手間がかかりました。
もちろん、ここでは ClickHouse を他の一般的な OLAP エンジン、たとえば Alibaba Cloud の Hologres に置き換えることもできます。
Alibaba Cloud では、多くのユーザーがこのリンクとアーキテクチャを採用していることがわかりました。
データ同期サービスとメッセージミドルウェアのコストを節約できるからです。
多くの中堅企業にとって、コスト管理は非常に重要です。
もちろん、TiDB などの他の OLAP エンジンもここで使用できます。
TiDB 公式も最近、Flink+TiDB のリアルタイム OLAP アーキテクチャを紹介する記事を公開しました。
データストレージとレイク取り込み
先ほど、データ取得は Flink SQL をベースに非常に簡単に行えると紹介しました。
これは ETL の Extract 部分です。
次に、Flink SQL のデータをレイクに格納する機能、つまり Load 部分について紹介します。
先ほどのストリームバッチ統合のアーキテクチャ図を振り返ると、その核心部分は Kafka データのウェアハウスへのストリーミング取り込みです。
このプロセスにより、リアルタイムとオフラインのデータウェアハウスが接続され、データウェアハウスの基本共通データが統一され、オフラインデータウェアハウスの適時性が向上します。
Flink SQL を使用したストリーミングデータ格納は非常に便利で、バージョン 1.12 では小ファイルの自動マージが既にサポートされており、小ファイルの課題を解決しています。
右側のコードを見てください。
まず、Flink SQL で Hive ダイアレクトを使用して Hive 結果テーブルを作成し、Kafka テーブルから Hive テーブルへの select from insert into というシンプルなクエリを使用して、Kafka データをリアルタイムに Hive にストリーミング取り込みするタスクを送信します。
小ファイルのコンパクションを有効にするには、Hive テーブルのパラメーターに auto-compaction = true を追加するだけで、この Hive テーブルへのストリーミング取り込み時に自動的に小ファイルのコンパクションが実行されます。
小ファイルマージの原理は、Flink のストリーミングシンクが小さなトポロジーを作成し、その中で temp writer ノードが受信データを継続的に一時ファイルに書き込みます。
チェックポイントを受信すると、compact coordinator に通知され、小ファイルのコンパクションが開始されます。
coordinator はコンパクションタスクを複数の compact operator に分散し、並列で小ファイルをマージします。
コンパクション完了後、partition committer に通知してパーティションファイル全体をコミットし、可視化します。
プロセス全体は Flink 独自のチェックポイントメカニズムを使用してコンパクションの自動化を完了し、追加のコンパクションサービスを必要としません。
これこそが Flink のストリーミングデータ取り込みが他のデータ取り込みツールと比較した核心的な優位性です。
ウェアハウスへのストリーミング取り込みに加え、Flink は現在レイクへのストリーミング取り込みもサポートしています。
Iceberg を例に取ると、Iceberg 0.10 をベースに、Flink SQL 内で直接 Iceberg catalog を作成し、create table で Iceberg catalog 直下に Iceberg テーブルを作成できます。
そして insert into クエリを送信してストリーミングデータを Iceberg に取り込みます。
その後、Iceberg テーブルを Flink でバッチモードで読み取り、オフライン分析を行うことができます。
ただし、Iceberg の小ファイル自動マージ機能はまだリリースされておらず、引き続きサポートが開発中です。
ここまで紹介したのは、純粋な append データのウェアハウスおよびレイクへのストリーミング取り込み機能です。
次に、CDC データのウェアハウスおよびレイクへのストリーミング取り込み機能を紹介します。
まず、CDC データの Kafka リアルタイムデータウェアハウスへの取り込みから始めます。
この要件はリアルタイムデータウェアハウス構築で非常に一般的です。
たとえば、データベースの binlog データを Kafka に同期したり、結合や集約の結果が更新ストリームであり、ユーザーはこの更新ストリームを中間データとして Kafka に書き込み、下流の消費用にしたい場合があります。
以前はこれが非常に手間がかかりました。
Flink 1.12 で、Flink は upsert-kafka という新しいコネクタを導入し、Kafka を効率的な CDC ストリーミングストレージとしてネイティブにサポートするようになりました。
なぜ効率的なのでしょうか。
ストレージ形式が Kafka のログコンパクションメカニズムと高度に統合されており、Kafka がトピックデータのコンパクションクリーンアップを自動的に実行しても、Flink はクリーンアップ後のデータを読み取ってもセマンティックな一貫性を確保できるからです。
また、Canal や Debezium のように before や op_type などの不要なメタデータ情報を大量に保存するのではなく、upsert-kafka はデータの内容自体のみを保存し、多くのストレージコストを節約します。
使用面では、DDL で connector = upsert-kafka を宣言し、PK を定義するだけです。
たとえば、ここで MySQL CDC のライブルームテーブルと upsert-kafka の結果テーブルを定義して、ライブルームデータベースを Kafka に同期します。
Kafka に書き込まれる INSERT と UPDATE はキー付きの通常データで、DELETE はキー付きの NULL データです。
Flink がこの upsert-kafka のデータを読み取る際、INSERT/UPDATE/DELETE メッセージを自動的に認識できます。
この upsert-kafka テーブルを消費することは、MySQL CDC テーブルを消費することと同じセマンティクスです。
そして、Kafka がトピックデータのコンパクションクリーンアップを実行しても、Flink はクリーンアップ後のデータを読み取ってセマンティックな一貫性を確保できます。
CDC データの Hive データウェアハウスへの取り込みはより複雑です。
Hive 自体が CDC のセマンティクスをサポートしていないからです。
一般的な方法は、CDC データを changelog-json 形式で HDFS にストリーミング書き込みし、バッチタスクを起動して定期的に HDFS 上の CDC データを op タイプ別に INSERT、UPDATE、DELETE の 3 つのテーブルに分割してからバッチマージを行うことです。
データワイドニング
先に Flink SQL ベースの ETL プロセスの Extract と Load を紹介したので、次に Transformation で最も一般的なデータワイドニング操作について紹介します。
データワイドニングはデータ統合で最も一般的な業務処理シナリオです。
データワイドニングの主な手段は Join です。
Flink SQL は Regular Join、Interval Join、Temporal Join など、豊富な Join サポートを提供しています。
Regular Join はよく知られたデュアルストリーム Join で、構文は一般的な JOIN 構文です。
図の例は、広告表示ストリームと広告クリックストリームを関連付けて広告データをワイドニングするものです。
ワイドニング後、広告コストをさらに計算できます。
図からわかるように、表示ストリームとクリックストリームの両方が Join ノードのステートに保存され、結合演算子は表示ストリームとクリックストリームのステートを関連付けてデータワイドニングを実現します。
Regular Join の特徴は、どちらかのストリームが結果の更新をトリガーすることで、例の表示ストリームとクリックストリームがそれに該当します。
同時に、Regular Join の構文は従来のバッチ SQL と一致しており、ユーザーの学習しきい値は低くなります。
ただし注意すべきは、Regular Join はステートを使用してデュアルストリームの既に到着したデータを保存し、ステートはデフォルトで永続的に保持されるため、Regular Join の問題点の 1 つはステートがデフォルトで継続的に増え続けることで、一般的に state TTL と組み合わせて使用します。
Interval Join はストリームに時間間隔を要求する結合です。
たとえば、先ほどの広告課金ケースには非常に典型的な業務特徴があります。
つまり、クリックは一般的に表示後 10 分以内に発生します。
したがって、Regular Join と比較して、実際には 10 分以内の表示データのみを関連付ければよいため、ステートにフル量の表示データを保存する必要はありません。
これは Regular Join に基づく最適化です。
Interval Join に変換するには、両ストリームに時間属性フィールド(図の click_time と show_time)を定義する必要があります。
そして、結合条件で左右のストリームの時間間隔を定義します。
たとえば、ここではクリック時間が表示時間以上であり、同時に表示後 10 分以下であるという条件を追加します。
Regular Join と同様に、Interval Join のどちらかのストリームが結果の更新をトリガーしますが、Regular Join と比較して、Interval Join の最大のメリットはステートが自動的にクリーンアップされ、時間間隔に基づいてデータが保持され、ステートの占有が大幅に削減されることです。
Interval Join は明確なビジネス時間間隔がある業務に適しています。
たとえば、表示フローとクリックフロー、クリックフローと注文フロー、注文フローと配送の関連付けなどです。
Temporal Join(テンポラルテーブル関連付け)は最も一般的に使用されるデータワイドニング方法で、よく知られたディメンションテーブル結合を行う際によく使用されます。構文上、明示的な FOR SYSTEM_TIME AS OF 文が必要です。Regular Join や Interval Join との最大の違いは、ディメンションデータの変更が結果の更新をトリガーしないことで、メインストリームに関連付けられたディメンションデータは変化しません。Flink は非常に豊富な Temporal Join 機能をサポートしており、関連ルックアップ DB、関連変更ログ、関連 Hive テーブルを含みます。従来、よく知られたディメンションテーブル結合は一般的にクエリ可能なデータベースに関連付けられていました。ディメンションデータがデータベース内にあるからです。しかし実際には、ディメンションデータは binlog 形式や、定期的に Hive に同期されて Hive パーティションテーブル形式になるなど、さまざまな物理形態を持つ可能性があります。Flink 1.12 では、これら 2 つの新しいディメンションテーブル形式の関連付けがサポートされています。
Temporal Join Lookup DB は最も一般的なディメンションテーブル結合方法です。たとえば、ユーザークリックストリームとユーザープロファイルの関連付けケースでは、ユーザークリックストリームは Kafka にあり、ユーザーのリアルタイムプロファイルは HBase データベースに保存されており、各クリックイベントごとに HBase にクエリしてユーザーのリアルタイムプロファイルと関連付け、データワイドニングを完了します。Temporal Join Lookup DB の特徴は、ディメンションテーブルの更新が結果の更新をトリガーせず、ディメンションデータはデータベースに保存されており、リアルタイム要件が高いシナリオに適しています。使用する際は、一般的に Async IO とメモリキャッシュを有効にしてクエリ効率を向上させます。
Temporal Join Changelog を紹介する前に、もう 1 つの Lookup DB の例を見てみましょう。ライブ配信インタラクションデータとライブルームディメンションの関連付けケースです。このケースでは、ライブ配信インタラクションデータ(いいね、コメントなど)は Kafka に保存され、ライブルームのリアルタイムディメンションデータ(アンカー、ライブルームのタイトルなど)は MySQL に保存されています。ライブ配信インタラクションデータの量は非常に多く、アクセスを高速化するため、一般的なソリューションはキャッシュを追加することです。たとえば、CDC を通じてライブルームのディメンションデータを同期し、Redis に保存してからディメンションテーブル関連付けを行います。このソリューションの課題は、ライブ配信の業務データが特殊であることです。ライブルームの作成とライブ配信のインタラクションデータは基本的に同時に生成されるため、インタラクションデータは早く Kafka に到着して Flink に消費される可能性がありますが、ライブルームの作成メッセージは Canal、Kafka、Redis を経由するリンクが比較的長く、データ遅延が比較的大きいため、インタラクションデータが Redis をクエリする時点でライブルームデータがまだ同期されていない可能性があり、その結果ライブルームデータとの関連付けができず、下流の統計分析に偏差が生じる可能性があります。
このようなシナリオに対応するため、Flink 1.12 では Temporal Join Changelog をサポートしており、Flink ステート内の更新ログからディメンションテーブルを具体化することでディメンションテーブル関連付けを実現しています。先ほどのシナリオにはより簡潔なソリューションがあります。Flink CDC コネクタを通じてライブルームデータベーステーブルの更新ログを Kafka に同期できます。右側の SQL に注目してください。upsert-kafka コネクタを使用して MySQL binlog を Kafka に書き込みます。つまり、ライブルームの変更データを Kafka に upsert ストリームとして保存します。そして、インタラクションデータをライブルームの upsert ストリームとテンポラル結合し、ライブ配信データのワイドニング機能を実現します。
ここで注意すべきは、FOR SYSTEM_TIME AS OF は処理時間に関連するのではなく、左ストリームのイベント時間に関連するということです。その意味は、このイベント時点でのライブルームデータを関連付けることです。同時に、ライブルームの upsert ストリームにウォーターマークを定義しているため、Temporal Join Changelog は実行時にウォーターマークの待機とアライメントを行い、結果の正確なバージョンとの関連付けを確保し、以前のソリューションでの関連付けできない問題を解決します。
Temporal Join Changelog のプロセスを詳しく説明します。左ストリームはインタラクティブストリームデータで、右ストリームはライブルームの更新ログです。ライブルームの更新ログは右ストリームのディメンションテーブルステートに具体化されます。このステートはマルチバージョンデータベースのミラーのようなものです。メインストリームのインタラクションデータは左ストリームのステートに一時的にキャッシュされます。ウォーターマークがアライメントされた後、ディメンションテーブルのステート内のデータを確認します。たとえば、インタラクティブストリームとライブストリームの両方のウォーターマークが 10:01 に達した場合、インタラクティブストリームの 10:01 のコメントデータがディメンションテーブルステートからクエリされ、room 103 と関連付けられます。10:05 にコメントデータが到着しても、すぐに出力されません。そうでなければ、その時点のライブルーム情報と関連付けられてしまいます。左右のストリームのウォーターマークが 10:05 に達するまで待機してから、ディメンションテーブルステート内のデータと関連付けて出力します。この時点で正確な 104 のライブルーム情報と関連付けることができます。
まとめると、Temporal Join Changelog の特徴は高いリアルタイム性能です。イベント時間に基づいてバージョンと関連付けるため、正確なバージョン情報と関連付けることができ、ディメンションテーブルはウォーターマークのアライメントを待機するため、ユーザーはウォーターマークを通じてディメンションテーブルのタイミングを制御できます。Temporal Join Changelog のディメンションテーブルデータはテンポラル結合ノードのステートに保存されており、読み取りはローカルの Redis と同様に非常に効率的で、ユーザーは追加の Redis コンポーネントをメンテナンスする必要がなくなります。
データウェアハウスシナリオでは Hive が広く使用されており、Flink と Hive の統合は非常に友好的です。現在、Hive パーティションテーブルと非パーティションテーブルの Temporal Join をサポートしています。Hive パーティションテーブルを関連付ける典型的なケースを見てみましょう。注文フローと店舗データの関連付けです。店舗データは一般的にゆっくり変化するため、業務側は一般的にフル店舗テーブルを日次で Hive パーティションに同期し、毎日新しいパーティションが生成され、各パーティションにはその日のフル店舗データが含まれます。
この種の Hive データを関連付けるには、Hive パーティションテーブルを作成する際に右側の 2 つの赤い丸のパラメーターを指定するだけで、Hive の最新パーティションを自動的に関連付ける機能を実現できます。partition.include = latest は Hive の最新パーティションのみを読み取ることを意味し、partition-name は最新パーティションを選択する際にパーティション名でアルファベット順にソートすることを示します。10 月 3 日の時点で、Hive に 10 月 2 日の新しいパーティションが生成されています。Flink は新しいパーティションを検出すると、10 月 2 日のデータをキャッシュに再読み込みし、10 月 1 日のデータを置き換えて最新のディメンションテーブルとします。後続の注文フローデータは、キャッシュ内の 10 月 2 日パーティションのデータと関連付けられます。Temporal Join Hive の特徴は、最新の Hive パーティションを自動的に関連付けられることで、ディメンションテーブルの更新が遅い業務シナリオや高スループットのシナリオに適しています。
先ほど紹介したデータワイドニングに使用されるいくつかの Join をまとめます。
Regular Join の適時性は非常に高く、スループットは平均的です。ステートがすべての到着データを保持するためで、デュアルストリーム結合シナリオに適しています。
Interval Join の適時性は非常に良く、スループットはより良好です。ステートが時間間隔内のデータのみを保持するためで、ビジネス時間間隔があるデュアルストリーム結合シナリオに適しています。
Temporal Join Lookup DB の適時性はより良好で、スループットは低めです。各データが外部システムへのクエリを必要とし、IO オーバーヘッドが発生するためで、ディメンションテーブルがデータベース内にあるシナリオに適しています。
Temporal Join Changelog の適時性は良好で、スループットも良好です。IO オーバーヘッドがないためで、ディメンションテーブルの待機が必要なシナリオや正確なバージョンとの結合が必要なシナリオに適しています。
Temporal Join Hive の適時性は平均的ですが、スループットは非常に良好です。ディメンションテーブルのデータがキャッシュに保存されているためで、ディメンションテーブルの更新が遅いシナリオや高スループットが必要なシナリオに適しています。
まとめ
最後に、Flink の ETL データ統合における機能をまとめましょう。これは現在の Flink データ統合の機能マトリックスです。既存の外部ストレージシステムをリレーショナルデータベース、KV データベース、メッセージキュー、データレイク、データウェアハウスの 5 つに分類しています。図からわかるように、Flink は非常に豊富なエコシステムを持ち、各ストレージエンジンに対して非常に強力な統合機能を持っています。
横軸では、6 つの機能を定義しています。3 つのデータアクセス機能、すなわちフルデータ読み取り、ストリーミング読み取り、CDC ストリーミング読み取り。1 つのデータワイドニング機能、すなわちディメンション関連付け。そして 2 つのストレージ/レイク取り込み機能、すなわちストリーム書き込みと CDC 書き込みです。
Flink の各システムに対するデータアクセス機能、ディメンションワイドニング機能、そしてストレージ/レイク取り込み機能が既に非常に完全であることがわかります。CDC ストリーミング読み取りについては、Flink は既に主流データベースと Kafka メッセージキューをサポートしています。データレイク方面では、Iceberg に対する Flink のストリーミング読み取りと CDC 書き込み機能も次の Iceberg バージョンでリリースされます。この機能マトリックスから、Flink のデータ統合機能が非常に包括的であることがわかります。
データウェアハウスとは、統合 (Integrated)、サブジェクト指向 (Subject-Oriented)、時間変動 (Time-Variant)、不揮発 (Nonvolatile) なデータコレクションであり、経営判断を支援するために使用されます。
これは、1990 年にデータウェアハウスの父 Bill Inmon が提唱したデータウェアハウスの概念です。
この概念で最も重要なポイントは「統合」であり、その他の特徴は方法論的なものです。
データウェアハウスが解決すべき最初の課題はデータ統合、つまり散在する複数の異種データソースを統合してデータの孤立を解消し、後続の分析を容易にすることだからです。
これは従来のオフラインデータウェアハウスだけでなく、リアルタイムデータウェアハウスや現在注目されているデータレイクにも当てはまります。
まず最初に解決すべきはデータ統合の課題です。
もし業務データがすべて 1 つのデータベースにあり、そのデータベースが非常に効率的なクエリと分析機能も提供できるのであれば、データウェアハウスやデータレイクは不要です。
データ統合は ETL と呼ばれるプロセスで、データの取得、データクレンジングと変換、そしてデータストレージと保存から構成されます。
これらは 3 つの英単語の頭文字に対応しているため、ETL と呼ばれます。
ETL プロセスはデータウェアハウス構築において最も作業量が多い工程でもあります。
では、Flink はこの ETL プロセスをどのように改善できるのでしょうか。
まず、従来のデータウェアハウスのアーキテクチャを見てみましょう。
従来のデータウェアハウスでは、リアルタイムデータウェアハウスとオフラインデータウェアハウスは 2 つの別々のリンクでした。
たとえば、リアルタイムリンクは Flume と Canal を通じてログデータとデータベースデータをリアルタイムに Kafka に同期し、Kafka 内でデータのクレンジングとワイドニングを行います。
一方、オフラインリンクは Flume と Sqoop を通じてログデータとデータベースデータを定期的に HDFS と Hive に同期し、Hive でデータのクレンジングとワイドニングを行います。
ここでは主にデータウェアハウス構築の前半部分、つまり ODS と DWD レイヤーまでに注目します。
この領域を広義の ETL データ統合の範囲と見なします。
この領域における従来のアーキテクチャの主な課題は、分割されたデータウェアハウス構築により多くの重複作業とリソースの重複消費が発生すること、そしてリアルタイムとオフラインの基盤データモデルが不整合であるため、データの整合性と品質の保証が困難になることです。
同時に、2 つのリンクのデータは分離されており、データの連携と共有が実現されていません。
では、Flink はこのアーキテクチャにどのような変化をもたらせるのでしょうか。
Flink SQL をベースに、ストリームバッチ統合 ETL データ統合を簡単に構築できるようになりました。
従来のデータウェアハウスアーキテクチャとの核心的な違いは、主に以下の点にあります。
Flink SQL は CDC をネイティブにサポートしているため、データベースへの直接接続でも、一般的な CDC ツール経由の接続でも、簡単にデータベースデータを同期できます。
最近のバージョンでは、Flink SQL はディメンションテーブル結合機能を継続的に強化しています。
データベース内のディメンションデータをリアルタイムに関連付けられるだけでなく、Hive や Kafka のディメンションデータも関連付けられるようになり、異なるワークロードと適時性の要件に柔軟に対応できます。
Flink の強力なストリーミング ETL 機能により、リアルタイムレイヤーでデータの取得とデータ変換を統一して行い、詳細レイヤーのデータをオフラインデータウェアハウスに戻すことができます。
Flink の Hive へのストリーミング取り込みでは、既に小ファイル自動マージ機能がサポートされており、小ファイルの課題を解決しています。
したがって、ストリームバッチ統合アーキテクチャにより、以下のメリットが得られます。
*基本共通データの統一
*ストリームとバッチの結果の整合性を保証
*オフラインデータウェアハウスの適時性を向上
*コンポーネントとリンクのメンテナンスコストを削減
次に、このアーキテクチャの各部分について、シナリオとケースを組み合わせて紹介します。
データ取得、データストレージとレイク取り込み、データワイドニングを含みます。
データ取得
データウェアハウスの典型的なデータソースは、主にログとデータベースに由来します。
ログ取得は現時点で非常に成熟しており、Flume、Filebeat、Logstash など、豊富なオープンソース製品から選択でき、Kafka にログを簡単に収集できます。
ここでは詳しく展開しません。
データベース取得はより複雑です。
よく使われる CDC 同期ツールには Canal、Debezium、Maxwell があります。
Flink はこれらの同期ツールと CDC フォーマットを通じて良好に連携し、これらのツールが生成するデータを直接消費できます。
同時に、Flink はネイティブ CDC コネクタも提供しており、データベースに直接接続し、アクセスのしきい値を下げ、データ同期プロセスを簡素化します。
まず CDC フォーマットの使用例を見てみましょう。
現在よく使われるソリューションは、Debezium または Canal を使用して MySQL データベースの binlog をリアルタイムに取得し、行レベルの変更イベントを Kafka に同期して Flink で分析処理する方法です。
Flink が CDC フォーマットをサポートする前は、ユーザーがこの種のデータを消費するのは非常に手間がかかりました。
ユーザーは CDC ツールのデータ形式を理解し、before や after などのフィールドを宣言し、ROW_NUMBER で重複排除を行って最新の 1 行のみをリアルタイムに保持するセマンティクスを実装する必要がありました。
しかし、これは使用コストが高く、DELETE イベントもサポートされていませんでした。
現在、Flink は CDC フォーマットをサポートしています。
たとえば、with パラメーターで format = 'debezium-json' を直接指定し、schema 部分にはデータベース内のテーブルのスキーマを記述するだけで済みます。
Flink は Debezium の INSERT/UPDATE/DELETE イベントを自動的に認識し、Flink 内部の INSERT/UPDATE/DELETE メッセージに変換します。
その後、ユーザーはテーブルに対して集約や結合などの操作を直接実行できます。
MySQL のリアルタイムマテリアライズドビューを操作するようなもので、非常に便利です。
Flink のバージョン 1.12 では、Canal json、Debezium json、Debezium avro、Maxwell など、主要な CDC フォーマットの大部分をネイティブにサポートしています。
同時に、Flink は CDC フォーマットインターフェイスも公開しており、ユーザーは独自の CDC フォーマットプラグインを実装して、自社の同期ツールと連携できます。
さらに、Flink は内部で CDC のセマンティクスをサポートしているため、MySQL の binlog データを直接読み取り、Flink 内部の変更メッセージに変換することが自然にできます。
そこで MySQL CDC コネクタが導入されました。
with パラメーターで connector=mysql-cdc を指定するだけで、追加のコンポーネントやサービスをデプロイせずに、テーブルを選択するだけで MySQL のフルデータと CDC 増分データをリアルタイムで読み取れます。
Flink で定義されたテーブルを MySQL のリアルタイムマテリアライズドビューとして理解できるため、このテーブルに対する集約や結合の結果は、MySQL でリアルタイムに実行した結果と一致します。
先ほど紹介した Debezium や Canal アーキテクチャと比較して、CDC コネクタはより簡単に使用できます。
追加のコンポーネントを学習・メンテナンスする必要がなく、データが Kafka を経由しないため、エンドツーエンドのレイテンシを削減できます。
さらに、まずフルデータを読み取り、シームレスに CDC 増分読み取りに切り替えることをサポートしています。
つまり、ストリームバッチ統合・ストリームバッチ融合アーキテクチャということです。
MySQL CDC コネクタはユーザーに非常に人気があり、特に OLAP エンジンと組み合わせると、リアルタイム OLAP アーキテクチャを迅速に構築できることがわかりました。
リアルタイム OLAP アーキテクチャの特徴の 1 つは、データベースデータを OLAP に同期してアドホッククエリを実行することで、オフラインデータウェアハウスが不要になることです。
以前はどのように行っていたのでしょうか。
以前は、ユーザーが DataX でフルデータ同期を行い、Canal でリアルタイム増分を Kafka に同期し、Kafka から OLAP に同期するのが一般的でした。
このアーキテクチャはより複雑で、リンクも非常に長くなります。
現在、多くの企業が Flink+ClickHouse を使用してリアルタイム OLAP アーキテクチャを迅速に構築しています。
Flink で mysql-cdc ソースと ClickHouse シンクを定義し、insert into クエリを送信するだけで、MySQL から ClickHouse へのリアルタイム同期が完了します。
非常に便利です。
さらに、ClickHouse の課題の 1 つである結合操作が比較的低速であるため、一般的に MySQL データを大きな詳細ワイドテーブルデータにフォーマットしてから ClickHouse に書き込みます。
これは Flink で 1 回の結合操作で完了します。
Flink が MySQL CDC コネクタを提供する前は、フルデータと増分データのリアルタイム同期プロセスでの結合は非常に手間がかかりました。
もちろん、ここでは ClickHouse を他の一般的な OLAP エンジン、たとえば Alibaba Cloud の Hologres に置き換えることもできます。
Alibaba Cloud では、多くのユーザーがこのリンクとアーキテクチャを採用していることがわかりました。
データ同期サービスとメッセージミドルウェアのコストを節約できるからです。
多くの中堅企業にとって、コスト管理は非常に重要です。
もちろん、TiDB などの他の OLAP エンジンもここで使用できます。
TiDB 公式も最近、Flink+TiDB のリアルタイム OLAP アーキテクチャを紹介する記事を公開しました。
データストレージとレイク取り込み
先ほど、データ取得は Flink SQL をベースに非常に簡単に行えると紹介しました。
これは ETL の Extract 部分です。
次に、Flink SQL のデータをレイクに格納する機能、つまり Load 部分について紹介します。
先ほどのストリームバッチ統合のアーキテクチャ図を振り返ると、その核心部分は Kafka データのウェアハウスへのストリーミング取り込みです。
このプロセスにより、リアルタイムとオフラインのデータウェアハウスが接続され、データウェアハウスの基本共通データが統一され、オフラインデータウェアハウスの適時性が向上します。
Flink SQL を使用したストリーミングデータ格納は非常に便利で、バージョン 1.12 では小ファイルの自動マージが既にサポートされており、小ファイルの課題を解決しています。
右側のコードを見てください。
まず、Flink SQL で Hive ダイアレクトを使用して Hive 結果テーブルを作成し、Kafka テーブルから Hive テーブルへの select from insert into というシンプルなクエリを使用して、Kafka データをリアルタイムに Hive にストリーミング取り込みするタスクを送信します。
小ファイルのコンパクションを有効にするには、Hive テーブルのパラメーターに auto-compaction = true を追加するだけで、この Hive テーブルへのストリーミング取り込み時に自動的に小ファイルのコンパクションが実行されます。
小ファイルマージの原理は、Flink のストリーミングシンクが小さなトポロジーを作成し、その中で temp writer ノードが受信データを継続的に一時ファイルに書き込みます。
チェックポイントを受信すると、compact coordinator に通知され、小ファイルのコンパクションが開始されます。
coordinator はコンパクションタスクを複数の compact operator に分散し、並列で小ファイルをマージします。
コンパクション完了後、partition committer に通知してパーティションファイル全体をコミットし、可視化します。
プロセス全体は Flink 独自のチェックポイントメカニズムを使用してコンパクションの自動化を完了し、追加のコンパクションサービスを必要としません。
これこそが Flink のストリーミングデータ取り込みが他のデータ取り込みツールと比較した核心的な優位性です。
ウェアハウスへのストリーミング取り込みに加え、Flink は現在レイクへのストリーミング取り込みもサポートしています。
Iceberg を例に取ると、Iceberg 0.10 をベースに、Flink SQL 内で直接 Iceberg catalog を作成し、create table で Iceberg catalog 直下に Iceberg テーブルを作成できます。
そして insert into クエリを送信してストリーミングデータを Iceberg に取り込みます。
その後、Iceberg テーブルを Flink でバッチモードで読み取り、オフライン分析を行うことができます。
ただし、Iceberg の小ファイル自動マージ機能はまだリリースされておらず、引き続きサポートが開発中です。
ここまで紹介したのは、純粋な append データのウェアハウスおよびレイクへのストリーミング取り込み機能です。
次に、CDC データのウェアハウスおよびレイクへのストリーミング取り込み機能を紹介します。
まず、CDC データの Kafka リアルタイムデータウェアハウスへの取り込みから始めます。
この要件はリアルタイムデータウェアハウス構築で非常に一般的です。
たとえば、データベースの binlog データを Kafka に同期したり、結合や集約の結果が更新ストリームであり、ユーザーはこの更新ストリームを中間データとして Kafka に書き込み、下流の消費用にしたい場合があります。
以前はこれが非常に手間がかかりました。
Flink 1.12 で、Flink は upsert-kafka という新しいコネクタを導入し、Kafka を効率的な CDC ストリーミングストレージとしてネイティブにサポートするようになりました。
なぜ効率的なのでしょうか。
ストレージ形式が Kafka のログコンパクションメカニズムと高度に統合されており、Kafka がトピックデータのコンパクションクリーンアップを自動的に実行しても、Flink はクリーンアップ後のデータを読み取ってもセマンティックな一貫性を確保できるからです。
また、Canal や Debezium のように before や op_type などの不要なメタデータ情報を大量に保存するのではなく、upsert-kafka はデータの内容自体のみを保存し、多くのストレージコストを節約します。
使用面では、DDL で connector = upsert-kafka を宣言し、PK を定義するだけです。
たとえば、ここで MySQL CDC のライブルームテーブルと upsert-kafka の結果テーブルを定義して、ライブルームデータベースを Kafka に同期します。
Kafka に書き込まれる INSERT と UPDATE はキー付きの通常データで、DELETE はキー付きの NULL データです。
Flink がこの upsert-kafka のデータを読み取る際、INSERT/UPDATE/DELETE メッセージを自動的に認識できます。
この upsert-kafka テーブルを消費することは、MySQL CDC テーブルを消費することと同じセマンティクスです。
そして、Kafka がトピックデータのコンパクションクリーンアップを実行しても、Flink はクリーンアップ後のデータを読み取ってセマンティックな一貫性を確保できます。
CDC データの Hive データウェアハウスへの取り込みはより複雑です。
Hive 自体が CDC のセマンティクスをサポートしていないからです。
一般的な方法は、CDC データを changelog-json 形式で HDFS にストリーミング書き込みし、バッチタスクを起動して定期的に HDFS 上の CDC データを op タイプ別に INSERT、UPDATE、DELETE の 3 つのテーブルに分割してからバッチマージを行うことです。
データワイドニング
先に Flink SQL ベースの ETL プロセスの Extract と Load を紹介したので、次に Transformation で最も一般的なデータワイドニング操作について紹介します。
データワイドニングはデータ統合で最も一般的な業務処理シナリオです。
データワイドニングの主な手段は Join です。
Flink SQL は Regular Join、Interval Join、Temporal Join など、豊富な Join サポートを提供しています。
Regular Join はよく知られたデュアルストリーム Join で、構文は一般的な JOIN 構文です。
図の例は、広告表示ストリームと広告クリックストリームを関連付けて広告データをワイドニングするものです。
ワイドニング後、広告コストをさらに計算できます。
図からわかるように、表示ストリームとクリックストリームの両方が Join ノードのステートに保存され、結合演算子は表示ストリームとクリックストリームのステートを関連付けてデータワイドニングを実現します。
Regular Join の特徴は、どちらかのストリームが結果の更新をトリガーすることで、例の表示ストリームとクリックストリームがそれに該当します。
同時に、Regular Join の構文は従来のバッチ SQL と一致しており、ユーザーの学習しきい値は低くなります。
ただし注意すべきは、Regular Join はステートを使用してデュアルストリームの既に到着したデータを保存し、ステートはデフォルトで永続的に保持されるため、Regular Join の問題点の 1 つはステートがデフォルトで継続的に増え続けることで、一般的に state TTL と組み合わせて使用します。
Interval Join はストリームに時間間隔を要求する結合です。
たとえば、先ほどの広告課金ケースには非常に典型的な業務特徴があります。
つまり、クリックは一般的に表示後 10 分以内に発生します。
したがって、Regular Join と比較して、実際には 10 分以内の表示データのみを関連付ければよいため、ステートにフル量の表示データを保存する必要はありません。
これは Regular Join に基づく最適化です。
Interval Join に変換するには、両ストリームに時間属性フィールド(図の click_time と show_time)を定義する必要があります。
そして、結合条件で左右のストリームの時間間隔を定義します。
たとえば、ここではクリック時間が表示時間以上であり、同時に表示後 10 分以下であるという条件を追加します。
Regular Join と同様に、Interval Join のどちらかのストリームが結果の更新をトリガーしますが、Regular Join と比較して、Interval Join の最大のメリットはステートが自動的にクリーンアップされ、時間間隔に基づいてデータが保持され、ステートの占有が大幅に削減されることです。
Interval Join は明確なビジネス時間間隔がある業務に適しています。
たとえば、表示フローとクリックフロー、クリックフローと注文フロー、注文フローと配送の関連付けなどです。
Temporal Join(テンポラルテーブル関連付け)は最も一般的に使用されるデータワイドニング方法で、よく知られたディメンションテーブル結合を行う際によく使用されます。構文上、明示的な FOR SYSTEM_TIME AS OF 文が必要です。Regular Join や Interval Join との最大の違いは、ディメンションデータの変更が結果の更新をトリガーしないことで、メインストリームに関連付けられたディメンションデータは変化しません。Flink は非常に豊富な Temporal Join 機能をサポートしており、関連ルックアップ DB、関連変更ログ、関連 Hive テーブルを含みます。従来、よく知られたディメンションテーブル結合は一般的にクエリ可能なデータベースに関連付けられていました。ディメンションデータがデータベース内にあるからです。しかし実際には、ディメンションデータは binlog 形式や、定期的に Hive に同期されて Hive パーティションテーブル形式になるなど、さまざまな物理形態を持つ可能性があります。Flink 1.12 では、これら 2 つの新しいディメンションテーブル形式の関連付けがサポートされています。
Temporal Join Lookup DB は最も一般的なディメンションテーブル結合方法です。たとえば、ユーザークリックストリームとユーザープロファイルの関連付けケースでは、ユーザークリックストリームは Kafka にあり、ユーザーのリアルタイムプロファイルは HBase データベースに保存されており、各クリックイベントごとに HBase にクエリしてユーザーのリアルタイムプロファイルと関連付け、データワイドニングを完了します。Temporal Join Lookup DB の特徴は、ディメンションテーブルの更新が結果の更新をトリガーせず、ディメンションデータはデータベースに保存されており、リアルタイム要件が高いシナリオに適しています。使用する際は、一般的に Async IO とメモリキャッシュを有効にしてクエリ効率を向上させます。
Temporal Join Changelog を紹介する前に、もう 1 つの Lookup DB の例を見てみましょう。ライブ配信インタラクションデータとライブルームディメンションの関連付けケースです。このケースでは、ライブ配信インタラクションデータ(いいね、コメントなど)は Kafka に保存され、ライブルームのリアルタイムディメンションデータ(アンカー、ライブルームのタイトルなど)は MySQL に保存されています。ライブ配信インタラクションデータの量は非常に多く、アクセスを高速化するため、一般的なソリューションはキャッシュを追加することです。たとえば、CDC を通じてライブルームのディメンションデータを同期し、Redis に保存してからディメンションテーブル関連付けを行います。このソリューションの課題は、ライブ配信の業務データが特殊であることです。ライブルームの作成とライブ配信のインタラクションデータは基本的に同時に生成されるため、インタラクションデータは早く Kafka に到着して Flink に消費される可能性がありますが、ライブルームの作成メッセージは Canal、Kafka、Redis を経由するリンクが比較的長く、データ遅延が比較的大きいため、インタラクションデータが Redis をクエリする時点でライブルームデータがまだ同期されていない可能性があり、その結果ライブルームデータとの関連付けができず、下流の統計分析に偏差が生じる可能性があります。
このようなシナリオに対応するため、Flink 1.12 では Temporal Join Changelog をサポートしており、Flink ステート内の更新ログからディメンションテーブルを具体化することでディメンションテーブル関連付けを実現しています。先ほどのシナリオにはより簡潔なソリューションがあります。Flink CDC コネクタを通じてライブルームデータベーステーブルの更新ログを Kafka に同期できます。右側の SQL に注目してください。upsert-kafka コネクタを使用して MySQL binlog を Kafka に書き込みます。つまり、ライブルームの変更データを Kafka に upsert ストリームとして保存します。そして、インタラクションデータをライブルームの upsert ストリームとテンポラル結合し、ライブ配信データのワイドニング機能を実現します。
ここで注意すべきは、FOR SYSTEM_TIME AS OF は処理時間に関連するのではなく、左ストリームのイベント時間に関連するということです。その意味は、このイベント時点でのライブルームデータを関連付けることです。同時に、ライブルームの upsert ストリームにウォーターマークを定義しているため、Temporal Join Changelog は実行時にウォーターマークの待機とアライメントを行い、結果の正確なバージョンとの関連付けを確保し、以前のソリューションでの関連付けできない問題を解決します。
Temporal Join Changelog のプロセスを詳しく説明します。左ストリームはインタラクティブストリームデータで、右ストリームはライブルームの更新ログです。ライブルームの更新ログは右ストリームのディメンションテーブルステートに具体化されます。このステートはマルチバージョンデータベースのミラーのようなものです。メインストリームのインタラクションデータは左ストリームのステートに一時的にキャッシュされます。ウォーターマークがアライメントされた後、ディメンションテーブルのステート内のデータを確認します。たとえば、インタラクティブストリームとライブストリームの両方のウォーターマークが 10:01 に達した場合、インタラクティブストリームの 10:01 のコメントデータがディメンションテーブルステートからクエリされ、room 103 と関連付けられます。10:05 にコメントデータが到着しても、すぐに出力されません。そうでなければ、その時点のライブルーム情報と関連付けられてしまいます。左右のストリームのウォーターマークが 10:05 に達するまで待機してから、ディメンションテーブルステート内のデータと関連付けて出力します。この時点で正確な 104 のライブルーム情報と関連付けることができます。
まとめると、Temporal Join Changelog の特徴は高いリアルタイム性能です。イベント時間に基づいてバージョンと関連付けるため、正確なバージョン情報と関連付けることができ、ディメンションテーブルはウォーターマークのアライメントを待機するため、ユーザーはウォーターマークを通じてディメンションテーブルのタイミングを制御できます。Temporal Join Changelog のディメンションテーブルデータはテンポラル結合ノードのステートに保存されており、読み取りはローカルの Redis と同様に非常に効率的で、ユーザーは追加の Redis コンポーネントをメンテナンスする必要がなくなります。
データウェアハウスシナリオでは Hive が広く使用されており、Flink と Hive の統合は非常に友好的です。現在、Hive パーティションテーブルと非パーティションテーブルの Temporal Join をサポートしています。Hive パーティションテーブルを関連付ける典型的なケースを見てみましょう。注文フローと店舗データの関連付けです。店舗データは一般的にゆっくり変化するため、業務側は一般的にフル店舗テーブルを日次で Hive パーティションに同期し、毎日新しいパーティションが生成され、各パーティションにはその日のフル店舗データが含まれます。
この種の Hive データを関連付けるには、Hive パーティションテーブルを作成する際に右側の 2 つの赤い丸のパラメーターを指定するだけで、Hive の最新パーティションを自動的に関連付ける機能を実現できます。partition.include = latest は Hive の最新パーティションのみを読み取ることを意味し、partition-name は最新パーティションを選択する際にパーティション名でアルファベット順にソートすることを示します。10 月 3 日の時点で、Hive に 10 月 2 日の新しいパーティションが生成されています。Flink は新しいパーティションを検出すると、10 月 2 日のデータをキャッシュに再読み込みし、10 月 1 日のデータを置き換えて最新のディメンションテーブルとします。後続の注文フローデータは、キャッシュ内の 10 月 2 日パーティションのデータと関連付けられます。Temporal Join Hive の特徴は、最新の Hive パーティションを自動的に関連付けられることで、ディメンションテーブルの更新が遅い業務シナリオや高スループットのシナリオに適しています。
先ほど紹介したデータワイドニングに使用されるいくつかの Join をまとめます。
Regular Join の適時性は非常に高く、スループットは平均的です。ステートがすべての到着データを保持するためで、デュアルストリーム結合シナリオに適しています。
Interval Join の適時性は非常に良く、スループットはより良好です。ステートが時間間隔内のデータのみを保持するためで、ビジネス時間間隔があるデュアルストリーム結合シナリオに適しています。
Temporal Join Lookup DB の適時性はより良好で、スループットは低めです。各データが外部システムへのクエリを必要とし、IO オーバーヘッドが発生するためで、ディメンションテーブルがデータベース内にあるシナリオに適しています。
Temporal Join Changelog の適時性は良好で、スループットも良好です。IO オーバーヘッドがないためで、ディメンションテーブルの待機が必要なシナリオや正確なバージョンとの結合が必要なシナリオに適しています。
Temporal Join Hive の適時性は平均的ですが、スループットは非常に良好です。ディメンションテーブルのデータがキャッシュに保存されているためで、ディメンションテーブルの更新が遅いシナリオや高スループットが必要なシナリオに適しています。
まとめ
最後に、Flink の ETL データ統合における機能をまとめましょう。これは現在の Flink データ統合の機能マトリックスです。既存の外部ストレージシステムをリレーショナルデータベース、KV データベース、メッセージキュー、データレイク、データウェアハウスの 5 つに分類しています。図からわかるように、Flink は非常に豊富なエコシステムを持ち、各ストレージエンジンに対して非常に強力な統合機能を持っています。
横軸では、6 つの機能を定義しています。3 つのデータアクセス機能、すなわちフルデータ読み取り、ストリーミング読み取り、CDC ストリーミング読み取り。1 つのデータワイドニング機能、すなわちディメンション関連付け。そして 2 つのストレージ/レイク取り込み機能、すなわちストリーム書き込みと CDC 書き込みです。
Flink の各システムに対するデータアクセス機能、ディメンションワイドニング機能、そしてストレージ/レイク取り込み機能が既に非常に完全であることがわかります。CDC ストリーミング読み取りについては、Flink は既に主流データベースと Kafka メッセージキューをサポートしています。データレイク方面では、Iceberg に対する Flink のストリーミング読み取りと CDC 書き込み機能も次の Iceberg バージョンでリリースされます。この機能マトリックスから、Flink のデータ統合機能が非常に包括的であることがわかります。
Related Articles
-
A detailed explanation of Hadoop core architecture HDFS
Knowledge Base Team
-
What Does IOT Mean
Knowledge Base Team
-
6 Optional Technologies for Data Storage
Knowledge Base Team
-
What Is Blockchain Technology
Knowledge Base Team
Explore More Special Offers
-
Short Message Service(SMS) & Mail Service
50,000 email package starts as low as USD 1.99, 120 short messages start at only USD 1.00
