読者です 読者をやめる 読者になる 読者になる

夢とガラクタの集積場

落ちこぼれ三流エンジニアである管理人の夢想=『夢』と、潰えた夢=『ガラクタ』の集積場です。

Amazon KinesisとApache Kafkaの類似点/相違点まとめ

こんにちは。

Amazon Kinesisについて調べたり実装してみたりしたため、
モデルがよく似たApache Kafkaとの類似点や相違点が気になってきました。

というわけで、実際比べてみた結果どうだったのかをまとめてみます。

1.2つのプロダクトの類似点

Amazon KinesisApache Kafkaの大きな類似点として、以下があります。

  • 1.メッセージを取得したタイミングで削除するのではなく、一定期間経過後に削除するモデルを取っている
    • Kestrel、RabbitMQといったプロダクトはメッセージを取得され、利用側から応答が返った段階で削除するモデルを取っている。
      • 「メッセージキュー」と言いあらわした場合、削除するモデルの方がイメージ的には近い?
    • Amazon KinesisApache Kafkaはメッセージの提供を行うのみで削除は行わない。一定時間経過後に削除している。
  • 2.メッセージの生産者(Producer)、メッセージの消費者(Consumer)は複数存在できる
    • 1の性質が存在するため、メッセージは複数の消費者から取得可能となる。
      • 取得後削除するモデルの場合、他の消費者が取得&応答待ちのメッセージの扱いなどで問題となるが、1のモデルのため問題ない。
  • 3.「どこまでメッセージを読んだか?」はメッセージの消費者側で管理する
    • こちらも1の性質と表裏となるが、メッセージを削除しないため、「どこまで読まれたか」はAmazon Kinesis/Apache Kafka側では管理しない。
      • そのため、消費者側でどこまで読んだかを管理し、「どこからどこまで読む」という形で消費者側がリクエストを出す形になる。
      • 言ってしまうと、Amazon Kinesis/Apache Kafkaのやっていることは「リクエストに応じて構成/メッセージを提供する」のみとなる。

尚、各々の基本構成図は以下です。
Amazon Kinesisクラスタ部分がクラウドによって隠蔽されて単純化していること以外は同じ構成になっています。

Apache Kafka

この手のプロダクトを言い表す場合、「メッセージキュー」という表現くらいしか広く通じる言葉がないのですが、
実際の所この2プロダクトは「メッセージキュー」という表現にはいまいち合いません。
PubSub型のPersistentメッセージバス」という表現が個人的には一番あっていると思いますが・・・
どなたか、いい言葉があれば教えてください^^;

2.2つのプロダクトの相違点

次は2つのプロダクトの相違点です。

Amazon KinesisApache Kafkaの大きな相違点は、当たり前な話ではあるのですが、以下です。

  • 1.Amazon Kinesisは内部のプロセス構成や障害について気にする必要は無い
    • Amazon Kinesisを利用する場合、内部のプロセス構成を気にすることなくShardの追加によるスケールアウトが可能。
    • Amazon Kinesisを利用する場合、内部の障害は「取得失敗」「性能超過」の2つに集約される。その2つのハンドリングを行えばいい。

Apache Kafkaはあくまでローカルのクラスタ群に構築した分散システムであるのに対し、
Amazon Kinesisクラウド上で提供されるSaaSです。
そのため、内部構成を気にすることなく後付けでスケールが可能である上に、障害も単純化されて種類に応じて対応すればいい、となります。

・・なんか、当たり前といえば当たり前な結果になりましたが、比較結果はこんな感じです。

3.細かい相違点

後は、以下のように細かい相違点は下記のようにそれなりにあるため、
もし両方に対応する必要が出てきた場合は下記のように考えておけばいいかと。

  • 「どこまでメッセージを読んだか?」は利用者側が管理する必要があるが、KinesisとKafkaは以下のようにデフォルトの動作が違う。
    • Kinesisは利用者側の管理情報の保持方法については2つ選択肢(下記)がある。
      • IRecordProcessorを継承したアプリを作成することで、DynamoDB上に自動的に保存。
      • クライアントAPIを直に実行することで、自前で管理することが可能。
      • ただし、IRecordProcessorを利用する場合は1スレッドで1パーティション分しかデータを取得できない。
    • KafkaはZooKeeperを用いて利用者側が連携するため、利用者側の管理情報はZooKeeper上に保持される。
      • メッセージをどのパーティションから取得するかもZooKeeperとのコーディネーションで自動的に行われる。
      • ただし、ZooKeeperを使用しない方式で自前で作りきることも一応可能。
  • KinesisとKafkaでは既存のStream(Topic)にShard(Partition)を追加/削除する場合は下記のようになる。
    • KinesisにはShardの追加/削除というオペレーションではなく、「Split」という形でパーティションを分割する。
      • そのため、分割後のShardには過去のデータは残っておらず、親のShardからデータをまず全て取得する必要がある。
    • Kafkaはパーティションの「追加」のみが可能。「削除」はできない。
      • KafkaのAPIとして「Consumerスレッド」<「パーティション数」であっても自動的にZooKeeperと通信して調整されるため、パーティションを削除するということ自体を行う必要がないモデルであるため?

とりあえずわかりやすい違いとしてはこれくらいでしょうか。
またもし更に詳細なことがわかった場合は再度まとめますね。