もし前の記事(Streaming 101)を読んでいないなら、まず読むことをお勧めする。 以後の内容を論じる上での前提事項を説明しているし、そこで述べられた内容について相応に理解していることを前提として、本記事は書かれているから。
また、本記事の一部ではアニメーションを使用しているため、もし印刷して読もうと考えている場合にはそれについて留意いただきたい。
でははじめよう。 簡単に要約すると、前回私は3つの内容について焦点を当てていた。 1つ目は「技術定義」。"ストリーム処理"についてどういうものを意図するか、明確に定義した。 2つ目は「バッチ VS ストリーム」。2つのシステムの比較を行い、「正確性」と「時間について推測可能なツールであること」の2要素が揃えば、ストリーム処理システムがバッチ処理システムの純粋な上位互換になり得ることを説明した。 3つ目は「データ処理パターン」。バッチ処理システム、ストリーム処理システムを用いて無限のデータ、有限のデータを処理する際の共通的なパターンについて説明した。
この記事においては、前回説明したデータ処理パターンについてより詳細かつ明確に踏み込んだ上で、更にその先に焦点を当てたい。 この記事の骨子は下記の2つの章からなる。
- Streaming 101 振り返り
Streaming 101で紹介したコンセプトについて振り返り、実例について概要を示す。
- Streaming 102
Streaming 101の内容を受け、無限のデータを扱う上で重要な要素となる追加の概念について詳細を動作例を基に説明する。
この記事を一通り読むことで、頑強なout-of-orderなデータ処理に必要となる主要な原則や概念の基本についておさえることができる。 この概念をおさえたストリーム処理は伝統的なバッチ処理を超えるツールとなり得る。
具体的にどのように構成をすればいいかを示すために、Google Cloud DataflowのSDKのコードと、概念を示すアニメーションを用いる。 SparkやStormといった他のシステムに通じている方もいる中でGoogle Cloud Dataflowを用いる理由は、概念を示すために十分な表現力をもつシステムが現状存在しないため。 ただ、徐々に他のプロダクトもこの方向に向かいつつあるのはいい傾向だと感じる。 さらに、GoogleからはApache Beamというプロダクトをdata Artisans、Cloudera、Talendといった会社と共に公開し、これを用いることでよりオープンなコミュニティとエコシステムの上でこのような頑強なout-of-orderなデータ処理が可能になるだろう。
でははじめよう。
Streaming 101で、はじめにいくつかの用語の定義を明確にしている。 有限のデータと無限のデータの違いについて明確にしている。 有限のデータソースは有限のサイズのデータを保持し、しばしば「バッチ」データとして扱われる。 無限のデータソースは無限のデータを有しており、しばしば「ストリーム」データとして扱われる。 まずはこういった形で有限だからバッチ、無限だからストリームという形で紐づけるのはミスリーディングになるので、そうではないことを示している。
その後、バッチ処理エンジンとストリーム処理エンジンの違いについても述べた。 バッチ処理エンジンは有限のサイズのデータのみを念頭に置いた設計になっており、ストリーム処理エンジンは有限のデータに加えて無限のデータに対しても考慮した設計となっている。 ここではバッチ処理、ストリーム処理は実際にそれを実行する実行エンジンにのみ紐づけて考えてほしい旨を記述している。
この定義の後、無限のデータを扱う上で2つの基本かつ重要な概念について説明している。 1つ目として、Event Time(いつそのイベントが発生したかを示す時刻)とProcessing Time(いつ対象のデータを処理したかを示す時刻)の区別がある。 もし実際にイベントが発生した時刻を基にした厳密な解析をしたい場合、Event Timeに基づいて処理を行う必要があり、Processing Timeを用いては解析に支障が出る、
2つ目として、Windowing(データを一時的な区切りを用いて分割すること)について説明した。 これは無限に発生し続け、終了しないデータソースからのデータを処理するにあたり、共通的なアプローチのうちの一つ。 基本的な例として、Windowingには固定長WindowとSlidingWindowがあることを示し、より複雑な形式のWindowingとして、Session(Windowサイズはデータによって決定し、アクセスがない時間が一定時間に達したらWindowが区切られる方式)と用途について示した。
これらの2つの考えに加えて、下記の3つについて掘り下げる。
WatermarkはEvent Timeベースでどこまで処理が完了したかを示す概念。 WatermarkがXの値を取った場合、「Event TimeがXより小さいデータは全て観測されている。」ことを示す。 つまりはWatermarkは無限のデータを観測している状態において、どこまで進んだかを示すメトリクスとして動作する。
Triggerはウィンドウ出力をどのタイミングで実体化するかをいくつかの外部の状況を基準に宣言するためのメカニズム。 Triggerはいつ出力値が実体化するべきかについて柔軟性を実現する。 また、Trigger機構によってウィンドウ出力がデータが更新される毎に複数回出力するということも可能になる。 これによって、上流からのデータが変化したり、Watermarkより遅れたデータが到着した際に、投機的な出力を行える。 (実際のところ、モバイルの環境下においては、電波圏外から戻るなど、端末が記録したデータが実際に到着するまでに大きく遅れることは頻繁に発生する。)
Accumulationモードは同一ウィンドウ内で複数の結果が算出された場合の関係性や動作を定めるもの。これらの結果は完全に切り離されて用いられるケースもあるかもしれない。(例:セッション生存期間を超えたアクセス同士の関連など)違うモードでは、異なるセマンティクスを保持し、計算方法も変わってくるだろう。
最後に、これらの概念の関係を理解しやすくするために、ある4つの質問について再度確認してみる。これらは無限のデータを処理するあらゆるシステムで絡んでくる問いだと考えるため。
- What results are calculated?
この質問に対しては、
-
Where in event time are results calculated?
-
When in processing time are results materialized?
-
How do refinements of results relate?