Distributed Computing Advent Calendar 10日目担当のsitotkfmです。
当初はCyberagent Advent Calendarの10日目に書いてたんですが、あっちは内容が分散とかけ離れてしまっているのと個別に書いた方が良さそうな話題がだったので分けてこちらで書かせていただきます。Kafkaの話じゃなくてすみません。。。
データの時刻
まずログは遅れます。
もちろん転送処理による遅延がほとんどなんですが、負荷高騰やログの詰まり、スマホアプリのオフライン時のログはバッファリングされオンラインになった時に送られてくることも多いです。
また転送のルーティングによっては先に生じたイベントログが次に生じたイベントの後に届くこともままあります。
このようにログの到達というのは遅延が生じ得るものなので順不同であるとみなされます。
解析処理はストリーミング処理(1イベントの逐次処理)とバッチ処理(イベントのまとまりに対する処理)に分けられますが、この2種類の処理どちらでも利用可能なデータ処理体系(ラムダアーキテクチャなど)を考えた時に、この順不同で送られるイベントどうを扱うのかというのが課題になっていました。
Dataflowモデル
Dataflow Modelは順不同かかつ無限に流れるデータに対してストリーミング処理やバッチ処理を行う時のデータの管理について論じられています。
このデータ構造を利用したサービスはGoogle Cloud Dataflowとして利用することができ、同じデータ構造を持つApache BeamとしてOSSで公開されています。
この論文の中では、そもそも順不同で延々流れているデータに対してある時刻で確実に到達しているとみなすと仮定することを難しいとし、時刻をEvent TimeとProcessing Timeに分けて扱うことを提案しています。
時刻の分類
Event timeはその名の通り、そのイベントが生じた時刻です。
Processing timeとはあるイベントに対して処理を行う時刻を指します。これはデータパイプラインを構築した場合、そのコンポーネントごとに変わります。例えばイベントがサーバログを解析する場合、HDFSにファイルとして書き出される時刻とそのファイルMapReduceジョブが処理を始める時刻は異なります。細かく言えばMapとReduceでもProcessing Timeは異なります。
Apache Flinkではこの二つの時刻に加えてIngestion timeというのが導入されています。これはFlink内のジョブのパイプラインの先頭にイベントが到達した時刻をIngestion Timeとするようです。
このIngestion Timeというのもストリーミング処理パイプラインを実際運用する際には非常に効果的なのですが、ここでも話が膨らむとアレなので今回は置いておきます。
ストリーミング処理の時刻の扱い
ちょっと個人的にはストリーミングのログ転送の続き的な話なので今回はストリーミング処理の時刻管理についてとさせてください。
バッチの話やウィンドウ処理のときの時刻の管理もあるのですが、それは各自論文を読んでいただいて、、、。
ログを水と見立てたときに、データパイプラインの各コンポーネントにどこまでデータが流れてきたかをWatermark(水位)と呼びます。
(DataFlow Modelの論文から抜粋)
これはあるストリーミング処理に送られたイベントのEvent TimeとProcessing Timeの分布の例です。 (丸の中の数字は今は意味がないので無視してください)イベントの発生順がX軸でシステムへの到着順がY軸で表されています。
Ideal Watermark(薄い点線)はEvent timeとProcessing Timeに差異がない場合、つまり転送のラグが全くない状態です。もちろんそんなことはあり得ないのでこのWatermarkを満たすようなイベントはありません。
実際のWatermark(Actual Watermark、濃い点線)はProcessing Timeが上に進む中で現れるイベントがを囲むように、右上に伸びるように進んでいきます。このWatermarkには順序が入れ替わっているイベントも含まれます。
このとき左上のイベントはWatermark内に含まれないことに注目してください。
Processing Timeが12:09のときにはEvent Timeは12:07に到達しているためこのイベントはWatermarkの後のイベントなのでストリーミング処理では無視されます。
Dataflowモデルのストリーミング処理は低レイテンシであることを優先させるため、このイベントを無視するという選択をしています。Dataflowはこのように二つの時刻を使って解析範囲を決めます。
まとめ
今回言いたかったのは時刻の扱いというのは処理によって変わるということと、Processing TimeやEvent Timeという二つの時刻はその手助けになるんじゃいかということでした。
Event TimeとProcessing Timeはよく考えれば当たり前のことなんですが、意外と同一に考えてしまっていることも多々あると思います。
Dataflowモデルまで行かなくても、例えばDBにTTLを設定するときにもEvent TimeなのかProcessing Timeなのかというのを考えておくといいと思います。
あとストリーミング処理に正確性を常に求めている人もいるかもしれないのですが、あくまでそれはレイテンシとのトレードオフということを意識していただければと思います。
ではみなさん今年も残り少ないですが、よい時刻をー。