[Kafka 入門] ストリーム処理 分散ストリーミングプラットフォーム

ストリーミング

対象者

本記事では、私が分散ストリーミングプラットフォームを学習する上でつまずいた以下の内容について記載しています。

  • そもそもストリーム処理とは何か
  • 分散ストリーミングプラットフォームとは何か
  • 分散ストリーミングプラットフォームは何に利用する?なぜ必要?

本記事では、分散ストリーミングプラットフォームの具体例として Apache Kafka を例に説明をします。

分散ストリーミングプラットフォームとは

分散ストリーミングプラットフォームは明確な定義はありませんが、一般的には以下の2つから構成されるシステムです。

  • 分散データストリームのソース(Publish/Subscribe メッセージングシステム)
  • 分散ストリーム処理

そのため、まずは上記2つの用語について説明します。

Publish/Subscribe メッセージングシステムとは

Publish/Subscribe メッセージングシステムとは、Publisher(送信側)から送信したメッセージ(順序付けられた文字列)を、非同期的に Subscriber(受信側)が受信可能なシステムです。

と言ってもわからないので、Publish/Subscribe メッセージングシステムである Apache Kafka を例に全体のコンポーネントを見てみましょう。なお、システムによって以下の用語は色々な呼び方をします。

  • Publisher( Producer, Writer とも呼びます)
  • Subscriber(Consumer, Reader とも呼びます)
    • メッセージを取得することを消費といいます

要はメッセージをソースからターゲットに移動(集約)させるだけのシステムです。

Publish/Subscribe メッセージングシステムのメリット

Publish/Subscribe メッセージングシステムの初見の感想は「Producer 側から Consumer 側に直接メッセージを送ればよくない?1箇所に集めたら何が良いんだ??」でした。

そのため、まずは Publish/Subscribe メッセージングをなんのために利用するか説明します。

メリット1:Producer の追加、削除が容易

Producer 側で既存の Consumer を1つ1つ探し、メッセージを送信する必要もありません。1つの Publish/Subscribe メッセージングシステムにメッセージを送信するだけです。

具体例を見る(Producer を追加する)

例えば、以下のようなシステムが存在したとします。

  • Producer: Web サイトAのログ、ショッピングサービスのログ
  • Consumer: モニタリング、機械学習、データベース

この時、「チャットサービス」のログでもモニタリング、機械学習、分析を利用したくなったとします。そのため、Producer に「チャットサービス」を追加します。

■Publish/Subscribe メッセージングシステムが存在しない場合
「チャットサービス」はモニタリング、機械学習、分析(複数箇所)にログを送信するように実装する必要があります。

■Publish/Subscribe メッセージングシステムが存在する場合
「チャットサービス」は Publish/Subscribe メッセージングシステム(1箇所)にログを送信するだけOKです。

メリット2:Consumer の追加、削除が容易

先程と似ていますが、Consumer を新しく追加しても、既存の Producer のメッセージ送信先を変更する必要がありません。

具体例を見る(Consumer を追加する)

例えば、開発部署に以下のようなシステムが存在したとします。

  • Producer: Web サイトA, ショッピングサービス, チャットサービスのログ
  • Consumer: モニタリング、機械学習、データベース

この時、営業部署でマーケティング調査のために、「分析システム」で Web サイトAのログ, チャットサービスのログを利用したくなりました。そのため、「分析システム」を Consumer に追加します。

■Publish/Subscribe メッセージングシステムが存在しない場合
Web サイトA、ショッピングサービス、チャットサービス(Producer)は、新しく「分析システム」にメッセージを送信するように変更する必要があります。

■Publish/Subscribe メッセージングシステムが存在する場合
Web サイトA、チャットサービス(Producer)は、既に Publish/Subscribe メッセージングシステムにメッセージを送信しているため、「分析システム」のために Producer の処理を変更する必要はありません。

メリット3:時間的制約を分離するバッファとして利用可能

ピーク時に Consumer 側の処理が間に合わない場合は、Publish/Subscribe メッセージングシステムにメッセージを一時的に保管することができます。

具体例を見る(時間的制約を分離するバッファ)

例えば以下のようなシステムを例に考えます。

  1. お客様がネット通販で注文した商品を Producer が Publish/Subscribe メッセージングシステムに送信
  2. Consumer が Publish/Subscribe メッセージングシステムからお客様の注文した商品を取得し、発送準備を行う

上記のシステムでは Producer 側と Consumer 側で以下のように時間的制約が異なります。

  • Publisher 側は可能な限り早い応答が求められる
    • 注文ボタンをクリックしてから、画面遷移に20秒待たされるシステムは論外だろう
  • Subscribe 側の発送準備はある程度の遅延は許容される
    • 通常5秒で終わる発送準備が、10分後に発送準備が完了したところでブチ切れるお客様は少ないはず

そのため、Publisher 側と Subscribe 側の時間的制約を分離するバッファとして 以下のように Publish/Subscribe メッセージングシステム利用します。

  • Publish/Subscribe メッセージングシステムに保存した時点で Producer 側で注文完了画面を表示します
  • Consumer 側は Publish/Subscribe メッセージングシステムのメッセージを消費して淡々と発送準備をします(ピーク時刻を過ぎると徐々に処理が追いついてきます。)

メリット4:メッセージを中央集中管理可能

下記の図のようにシステムが複雑になりません。あのデータは誰が持っている?加工後のデータはどこに渡せばいい?というような事態を回避できます。

メッセージキューイングシステムと何が違うの?

Publish/Subscribe メッセージングシステムでは、1つのメッセージを Consumer が複数回消費可能であるのに対し、メッセージキューイングシステムでは、1つのメッセージを1度しか消費できません。

これにより、Producer は Publish/Subscribe メッセージングシステムに1回だけメッセージを送信すればよく、複数の Consumer にメッセージを送信する必要がありません。(上述したメリット1,2に繋がります)

fluentd と何が違うの?

fluentd はデータをソースからターゲットに移動(集約)させるという用途では似てますが、キューイング機能を持ちません。そのため、時間的制約の分離を実現できません。

なお、以下の記事の「キューを置く」のように、時間的制約の分離と Reliability の向上のために、データの集約先として Publish/Subscribe メッセージングシステムを利用することもあるようです。この場合 fluentd は Publisher, Subscriber となります。

Fluentdとログ収集のパターン - Go ahead!
「ログを集めて保存する」と言うのは簡単だけど,ログ収集の構成にはいくつか方法があり,勉強会などでちょくちょく聞かれるので,いくつかのパターンについて書く. 「俺はもうバリバリログ収集やってるぜ!」という人は多分すでに知っていることが書かれているので,タブを閉じて良い. …

具体的な製品例

以下の製品が有名です。

  • Apache kafka
  • Kinesis Data Stream

Publish/Subscribe メッセージングシステムのアーキテクチャ

先程 Publish/Subscribe メッセージングシステムの概要として以下の図を示しましたが、ここでは中のアーキテクチャについて見ていきます。

ここでは、Apache Kafka を例に Publish/Subscribe メッセージングシステムの中身を見ていきます。

Kafka のアーキテクチャ

メッセージ

Publish/Subscribe メッセージングシステムで利用するメッセージはバイト列です。アプリケーションログなどをメッセージとして Publish/Subscribe メッセージングシステムに送信したり、消費したりします。

シリアライズ

送信するログなどをバイト列に変換することです。上述のとおり、メッセージはバイト列である必要があります。

デシリアライズ

消費するバイト列を元のデータに変換することです。上述のとおり、消費するメッセージはバイト列なので必要に応じて元のデータに戻します。

Broker

Broker は Publish/Subscribe メッセージングシステムが稼働する 1 台のサーバーです。Publish/Subscribe メッセージングシステムは複数の Broker から構成されるクラスターです。

パーティション

パーティションは Broker 内に存在するメッセージを書き込む場所です。メッセージはパーティションの先頭から書き込まれ、パーティション内の順序が保証されます。パーティションは別々の Broker に配置することも可能です。

トピック:

パーティションの集合です。つまりトピックを使用して、複数のコンピュータに処理を分散させたり、データをレプリケーションします。

Producer

メッセージを送信する側のクライアントです。Producer はトピックを指定してメッセージを送信します。トピックは、パーティションキーのハッシュ値を元にメッセージを保存するパーティションを決定します。

Consumer

メッセージを消費する側のクライアントです。Consumer はトピックとパーティションを指定することでメッセージを消費します。

オフセット

Consumer がパーティションをどこまで消費したのか記録した値です。Consumer が死んだ時、新しく割り当てられた Consumer は前回の続きからデータを読むことができます。

分散ストリーム処理とは

分散ストリーム処理とは、ストリーミングデータ(時間の経過とともに無限に流れてくるデータ)を複数のコンピュータで処理することです。

ストリーミングデータの特徴

ストリーミングデータ(イベントストリーム、データストリームとも呼ばれる)の特徴は以下の3つです。

  • 順序付けされている
  • イミュータブル(変更不可能)なデータレコード
  • 再生可能 ※必須ではない

順序付けされている

イベント(ストリーミングデータの各データ)には順序があり、順序を重要視するシステムで利用します。

例えば、イベント1「給料 20 万円の振り込み」、イベント2「5 万円の引き出し」には順序があります。残高 0 円の口座の場合、イベント1が先です。逆は残高不足で引き下ろせないのでありえません。

イミュータブル(変更不可能)なデータレコード

イベントは1度発生すると削除、変更できません。

例えば、イベント「5 万円の引き出し」を後から削除、変更することはできません。このイベントをキャンセルするには、新しいイベント「5 万円を預け入れ」を実行する必要があります。

再生可能 ※必須ではない

順序付けされていて、イミュータブルなデータレコードのため、ストリーミングデータは再現可能です。

以下のようなイベントが発生した場合、現在の残高を求めることはもちろん、ある時点での残高を求めることも可能です。

イベント0「残高 0 円で口座開設」
イベント1「5 万円を預け入れ」
イベント2「10 万円を預け入れ」
イベント3「5 万円の引き出し」
イベント4「5 万円を預け入れ」
イベント5「10 万円の引き出し」

例えばイベント3終了時点では、残高が 10 万円であることがわかります。このようにイベントリストから過去のある状態のデータを再現することをマテリアライズと言います。

ストリーム処理 VS バッチ処理

ストリーム処理とバッチ処理の違いは時間軸の違いです。
ストリーム処理はリアルタイム性を重視し、バッチ処理はリアルタイム性を重視しません(スループットを重視します)。
※ストリーミングデータに特性には時間は関係ありません。

バッチ処理

バッチ処理はデータを一括で処理することでスループットを重視します。(例えば、データを都度送信する場合は1つのデータに1つのヘッダが付与されますが、一括でデータを送るとヘッダが1つで済みます。)

例えば、店舗売上の日次処理や、夜中のメンテナンスなどがバッチ処理に含まれ、通常はリアルタイム性を求められません。

ストリーム処理

ストリーム処理はストリーミングデータが発生する度にデータを処理することでリアルタイム性を重視します。

リアルタイム性が重視される例としては以下のとおりです。

  • クレジットカードの不正検出(翌日や1ヶ月後に検出では遅すぎます。すぐに利用を停止したいです)
  • リアルタイム広告(ユーザーがWebサイトを離れてしまった後に最適な広告を決定するのでは遅すぎます)
  • 運送状況の確認(IoTデバイスが翌日に通過した位置情報を送信しても、既にそこ宅配物はありません。)

具体的な製品名

有名な製品は以下のとおりです。

  • Kafka Streams(Apache Kafka の Streams API)
  • Kinesis Data Analytics
  • Apache Flink
  • Apache Spark Streaming
  • Apache Storm
  • Apache Samza

分散ストリーミングプラットフォームまとめ & 参考書籍

分散ストリーミングプラットフォームは「Publish/Subscribe メッセージングシステム」と「分散ストリーム処理」の特性を組み合わせることにより、以下の機能を持ちます。

  • 複数のデータソースから複数のデータターゲットにデータを移動
  • データソースとデータターゲットの時間的制約を分離
  • リアルタイムにデータを処理

また、処理やデータの保存を分散する特性上、単一障害点を回避する機能も持ちます。

分散ストリーミングプラットフォームの企業での利用例

分散ストリーミングプラットフォーム(Apache Kafka)を企業で使用した例を載せます。より具体的な

参考書籍

本記事を記載する上で以下の書籍を参考にしました。分散ストリーミングプラットフォーム である Apache Kafka の作成者が執筆した書籍だけあり、かなりわかりやすく説明されています。

本記事よりも詳しく Apache Kafka を知りたい方はどうぞ。

0

コメント

タイトルとURLをコピーしました