1
© 2017 NTT DATA Corporation
NTTデータ OSSプロフェッショナルサービス
猿田 浩輔
2017/10/30 NTTデータ テクノロジーカンファレンス2017
Structured Streaming
- The Internal -
2
• 猿田 浩輔
• Apache Sparkコミッタ
• Timeline View作者
• Hadoop/SparkなどOSS並列分散処理系のテクニカルサ
ポートに従事
$ whoami
3
The Basic
4
• Apache Sparkの新しいストリーム処理系
• Spark SQLの上に構築される
• Spark 2.0で試験的に導入され、2.2でα版を卒業
• Spark Streamingには無かったセマンティクスをサポート
• イベントタイムウィンドウ集約
• 遅れて到着したデータのハンドリング
• End-to-End Exactly Once
Structured Streaming
5
データ処理モデル
https://spark.apache.org/docs/latest/structured-streaming-programming-guide.html
ストリームデータをDataFrameの
レコードとして扱う
マイクロバッチを定期的に起動し、
DataFrameに対してクエリを発行する
結果を出力する
DataFrameに対する数10ms - 数100msで完了するマイクロバッチを
連続的に実行することでストリーム処理を実現する
6
• 実行プランの作成
• ステートフル集約処理
• イベントタイムウィンドウ集約処理
• ウォーターマーク
このセッションのスコープ
7
The Internal
実行プランの作成
8
ユーザがDSLを用いて記述したデータ操作の内容に応じて、
背後では論理プランが作られる
実行プランの作られ方(DSLから論理プランの生成)
Aggregate
Filter
Project
Scan Scan
述語: signal > 10
射影リスト: devie, signal
グループキー: device
集約関数: countval agged = deviceDF1
.union(deviceDF2)
.select("device", "signal")
.where("signal > 10")
.groupBy("device")
.agg(count())
Union
9
ユーザがDSLを用いて記述したデータ操作の内容に応じて、
背後では論理プランが作られる
実行プランの作られ方(DSLから論理プランの生成)
• プランツリーの各ノードはDataFrame
の各レコードに適用するオペレータ
を表す。
• 論理プランでは、各オペレータは具
体的にデータをどのように処理する
かは定義しない。適用するオペレー
タの順序や各オペレータが出力する
レコードのスキーマ等を定義する
Aggregate
Filter
Project
Scan Scan
述語: signal > 10
射影リスト: devie, signal
グループキー: device
集約関数: count
Union
10
マイクロバッチごとに制御エンジンが論理プランを修正する
• 新規データが到着していないデータソースのスキャンを省く
• マイクロバッチごとに変化する属性値の更新など
実行プランの作られ方(論理プランの修正)
Aggregate
Filter
Project
Scan Scan
Union
Aggregate
Filter
Project
Scan Scan
Union
11
ワークフローに沿って論理プランから物理プランが作られる
実行プランの作られ方(意味解析/物理プランの生成/最終化)
意味解析
最適化
物理プラン作成
物理プラン最終化
属性やDataFrameなどの参照解決
型チェック
追加の意味づけ
物理的な条件に依らない最適化
データソースに応じたスキャン方式の決定
集約/結合処理方式の決定
シャッフルの挿入
物理プランの最適化
ステータスの更新
論理プラン
12
制御エンジンが作った物理プランに基づいて、分散処理実行
時の各タスクの処理が決まる
実行プランの作られ方(論理プランの修正)
HashAggregateExec
ProjectExec
FilterExec
FileSourceScanExec
ShuffleExchangeExec
• 各オペレータはDataFrameのレコー
ドの具体的な処理方法を定義する
• 分散処理実行時には各タスクが
DataFrameのパーティションに対して
各オペレータを適用する
13
The Internal
ステートフル集約処理
14
• ステートレスな処理
• 属性の選択(プロジェクション)やフィルタなど、他のレコードと
独立に処理可能なもの
• マイクロバッチごとに、新規に到着したレコードで構成された
DataFrameを処理する
• ステートフルな処理
• 集約処理など
• 新規に到着したレコードに加えて、直前までのマイクロバッチ
により更新されたステートを加味してDataFrameを処理する
ステートレスな処理とステートフルな処理
15
ステートフル集約処理の例
• ストリーム処理で集約処理を行う場
合、過去に処理したデータも含めて
集約処理したい場合が多い
• 処理実行時点までに特定のイベン
トが発生した回数のカウントなど
• それまでの集約処理の計算結果も
加味して集約処理を行う
https://spark.apache.org/docs/latest/structured-streaming-programming-guide.html
16
① 部分集約処理
• タスクローカルでグループごとに集約処理を行う
② 部分マージ処理1
• 各タスクが部分集約処理した結果を、グループキーに基づいて
シャッフルしてマージ
③ ステートリストア
• 直前のマイクロバッチで保存された「ステート」をリストアする
④ 部分マージ処理2
• 部分マージ処理1の出力とリストアしたステートをマージする
⑤ ステートセーブ
• 部分マージ処理2の結果を「ステート」として保存する
⑥ 最終処理
• 集約関数固有の最終処理
ステートフル集約処理は6つのフェーズで行われる
17
例題: 平均値を求める - 部分集約処理 -
20
17
30
A
B
C
area temp
A 20
B 17
C 30
・
・
・
DataFrame
(観測点の気温)
32
31
22
B
B
A
27
15
17
C
A
A
20
17
30
A
B
C
1
1
1
累積気温 観測件数
累積値とレコード数の属性を追加
sumarea count
63
22
B
A
2
1
27
32
C
A
1
2
分
割
し
て
各
タ
ス
ク
に
分
配
タ
ス
ク
ご
と
に
集
約
18
例題: 平均値を求める - 部分マージ処理1 -
20
17
30
A
B
C
1
1
1
累積気温 観測件数
sumarea count
63
22
B
A
2
1
27
32
C
A
1
2
20
22
32
A
A
A
1
1
2
17
63
B
B
1
2
30
27
C
C
1
1
74A 4
80B 3
57C 2
観測点ごとにマージ
(累積気温と観測件数を足し合わせる)
観
測
点
ご
と
に
シ
ャ
ッ
フ
ル
19
例題: 平均値を求める - ステートリストア -
sumarea count
80A 374A 4
80B 3
57C 2
areaの値をキーに、ステートストア
からステート(過去のマイクロバッチ
の部分マージ2の結果)を読み出す
ステートストア
⊕
⊕
⊕
150B 5
150C 5
74A 4
80A 3
80B 3
150B 5
57C 2
150C 5
key=A
key=B
key=C
20
例題: 平均値を求める - 部分マージ2 -
sumarea count
74A 4
80A 3
80B 3
150B 5
57C 2
150C 5
154A 7
230B 8
207C 7
ステートストアからリストアしたステートと、当該
マイクロバッチの部分マージ1の結果をマージ
(累積気温と観測件数を足し合わせる)
21
例題: 平均値を求める - ステートセーブ -
sumarea count
154A 7
230B 8
207C 7
ステートストア
areaの値をキーに、ステートをアップ
デート
ステートセーブの出力は出力モードに
依存する(この例はCompleteモード)
181D 6
154A 7
34E 2
230B 8
135F 5
207C 7
22
例題: 平均値を求める - 最終処理 -
最終処理(sum / countで観測地点ごとの平均気温を求める)
181D 6
154A 7
34E 2
230B 8
135F 5
207C 7
sumarea count
sum / count
30.1D
22A
avgarea
17E
28.8B
27F
29.6C
23
The Internal
イベントタイムウィンドウ集約処理
24
• ステートフル集約処理の一種
• データが処理系に到着した時刻に基づくウィンドウ集約では
なく、イベントタイム(レコードに意味付けされた時間。例え
ばイベントの生起時刻)に基づくウィンドウ集約
• Spark Streamingでは到着時刻に基づくウィンドウ集約処理
のみ実装されていた
イベントタイムウィンドウ集約処理
25
• データの到着時刻は必ずしも「関心ごと」を表さない
• 例えばデータの生起時刻に関心がある場合、遅延などで
データの到着順序の前後や到着間隔のズレが生じるため、
「到着時刻」に着目しても無意味
なぜイベントタイムウィンドウ集約処理が必要か
26
イベントタイムウィンドウ集約処理の例
https://spark.apache.org/docs/latest/structured-streaming-programming-guide.html
27
window time word
start end
12:00 12:07 12:00 Spark
12:06 12:13 12:08 Hadoop
イベントタイムウィンドウの作り方
• 任意のイベントタイムを持つレコードについて、それらが属する、開始時間が
最も遅いタイムウィンドウを求める
• 求め方は実行プラン作成時に、イベントタイムを変数として定式化できる
• ウィンドウ幅=7分
• スライディング幅=3分
DataFrame
time word
12:00 Spark
12:08 Hadoop
28
イベントタイムウィンドウの作り方
time word
12:00 Spark
12:08 Hadoop
window time word
start end
11:54 12:01 12:00 Spark
11:57 12:04 12:00 Spark
12:00 12:07 12:00 Spark
12:00 12:07 12:08 Hadoop
12:03 12:10 12:08 Hadoop
12:06 12:13 12:08 Hadoop
• 任意のレコードが属するタイムウィンドウの最大数分だけタイムウィンドウを増幅する
• 最大数はウィンドウ幅とスライディング幅から求められる
• ウィンドウ幅=7分
• スライディング幅=3分
DataFrame
29
イベントタイムウィンドウの作り方
time word
12:00 Spark
12:08 Hadoop
time < window.start || window.end <= timeであるレコードを除外する
• ウィンドウ幅=7分
• スライディング幅=3分
DataFrame
window time word
start end
11:54 12:01 12:00 Spark
11:57 12:04 12:00 Spark
12:00 12:07 12:00 Spark
12:00 12:07 12:08 Hadoop
12:03 12:10 12:08 Hadoop
12:06 12:13 12:08 Hadoop
30
イベントタイムウィンドウ集約
windowとwordでグループ化/集約処理
window time word
start end
11:54 12:01 12:00 Spark
11:57 12:04 12:00 Spark
12:00 12:07 12:00 Spark
12:03 12:10 12:08 Hadoop
12:06 12:13 12:08 Hadoop
12:00 12:07 12:04 Spark
12:03 12:10 12:04 Spark
window word count
start end
11:54 12:01 Spark 1
11:57 12:04 Spark 1
12:00 12:07 Spark 2
12:03 12:10 Hadoop 1
12:03 12:10 Spark 1
12:06 12:13 Hadoop 1
31
The Internal
ウォーターマーク
32
• ストリーム処理ではデータの到着遅延はつきもの
• 異なるデータソース間の遅延のばらつき
• データソースと処理系間の伝送路の一時的な輻輳
ウォーターマークのモチベーション
https://spark.apache.org/docs/latest/structured-streaming-programming-guide.html
33
• 遅れてきたデータをハンドリングする仕組み
• ステートフルな処理とともに用いられる
• マイクロバッチ実行時点での最新イベントタイム - 許容する
遅延時間で計算される
• 最新イベントタイムはマイクロバッチごとに制御エンジンが更
新する
ウォーターマーク
34
ウォーターマークの作用
https://spark.apache.org/docs/latest/structured-streaming-programming-guide.html
35
ウォーターマークの作用
https://spark.apache.org/docs/latest/structured-streaming-programming-guide.html
イベントタイム=12:17 > ウォーターマーク=12:11なので受理される
36
ウォーターマークの作用
イベントタイム=12:04 <= ウォーターマーク=12:11なので破棄される
https://spark.apache.org/docs/latest/structured-streaming-programming-guide.html
37
• Structured Streamingの中でも特徴的な機能に焦点を当て、
裏では何が起きているのかを実装面から解説した
• 今回カバーしなかったエラーリカバリや、バージョン2.3で導
入される新機能、開発中のイベントドリブンのストリーム処
理エンジンも興味深いテーマ
まとめ
38© 2017 NTT DATA Corporation

Structured Streaming - The Internal -