https://read-streaming-systems.connpass.com/event/253010/
以下の5つの概念を、後のChapterの土台として説明していく (1, 2はChapter1で既出だが、このChapterで再訪)
Triggers
[13:20:00, 13:30:00)
のものだった時、「13:25:00に途中状態から一旦出力する」というトリガも設定できるWatermarks
t' < t
な event time を持つデータがやってくることも現実的にはある。これはlate dataと呼ぶAccumulation
Akidau先生イチオシの、ストリーム処理の分析フレームワーク。
この疑問に答えていくと、とあるストリーム処理のパイプライン(またはその部分)が何をしているものかわかるという代物。
(ぶっちゃけ分かりづらくない…?)
上述の5つの概念のうち、
は全てにカスる。残りの
がどう絡むか記載する。
time-agnostic processing
とか more complex types of windows
がどういう意図なのかは掴みかねた
Where in event time
という質問の解は未定義に思うのだが、文ではそう言ってない気もするここからしばらくバッチ処理の話。What resultとWhere in event timeは(無限データ列が対象の)ストリーム処理持ち出さずとも(有限データ列が対象の)バッチ処理で語れるので。
逆に、以下はバッチの話だと通常出てこない。
これらは全て「途中経過」に関するものであり、有限データを扱うバッチ処理の場合は最後に一発結果を出すだけで基本的に十分なので。
Beam Modelは無限データも有限データも統一的に扱えるので、ここからBeam Modelのコードスニペットが出てくる。
本書の至るところで使われるテーブルと:
> SELECT * FROM UserScores ORDER BY EventTime;
------------------------------------------------
| Name | Team | Score | EventTime | ProcTime |
------------------------------------------------
| Julie | TeamX | 5 | 12:00:26 | 12:05:19 |
| Frank | TeamX | 9 | 12:01:26 | 12:08:19 |
| Ed | TeamX | 7 | 12:02:26 | 12:05:39 |
| Julie | TeamX | 8 | 12:03:06 | 12:07:06 |
| Amy | TeamX | 3 | 12:03:39 | 12:06:13 |
| Fred | TeamX | 4 | 12:04:19 | 12:06:39 |
| Naomi | TeamX | 3 | 12:06:39 | 12:07:19 |
| Becky | TeamX | 8 | 12:07:26 | 12:08:39 |
| Naomi | TeamX | 1 | 12:07:46 | 12:09:00 |
------------------------------------------------
計算が出てくる:
computing keyed integer sums over a simple dataset consisting of nine values
この9行のレコードのScoreカラムの合計値を色んな軸で区切って計算するという話。
上記の9行をevent time v.s. processing time なグラフにプロット(値はScore)すると↓
とか、そういうことが見て取れる
Beam Modelにおいて、計算対象(入出力)は PCollections
とモデリングされ、計算は PTransforms
とモデリングされる。
接頭辞の P
は Parallel のP。Beam Modelは分散並列前提なので、テーブルやらキューみたいなもの(PCollections)も分散して置かれるし、それに対する処理(PTransforms)も分散並列で行われる。
ここからBeamのコードスニペットが出てくる。書籍のは適宜擬似コードになっているが、本当に動くコードはこちらにあるとのこと: https://github.com/takidau/streamingbook/blob/master/src/main/java/net/streamingbook/BeamModel.java
先に挙げた9行テーブルの例のサブセットとして、Beam Modelで次のような計算を記述している。
黄色いのは “What result” に対応。Beam語で言うと PTransforms に当たる。
IO.read(...)
で読み、単一Stringな PCollection<String> raw
に格納raw
に ParseFn
というパース計算を適用。どうやら文字列にはチーム情報とスコア情報が含まれていたようで、それをkey-value形式で PCollection<KV<Team, Integer>> input
に変換input
に Sum.integersPerKey()
を適用。名前からして、「同一キーのバリューの合計値を算出」するPTransform。その結果を PCollection<KV<Team, Integer>> totals
に格納先の例だと9行全て Team = "TeamX"
となっているので、キーは単一となり、合計値も単一となる。
Processing timeが経過していくとスコアが5, 7なレコードが順に到着し、合計値が更新されていく。今回はバッチ計算ということなので、全データが到着したことが保証されるタイミング(上図だと12:10の設定)に1回切り、結果が出力される(上図の右下)。
ちなみに、 http://streamingbook.net/fig のサイトにニュルニュル動く図が公開されているのでこれ見ながらじっくり悩むと便利なときがある
上図は http://streamingbook.net/fig/2-3
ウィンドウはデータ列が無限長でも有限長でも定義できる。
Ch.1でもやったが、よくあるウィンドウは↓の3つ。
Fixed windowのうち、2分おきなやつ(そしてウィンドウ内では同一キーのバリューの合計値を算出)をBeam Modelで記述すると↓
黄色ハイライトのせいで見えづらいが、 Window.into(FixedWindows.of(TWO_MINUTES)) の青字は “Where in event time” に対応している。その問の答えはここでは「event timeで2分ごと」となる。
前出の例でこのウィンドウ計算を行うと、結果は↓のようになる。バッチ処理であり、processing time = 12:10 で一気に結果が出てくる点に再度注意。
いよいよストリーム処理特有の「無限データ列処理の途中経過」の話、