Entering Apache Flink

1. Apache Flink とは

Apache Flink は、オープンソースのストリームベースのステートフルコンピューティングフレームワークです。分散方式で実行され、低レイテンシと高スループットという優れた性能を備え、ステートフルで複雑な計算ロジックを扱うシナリオに優れています。

1. Flink の起源

Apache Flink は、Apache オープンソースソフトウェア財団のトップレベルプロジェクトです。Spark が UC Berkeley の研究室から生まれたように、多くの Apache トップレベルプロジェクトと同様に、Flink も非常に有名な大学であるベルリン工科大学の研究室から生まれました。

プロジェクトの元々の名前は Stratosphere で、ビッグデータ処理をより簡潔に見せることを目標としていました。プロジェクトの初期コードコントリビューターの多くは現在も Apache のプロジェクト管理委員会で活動しており、コミュニティへの貢献を続けています。

Stratosphere プロジェクトは 2010 年に開始されました。Git のコミットログから、最初のコードが 2010 年 12 月 15 日に書かれたことが確認できます。

2014 年 5 月、Stratosphere プロジェクトは Apache ソフトウェア財団に寄贈され、インキュベータープロジェクトとして孵化し、名称を Flink に変更しました。

2. Flink の発展

Flink プロジェクトは非常に活発です。2014 年 8 月 27 日に、インキュベーター初のバージョン v0.6-incubating がリリースされました。

Flink プロジェクトは多くのコントリビューターを集め、活動面でも非常に活発であったため、2014 年 12 月に Apache トップレベルプロジェクトに昇格しました。
トップレベルプロジェクトに昇格してから 1 か月後、初のリリースバージョン Flink 0.8.0 が公開されました。その後、Flink は約 4 か月ごとのリリースサイクルを維持しながら、現在まで発展を続けています。

3. Flink の現状 — Apache コミュニティで最も活発なプロジェクト

現在、Flink は Apache コミュニティで最も活発なビッグデータプロジェクトとなっています。ユーザーおよび開発者メーリングリストの活発度は、2020 年 Apache 年次レポートで第 1 位にランクされました。

前述の図に示すように、非常に活発な Spark プロジェクトと比較すると、ユーザーメーリングリストの活発度では Flink が Spark を上回っています。また、開発者のコードコミット数や GitHub へのユーザーアクセス数においても、Flink は Apache プロジェクト全体で第 2 位、ビッグデータプロジェクトでは第 1 位にランクされています。

2019 年 4 月以降、Flink コミュニティは 5 つのバージョンをリリースし、各バージョンごとにコミット数とコントリビューター数が増加しています。

2. Apache Flink を学ぶ理由

1. ビッグデータ処理のリアルタイム化の傾向

ネットワークの急速な発展に伴い、ビッグデータ処理には非常に明確なリアルタイム化の傾向が現れています。

前述の図に示すように、日常生活における代表的なシナリオをいくつか挙げました。たとえば、春節聯歓晚会のリアルタイム大画面や、ダブル 11 ショッピングフェスティバルのリアルタイム売上統計とメディア報道などがあります。

シティブレインは交通状況をリアルタイムに監視でき、銀行はリスク管理をリアルタイムに実行できます。タオバオや Tmall などのアプリケーションを開くと、ユーザーの行動習慣に応じてリアルタイムにパーソナライズされたレコメンデーションが表示されます。これらの事例から、ビッグデータ処理に明確なリアルタイム化の傾向が見て取れます。

2. Flink は国内外のリアルタイムコンピューティングのデファクトスタンダードに

リアルタイム化の大潮流の中で、Flink は国内外のリアルタイムコンピューティングのデファクトスタンダードとなっています。

前述の図に示すように、現在、国内外の多くの企業が Flink を使用しています。

3. ストリームコンピューティングエンジンの進化

ストリームコンピューティングエンジンは複数の世代を経て進化してきました。第 1 世代のストリームコンピューティングエンジンである Apache Storm は、純粋なストリーム設計で非常に低いレイテンシを実現しましたが、メッセージの重複処理を避けられず、データの正確性に問題があるという課題もありました。

Spark Streaming は第 2 世代のストリームコンピューティングエンジンで、ストリームコンピューティングのセマンティクスの正確性の問題を解決しました。ただし、その設計思想はバッチベースであり、レイテンシが比較的高く、10 秒レベルの遅延しか実現できず、エンドツーエンドで 1 秒未満の遅延を達成できないという課題がありました。

Flink は第 3 世代、すなわち最新のストリームコンピューティングエンジンです。低レイテンシを保証するだけでなく、メッセージの一貫性のあるセマンティクスも保証でき、組み込みの状態管理によりアプリケーションの複雑さを大幅に削減できます。

3. Apache Flink の代表的なアプリケーションシナリオ

1. イベント駆動型アプリケーション

最初のアプリケーションシナリオは、イベント駆動型アプリケーションです。

イベント駆動とは、あるイベントが後続の 1 つまたは複数のイベントをトリガーし、その一連のイベントに基づいて何らかの処理を行う仕組みです。

ソーシャルシナリオでは、Weibo を例に取ると、ユーザーが他のユーザーをフォローすると、フォローされたユーザーのファン数が変化します。その後、フォローされたユーザーが Weibo に投稿すると、フォローしているファンにメッセージ通知が届きます。これが典型的なイベント駆動です。

また、オンラインショッピングの文脈では、ユーザーが商品にレビューを投稿すると、それらのレビューは一方ではショップの星評価に影響し、他方では悪意のある低評価の検出が行われます。さらに、ユーザーは情報フィードをクリックすることで商品の配送状況などを確認でき、これらが一連の後続イベントをトリガーする可能性があります。

金融不正対策のシナリオでは、詐欺師が SMS で詐欺を働き、ATM で他人の現金を引き出すケースがあります。このシナリオでは、カメラで撮影した後、迅速に識別して対応し、犯罪行為に対して適切な処置を行います。これも典型的なイベント駆動型アプリケーションです。

まとめると、イベント駆動型アプリケーションとは、イベントストリーム内のイベントに基づいて計算をトリガーし、状態を更新し、または外部システムへの操作を実行するステートフルアプリケーションの一種です。イベント駆動型アプリケーションは、リアルタイムレコメンデーション、金融不正対策、リアルタイムルール警告など、リアルタイムコンピューティングサービスでよく見られます。

2. データ分析型アプリケーション

第 2 の代表的なアプリケーションシナリオは、データ分析アプリケーションです。たとえば、ダブル 11 の売上高のリアルタイム集計や、PV・UV 統計などがあります。

前述の図に示すように、世界各地での Apache オープンソースソフトウェアのダウンロード状況を示したもので、実際には情報の集計結果です。

大規模マーケティングダッシュボードも含まれ、売上の変動や、マーケティング戦略の効果を四半期比や前年比で比較する分析などがあります。これらはいずれも大量の情報のリアルタイム分析と集約を伴います。これらは Flink の非常に典型的な使用シナリオです。

前述の図に示すように、ダブル 11 を例に取ると、2020 年の Tmall ダブル 11 ショッピングフェスティバルにおいて、Alibaba の Flink ベースのリアルタイムコンピューティングプラットフォームは毎秒 40 億メッセージを処理し、データ量は 7 TB に達し、注文作成数は毎秒 58 万件に達し、計算規模は 150 万コアを超えました。

これらのアプリケーションシナリオは規模が大きく、リアルタイム性能に対する要求が非常に高いことがわかります。これは Apache Flink が非常に得意とするシナリオでもあります。

3. データパイプラインアプリケーション (ETL)

Apache Flink が得意とする第 3 のシナリオは、データパイプラインアプリケーション、すなわち ETL です。

ETL (Extract-Transform-Load) は、データソースからデータを抽出/変換/読み込みし、送信先へ転送するプロセスです。

従来の ETL はオフライン処理を使用し、数時間単位または日次の ETL を行うことが一般的でした。

しかし、ビッグデータ処理のリアルタイム化の傾向に伴い、リアルタイムデータウェアハウスへの需要も生じています。リアルタイムデータウェアハウスでは、分単位または秒単位でデータを更新し、タイムリーにクエリを実行してリアルタイム指標を確認し、さらなるリアルタイム判断と分析を行えることが求められます。

これらのシナリオで、Flink はリアルタイム要件を最大限に満たすことができます。

その主な理由は以下の通りです。まず、Flink は非常に豊富なコネクタを備え、複数のデータソースとデータシンクに対応し、すべての主要ストレージシステムをカバーしています。さらに、非常に汎用的な組み込み集約関数を備えており、ETL プログラムの記述を容易にしています。そのため、ETL 型アプリケーションも非常に適したアプリケーションシナリオです。

4. Apache Flink の基本概念

1. Flink の核心概念

Flink には 4 つの主要な概念があります。Event Streams (イベントストリーム)、State (状態)、(Event) Time (イベント時間)、Snapshots (スナップショット) です。

1.1 Event Streams

イベントストリームは、リアルタイムデータの場合も履歴データの場合もあります。Flink はストリームベースですが、ストリームだけでなくバッチも処理できます。ストリームとバッチの入力はいずれもイベントストリームです。違いはリアルタイムかバッチかにあります。

1.2 State

Flink はステートフルな計算を得意とします。通常、複雑なビジネスロジックはステートフルです。単一のイベントを処理するだけでなく、一連の履歴情報を記録し、その上で計算や判断を行う必要があります。

1.3 (Event) Time

主に扱う問題は、データの順序が乱れた場合に一貫性をどのように保証するかです。

1.4 Snapshots

データスナップショット、障害復旧、データ整合性の保証、ジョブのアップグレードと移行などを実現します。

2. Flink のジョブ定義と論理トポロジー

次に、Flink のジョブ定義と論理トポロジーを詳しく見ていきましょう。


上記に示すように、コードはシンプルな Flink ジョブの定義です。まず Kafka Source を定義し、データソースが Kafka メッセージキューから来ることを指定します。次に、Kafka 内の各データを解析します。解析完了後、配信されたデータはイベントの ID で KeyBy され、各グループが 10 秒ごとにウィンドウ集計を実行します。集計処理後、メッセージはカスタム Sink に書き込まれます。以上がシンプルなジョブ定義であり、直感的な論理トポロジーにマッピングされます。

論理トポロジーには 4 つのオペレーター (操作ユニット) があり、それぞれ Source、Map、KeyBy/Window/Apply、Sink です。この論理トポロジーを Streaming Dataflow と呼びます。

3. Flink の物理トポロジー

論理トポロジーは物理トポロジーに対応し、各オペレーターは負荷分散と処理高速化のために並列処理が可能です。

ビッグデータ処理は基本的に分散処理であり、各オペレーターは異なる並列度を持つことができます。KeyBy キーワードがある場合、データはキーに基づいてグルーピングされるため、KeyBy の前のオペレーターの処理後に、データはシャッフルされて次のオペレーターに送信されます。上記の図は、この例に対応する物理トポロジーを示しています。

4. Flink の状態管理とスナップショット

次に、Flink の状態管理とスナップショットについて見ていきましょう。

Window の集約ロジックを実行する際、集約関数は 10 秒ごとにデータを処理します。この 10 秒間のデータは一時的に保存し、タイムウィンドウが発火されたタイミングで処理を行う必要があります。これらの状態データは組み込みストレージの形式でローカルに保存されます。ここでの組み込みストレージは、プロセスのメモリ内にも、RocksDB に似た永続化 KV ストレージにも配置できます。両者の主な違いは処理速度と容量です。

さらに、これらのステートフルオペレーターの各並列インスタンスにはそれぞれローカルストレージがあるため、状態データはオペレーターの並列度に応じて動的にスケールアップ・スケールダウンできます。これにより、並列度を上げることで大量のデータを処理できます。

一方、ジョブはさまざまな状況で失敗する可能性があります。失敗後の再実行時にデータの一貫性をどのように保証すればよいでしょうか。

Flink は Chandy-Lamport アルゴリズムに基づき、各分散ノードの状態を分散ファイルシステムにチェックポイントとして保存します。そのプロセスは概ね以下の通りです。まず、データソースから Checkpoint Barrier を注入します。これは特別なメッセージです。

その後、通常のイベントと同様にデータフローに乗って流れていきます。Barrier がオペレーターに到達すると、オペレーターは自身の現在のローカル状態のスナップショットを取得します。Barrier が Sink まで到達した時点で、すべての状態が完全に保存され、グローバルスナップショットが形成されます。

これにより、ジョブ失敗時に、リモートファイルシステムに保存されたチェックポイントからロールバックできます。まず Source をチェックポイントに記録されたオフセットまでロールバックし、次にステートフルノードの現在の状態を対応する時点までロールバックして再計算を実行します。これにより、ゼロから計算を再開する必要がなく、データセマンティクスの一貫性も保証されます。

5. Flink の時間定義
image.png

Flink のもう 1 つの重要な定義は Event Time (イベント時間) です。

Flink には 3 つの異なる時間があります。Event Time はイベントが発生した時刻を指します。Ingestion Time はイベントが Flink データソースに到着した時刻、すなわち Flink 処理フレームワークに入った時刻を指します。Processing Time は処理時間で、イベントがオペレーターに到着した時刻を指します。これらの違いは何でしょうか。

現実世界では、イベントの発生からシステムへの書き込みまでの間隔が比較的長くなることがあります。たとえば、地下鉄内で電波が弱い場合に Weibo でリツイート、コメント、いいねなどの操作を行っても、ネットワークの制約により、これらの操作は地下鉄を出るまで完了できないことがあります。そのため、先に発生したイベントが遅れてシステムに到達する可能性があります。しかし、Event Time はイベントが発生した時刻をより正確に反映するため、多くのシナリオでは Event Time をイベント発生時刻として使用します。

ただしこの場合、遅延によりウィンドウへの到着を長く待つ必要があるため、エンドツーエンド遅延が大きくなる可能性があります。
データの順序が乱れる問題への対応も必要です。Processing Time をイベント時間として使用すると、処理は速くレイテンシは低くなりますが、イベントの実際の発生時刻を反映できません。そのため、実際のアプリケーション開発では、アプリケーションの特性に応じて適切なトレードオフを行う必要があります。

6. Flink API

Flink の API は 4 つのレベルに分けられます。最下層の API はカスタマイズ可能な Process Function で、時間や状態などの最も基本的な要素を細かく扱い、独自のロジックを実装します。

その上層には DataStream API があり、ストリーム処理とバッチ処理を実行できます。もう一方では論理式でもあり、Flink には Map、keyBy、timeWindow、sum などの豊富な組み込み関数が用意されており、プログラムの記述を容易にしています。

最上層の API は Table API と Stream SQL です。これは非常に高度な表現で、簡潔にロジックを記述できます。具体例で説明しましょう。

6.1 Process Function

processElement では、イベントと状態に対してカスタムロジックを実行できます。さらに、タイマーを登録して、タイマーが発火したときや指定時刻に到達したときに行う処理をカスタマイズできます。これは非常に細かいレベルの低レイヤー制御です。

6.2 DataStream API

DataStream API はジョブの定義です。Map、keyBy、timeWindow、sum などの多くの組み込み関数があることが確認できます。また、MyAggregationFunction のような先ほどカスタマイズした ProcessFunction もあります。

6.3 Table API & Stream SQL

同じロジックも、Table API と Stream SQL で記述するほうがより直感的です。データアナリストは低レイヤーの詳細を理解する必要がなく、宣言型言語でロジックを記述できます。Table API と Stream SQL の内容はレッスン 5 で詳しく紹介します。

7. Flink ランタイムアーキテクチャ

Flink のランタイムアーキテクチャには主に 3 つの役割があります。

1 つ目はクライアントです。クライアントはアプリケーションプログラムを送信します。SQL プログラムの場合は、SQL オプティマイザーによる最適化も行い、対応する JobGraph を生成します。クライアントは JobGraph を JobManager に送信します。JobManager はジョブ全体のマスター制御ノードとみなせます。

JobManager は一連の TaskManager をワークノードとして起動し、ワークノードはジョブトポロジーに従って直列に接続され、対応する計算ロジックの処理を行います。JobManager は主に制御フローの処理を担当します。

8. Flink の物理デプロイ

最後に、Flink をデプロイできる環境を見ていきましょう。

まず、YARN、Mesos、Standalone クラスターにジョブを手動で送信できます。さらに、K8s クラウドネイティブ環境にもミラーリングを通じて送信できます。

現在、Flink はさまざまな物理環境にデプロイできます。

Related Articles

Explore More Special Offers

  1. 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

phone お問い合わせ
Hi, I'm Alibaba Cloud AI Assistant!
I can help with questions and solutions.