ikemonn's blog

技術ネタをちょこちょこと

Kafka: a Distributed Messaging System for Log Processing を読んだ

Kafka: a Distributed Messaging System for Log Processingを読んだ時のメモ。

どんなもの?

  • LinkedInによって開発された分散メッセージングシステム
    • 大容量のログを高スループットで配信、低レイテンシで収集することを目的としている

先行研究とくらべて何がすごい?

  • ログの処理の焦点を絞って開発されたので低レイテンシで高スループット
    • 従来のメッセージングシステムに備わっていた、不要な機能を削ぎ落としている
      • delivary guaranteeや順番の担保等
        • ログなので多少欠けていても問題ない
      • 従来のメッセージングシステムはスループットにforcusしてなかった
        • バッチ処理でやればいいと考えていた
        • ビジネス的にはリアルタイムでログを処理したい場面も増えた
  • スケールアウトしやすい

技術や手法の肝は?

f:id:ikemonn:20170712230147p:plain

  • Kafka Architecture and Design Principles
    • producer
      • topic(メッセージのfeedのようなもの)にメッセージを送る
    • broker
      • topicに送られてきたメッセージを保存する
    • consumer

      • 1つ以上のtopicをsubscribeできて、pullすることでbrokerからデータを取得する
    • 負荷を分散するためtopicは複数のbrokerに分散されている

    • producerとconsumerは同時にmessageをpublish/subscribeできる

f:id:ikemonn:20170712230205p:plain

  • Efficiency on a Single Partition
    • Simple storage
      • topicのそれぞれの部分はlogical logに対応している
      • 物理的なログは一定サイズのsegment fileとして、保存されている
      • producerがメッセージをpartitionにpublishすると、brokerはログの最後にメッセージを追加していく
      • パフォーマンス向上のために、ある程度メッセージが溜まってからdiskにflushする
      • メッセージはflushされてから、consumerにconsumeされる
      • 従来のメッセージングシステムと異なり、メッセージにはIDは振られていない
        • それぞれのメッセージはlog内のoffsetで位置を決められている
      • consumerは特定のpartitionから順番にメッセージをconsumeする
        • consumerからのpull requestにはメッセージのoffsetとfetchするbyte数が含まれている
      • brokerはin-memoryに各segment fileの初期位置を示したoffset listを持っている
    • Efficient transfer
      • Kafka Layerにはcacheを持たず、file systemのpage cacheを利用している
        • GCのoverheadが小さい
    • Stateless broker
      • brokerは各consumerがどれくらいメッセージをconsumeしたかについての情報は管理しない
        • consumer自身がその情報を持っている
        • brokerが管理すると複雑になってしまうのと、overheadが生まれるから
      • brokerはどこまでデータが読まれたかがわからないので、一定時間が経ったデータを消していく
        • アプリケーションのバグがあっても一定期間内であれば、再度同じ情報をconsumeできる
  • DistributedCoordination
    • consumer group
      • 1つ以上のconsumerから成るグループ
      • そのグループに対して一つずつメッセージが配信される
      • グループはそれぞれ独立していて、他のグループと協働しない
    • 工夫点
      • topic内のpartitionを並列化の最小単位とした
        • どんな時も1つのpartitionの全てのメッセージはそれぞれのグループの1つのconsumerからのみconsumeされる
          • どのconsumerにどのメッセージを送ったかという情報やlockのことを考えずにすむのでoverheadが少ない
      • central master modelは避けた
        • ZooKeeperを用いて、master無しでconsumer達が協調して動くようにした
    • Delivery Guarantees
      • at-least-once delivery
        • consumerがcrashしてももう一度同じメッセージを読みにいける
        • 正確に一度だけ送ろうとすると2PC等を使わねばならず、非効率
      • single partitionからは順番にデータが送られるが、partition間での順序は保証しない

どうやって有効と検証した?

  • LinkedInで半年間使った
  • KafkaとApache ActiveMQの比較をした f:id:ikemonn:20170712230224p:plain

  • Producer Performance

    • producerはbrokerからのackを待たないので速い
    • 効率的なメッセージフォーマットなので速い
      • メッセージのoverheadは9bytes(ActiveMQは144bytes)
    • ActiveMQはメッセージのメタデータを管理するindexへのアクセスに時間がかかる

f:id:ikemonn:20170712230235p:plain

  • Consumer Performance
    • 効率的なメッセージフォーマットなので速い
    • 全てのメッセージの配信状況を管理しないので速い
      • 中には送られていないメッセージもある
    • sendFile APIが転送のoverheadを少なくした

議論はある?

  • 複数のbroker間でのメッセージレプリケーションをbuilt-inの機能として入れる
  • 幾つかのストリーム処理を組み込む
    • window countingとか
  • producerはbrokerのackを待たないので、全てのメッセージが送られていることを保証できない

次に読むべき論文は?

ZooKeeper: Wait-free coordination for Internet-scale systems