Kafka definitive guideを読んでいく上での自分用メモ
つど追記予定
特徴
Apache KafkaはLinkedInでスタートしたstreaming processing framework。
当初の目的として以下が挙げられている。
- push-pullモデルによって、producerとconsumerを疎結合にする
- メッセージの永続性
- 高スループット
- 水平スケール
guideでは、serialization formatとしてAvroが推奨されている。
2015年8月時点で、LinkedInでは1日あたり
- 1兆メッセージのproduce
- ペタバイト超のconsume
で使ってるらしい。恐ろしいスケールだ。
基本用語/概念
Topic
messageをカテゴライズする単位。
アクセス解析システムだったらPV / Click / CVみたいな単位になりそう。
messageはtopicに対してappend-onlyで書き込まれていく。
Partition
topicが分散させる単位のことをpartitionと呼ぶ。
topicに対するpartition数は、増加させることしかできない。
partition数は、Kafka cluster内のbrokerと同一か、その倍数にすることで効率よく分散させられる。
Broker
一つのKafka serverをbrokerと呼ぶ。
Producer
topicに対してmessageを書き込むKafka clientのことをproducerと呼ぶ。
デフォルトではpartitionを指定せずに、すべてのpartitionに均等に書き込むが、partitionerによって明示することも可能。ここらへんはSparkと似てる。
Consumer
topicからmessageを読み出すKafka clientのことをconsumerと呼ぶ。
messageはpartition内でユニークなoffsetを持っており、これを使うことでどこまでconsumeしたかをトラッキングできる。
同一のtopicをsubscribeするconsumerたちは同一のconsumer groupに属する。
Kafka clusterのサイジング
以下から算出する
- messageを保持するために必要なdisk space
- 必要となるスループットと、一台あたりの処理可能なnetwork capacity
Producer
Producerの詳細。
KafkaProducer
インスタンスに対して行う。
書き込みスループットを上げたい場合、複数スレッドからsendを呼び出してよい。
messageの書き込み方法には以下の3種類がある。
- Fire-and-forget
- sendを呼び出し、返値を無視する
- Synchronous
- sendで返されるFutureを同期的に待ち受ける
- Asynchronous
- callbackとともにsendを呼び出す
Producerの設定
acks
sendが成功したと判断するために、いくつのpartition replicaに対する書き込み成功を要求するか、を表す。
- acks=0
- brokerからのresponseを待たずに成功と判断する。もっともスループットは出るが、messageがロストしうる
- acks=1
- leader replicaへの書き込み成功を待つ。leaderがcrashして他のreplicaがleader選出された場合にはmessageがロストしうる
- acks=all
- 全replicaへの書き込み成功を待つ
ここらへん、LinkedInでは具体的にどういうログをどのacksで運用しているのか、気になる
Consumer
Consumerの詳細。
一つのtopicに対するconsumerのスループットを上げたい場合、consumer groupにconsumerを追加する。
topicの持つpartition数を超える数のconsumerがconsumer group内にあっても、意味がない(いくつかは遊ぶことになる)
複数のapplicationで同一のtopicをsubscribeしたい場合は、それぞれのapplicationでconsumer groupを用意する。
rebalance
consumerの追加/削除を行った場合、partitionのrebalanceが行われる。
rebalanceの最中はconsumeができなくなるため、若干のダウンタイムが発生する。
consumerの追加 / 削除は、brokerのgroup coordinatorへのAPI request / heartbeatによって行われる。