Kafkaの概要を理解する

Kafkaとは

スケーラビリティに優れた分散メッセージキューです。

システム間のデータの受け渡しを仲介し、データを一時的に保持(キューイング)するミドルウェアです。

主な機能

よく使われるのは以下の2つです。

  • ストリームデータ処理のキューイング

[plantuml]
@startuml
agent sensor
database DataSource
usecase Kafka
agent Stream

sensor -> Kafka
Kafka -> Stream
Stream -> DataSource

@enduml
[/plantuml]

  • システム間で大量のデータを受け渡すためのパイプライン

[plantuml]
@startuml
agent System
database Data
usecase kafka
agent Service
agent App

[System] <-> [kafka]
[kafka] <-> [Data]
[Service] -up-> [kafka]
[kafka] -down-> [Service]
[App] -down-> [kafka]
[kafka] -up-> [App]
@enduml
[/plantuml]

ユースケース

Kafkaは2011年にLinkedInからリリースされました。
もともとLinkedInのWebサイトで生成されるログを処理して、Webサイト上のアクティビティをトラッキングすることを目的に開発されたそうです。
アクティビティには、ユーザによるページビューや検索キーワード、広告の利用状況などが含まれるようです。

Webサイトで生成される大量のログを解析することで、ユーザの活動をモニタリングしてサービスの改善に役立てる目的のようです。

LinkedInがKafkaを開発することで、実現したかったユースケースをあげてみます。

  • 高いスループットでリアルタイムに処理したい
  • 任意のタイミングでデータを読み出したい
  • 各種プロダクトやシステムとの接続を容易にしたい
  • メッセージをロストしたくない

[plantuml]
@startuml

agent PageView
agent SearchKeyword
agent Event
usecase Kafka
database SearchEngine
database DWH

PageView -[hidden]-> SearchKeyword
SearchKeyword -[hidden]-> Event
SearchEngine -[hidden]-> DWH

PageView -ri-> Kafka:Data
SearchKeyword -ri-> Kafka:Data
Event -ri-> Kafka:Data

Kafka -> SearchEngine:Stream
Kafka -> DWH:Batch

@enduml
[/plantuml]

高いスループットでリアルタイムに処理したい

膨大なデータを捌きたいので、高いスループットが必要になります。
また、ユーザのアクティビティを把握、またはユーザのアクションに応じて即座にフィードバックを返すためには、リアルタイムに処理したいところです。

任意のタイミングでデータを読み出したい

LinkedInでは、リアルタイム処理とは別に、既存の基盤を用いて集めたアクセス絵オグを一定時間ごとにバッチ処理的に扱いたいというニーズもあったようです。
データを利用するタイミングが必ずしも同時ではなく、利用目的に応じて異なる可能性があり、膨大なデータを受け渡す際のバッファとしての役割も必要になります。

各種プロダクトやシステムとの接続を容易にしたい

LinkedInでは、データの発生元が単一ではなく、複数のシステムからデータを受ける必要がありました。また、利用側も目的ごとに基盤が複数存在していたようです。
以降で紹介するアーキテクチャの図のイメージですね。

メッセージをロストしたくない

扱うメッセージが膨大であったとしても、メッセージのロストは極力避けたいとの思いがあったようです。
ただ、1件ごとの管理をやろうとするとオーバーヘッドが大きくなるため、多少の重複があったとしてもメッセージを失いさえしなければOKの思想らしいです。

アーキテクチャ

Kafkaっていろんな名前が出てきて、最初は混乱するんですよね。
なので、絵を描いて整理しておきます。

[plantuml]
@startuml

rectangle BrokerCluster{
rectangle Broker1{
agent “Partition"
agent “Partition “
}
rectangle Broker2{
agent " Partition"
agent " Partition “
}
}
rectangle “ZooKeeperCluster"{
agent “ZooKeeper “
agent " ZooKeeper “
}
rectangle “DataSource"{
agent “Producer"
agent “Producer “
}
rectangle “UserAPP"{
agent “Consumer"
}
rectangle “Framework"{
agent “Consumer “
agent " Consumer “
}

Broker2 -[hidden]-> ZooKeeperCluster
Broker1 -[hidden]-> Broker2

[Producer] -[hidden]- [Producer ]
[ Consumer ] -[hidden]- [Consumer ]
UserAPP -[hidden]- Framework
DataSource -ri-> BrokerCluster
BrokerCluster -do-> ZooKeeperCluster
[Consumer] <-> BrokerCluster

@enduml
[/plantuml]

plantumlのレイアウトがごちゃごちゃ、、

各コンポーネントについて

  • Producer
    • 書き込み用ライブラリ
  • Broker
    • メッセージキュー(Topic)を構成
  • Consumer
    • 読み出し用ライブラリ

構成をまとめると

  • Topic(1個の仮想的なキュー)を複数のBrokerに分散配置したPartitionで構成する
  • Topinのデータ書き込み/読み出しには、Producer/Consumerライブラリを使用する

まとめ

ざっくりアーキテクチャと、登場人物がわかりました、わかった気になりました。

以降、登場人物の細かい役割などをみていこうと思います。