データフロー プログラミング モデル

抽象化レベル

Flink はストリーミング/バッチ アプリケーションを開発するための異なる抽象化レベルを提供します。

抽象化のプログラミング レベル

  • 一番低レベルの抽象化は単にステートフル ストリーミングを提供します。それはProcess 関数を使ってデータストリーム APIに組み込まれています。ユーザは自由に1つ以上のストリームからイベントを処理することができ、一貫性のある耐障害性状態が使われます。更に、ユーザはイベントタイムと処理タイムのコールバックを登録することができ、プログラムは洗練された計算を理解することができます。

  • In practice, most applications would not need the above described low level abstraction, but would instead program against the Core APIs like the DataStream API (bounded/unbounded streams) and the DataSet API (bounded data sets). These fluent APIs offer the common building blocks for data processing, like various forms of user-specified transformations, joins, aggregations, windows, state, etc. これらのAPI内で処理されるデータ型はそれぞれのプログラム言語内のクラスとして表されます。

    低レベル プロセス関数データストリーム APIを統合し、特定のオペレーションのみのための低レベル抽出をすることができます。The DataSet API offers additional primitives on bounded data sets, like loops/iterations.

  • Table APItablesを中心とした宣言型のDSLで、(ストリームを表現する場合は)動的に変更するテーブルかも知れません。The Table API follows the (extended) relational model: Tables have a schema attached (similar to tables in relational databases) and the API offers comparable operations, such as select, project, join, group-by, aggregate, etc. Table API programs declaratively define what logical operation should be done rather than specifying exactly how the code for the operation looks. Table API はユーザ定義関数の様々な型によって拡張可能で、Core APIsよりは表現力が劣りますが、(各コードが少なく)もっと簡単に使えます。更に、Table API プログラムは実行の前に最適化ルールを適用するオプティマイザを通すこともできます。

    プログラムがTable APIDataStreamおよび DataSet API間で混ぜ合わせることができ、テーブルとDataStream/DataSet間をシームレスに変換することができます。

  • Flinkによって提供される高レベルの抽象化はSQLです。この抽象化はセマンティクスと表現の両方においてTable APIに似ていますが、プログラムをSQLクエリ表現として表します。SQL 抽象化は Table API と密接にやり取りをし、SQLクエリはTable APIの中で定義されたテーブル上で実行することができます。

プログラムとデータフロー

Flinkプログラムの基本的な構築ブロックはストリーム変換です。(Note that the DataSets used in Flink’s DataSet API are also streams internally – more about that later.) Conceptually a stream is a (potentially never-ending) flow of data records, and a transformation is an operation that takes one or more streams as input, and produces one or more output streams as a result.

実行された場合、Flinkプログラムはストリームと変形オペレータから成るストリーミング データフローにマップされます。各データフローは1つ以上のソース で始まり、1つ以上のシンクに終着します。データフローは任意の有効非循環グラフ (DAGs)に似ています。Although special forms of cycles are permitted via iteration constructs, for the most part we will gloss over this for simplicity.

データストリームプログラムとそのデータフロー。

しばしば、プログラム内の変換とデータフロー内のオペレータの間には1対1の対応があります。しかし、時には1つの変換が複数の変換オペレータからできているかも知れません。

上に戻る

並行データフロー

Flinkでのプログラムは本質的に並行および分散です。実行中はストリーム は1つ以上のストリーム パーティションを持ち、それぞれのオペレータは1つのストリームパーティションあるいはオペレーターのサブタスクを持ちます。オペレータのサブタスクはお互いに独立していて、異なるスレッドあるいは異なるマシーンやコンテナ上でさえも実行されます。

オペレータサブタスクの数は特定のオペレータの並行度 です。ストリームの並行度は常にその生成オペレータの並行度です。同じプログラムの異なるオペレータは異なるレベルの並行度を持つかも知れません。

並行データフロー

ストリームはone-to-one (あるいは forwarding) パターン、あるいは redistributing パターンの中での二つのオペレータ間でデータを転送することができます。

  • One-to-one ストリーム (例えば、上の図でのSourcemap() 間のオペレータ) は要素のパーティショニングとオーダリングを保持します。このことはmap() オペレータのsubtask[1]がSourceオペレータのsubtask[1]によって生成された時と同じ順番の同じ要素を見るだろうことを意味します。

  • Redistributing ストリーム (map()keyBy/window間、およびkeyBy/windowsink間) はストリームのパーティショニングを変更します。各 オペレータのサブタスクは、選択された変換に依存して、データを異なるターゲットのサブタスクに送信します。例として keyBy() (キーのハッシュ化による再パーティション), broadcast() あるいは rebalance() (ランダム再分配)があります。redistributing 交換の場合、送信および受信タスクのそれぞれのペアについての要素間の順番のみが維持されます(たとえば、map()のサブタスク[1]とkeyBy/windowのサブタスク[2])。So in this example, the ordering within each key is preserved, but the parallelism does introduce non-determinism regarding the order in which the aggregated results for different keys arrive at the sink.

上に戻る

ウィンドウ

集約イベント(例えば、カウント、合計)は、バッチ処理に比べてストリーム上では異なる働きをします。例えば、ストリームは一般的に無限なため、最初にストリーム内で全ての要素を数えることは不可能で、したがってカウントを返します。代わりに、ストリーム上の集約(カウント、合計など)は“count over the last 5 minutes” あるいは“sum of the last 100 elements”のようなwindowsによってスコープされます。

ウィンドウはtime driven (例: 各30秒毎) あるいは data driven (例: 各100要素毎)があり得ます。One typically distinguishes different types of windows, such as tumbling windows (no overlap), sliding windows (with overlap), and session windows (punctuated by a gap of inactivity).

時間とカウント ウィンドウ

このブログの投稿の中でもっと多くのウィンドウの例を見つけることができます。

上に戻る

時間

ストリーミングプログラムの中で(例えばウィンドウを定義するために)時間を参照する場合、時間の異なる表記を指示することができます。

  • イベントタイム は、イベントが生成された時間です。通常はイベントのタイムスタンプによって表現されます。例えば、センサーの生成あるいは生成サービスによってアタッチされたもの。Flinkはtimestamp assignersを使ってイベントのタイムスタンプにアクセスします。

  • Ingestion time はイベントがソースオペレータにおいてFlinkデータフローに入った時間です。

  • Processing Time は時間ベースのオペレーションを実施する各オペレータでのローカルの時間です。

イベントタイム、取り込み時間、処理時間

時間を扱う方法についての詳細はイベントタイム ドキュメントにあります。

上に戻る

ステートフル オペレーション

データフロー内の多くのオペレーションは単純に1つの個々のそのときのイベントを見ますが(例えば、イベントパーサー)、いくつかのオペレーションは多数のイベントを横断して情報を記録します(例えば、ウィンドウ オペレーション)。これらのオペレーションはステートフルと呼ばれます。

ステートフルのオペレーションは組み込みのキー/値ストアとみなすことができるものの中で維持されます。状態はステートフル オペレータによって読み込まれたストリームと一緒に厳密にパーティション化され分散されます。したがって、キー/値 状態へのアクセスはkeyBy() 関数の後のkeyed streams上でのみ可能で、現在のイベントキーの値にのみ限定されます。ストリームと状態のキーの割り当ては、トランザクションのオーバーヘッド無しにすべての状態の更新がローカルオペレーションであることを確実にします。この割り当てはFlinkが状態を再分配しストリームのパーティショニングを透過的に調整することも可能にします。

状態とパーティショニング

上に戻る

耐障害性のためのチェックポイント

Flinkはストリーム再生チェックポイントを使って耐障害性を実装します。チェックポイントは各オペレータに対応する状態と一緒に各入力ストリーム内の特定の場所に関係します。ストリーミング データフローは、オペレータの状態の回復およびチェックポイントの場所からのイベントの再生により、一貫性を維持(確実に一回の処理セマンティクス)しながらチェックポイントから再開することができます。

The checkpoint interval is a means of trading off the overhead of fault tolerance during execution with the recovery time (the number of events that need to be replayed).

チェックポイント耐障害性の詳細は耐障害性のドキュメントにあります。

上に戻る

ストリーミングのバッチ

Flink はバッチプログラムをストリーミングプログラムの特別な場合として実行します。この時ストリームは制限(要素の数が有限)されます。DataSet は内部的にデータのストリームとして扱われます。上記の概念はしたがって少しの例外を除いてストリーミングプログラムに適用される方法と同じようにバッチプログラムに適用されます:

  • データセットAPI中のプログラムはチェックポイントを使いません。回復は完全にストリームを再現することで起こります。入力が制限されているため、それらが可能です。このことは回復のためのコストを押し上げますが、チェックポイントを回避するため一般的な処理を手軽にします。

  • データセットAPI内のステートフル オペレーションは、キー/値 インデックスでは無く、単純化されたインメモリ/アウトオブコアのデータ構造を使用します。

  • データセットAPIは特別な同期(スーパーステップ ベース)のイテレーションを導入します。これは制限されたストリーム上でのみ可能です。詳細はイテレーションのドキュメントを調べてください。

上に戻る

次のステップ

Flinkの 分散ランタイムの基本的な概念に続きます。

TOP
inserted by FC2 system