web-dev-qa-db-ja.com

Kafkaを使用したデータモデリング?トピックとパーティション

新しいサービス(非RDBMSデータストアやメッセージキューなど)を使用するときに最初に考えることの1つは、「データをどのように構成する必要があるか」です。

私はいくつかの入門資料を読んで見ました。具体的には、たとえば、 Kafka:ログ処理用の分散メッセージングシステム を使用します。

  • 「トピックは、メッセージが関連付けられているコンテナです」
  • 「並列処理の最小単位はトピックのパーティションです。これは、...トピックの特定のパーティションに属するすべてのメッセージが、コンシューマグループ内のコンシューマによって消費されることを意味します。」

これを知って、トピックとパーティションの使用方法を示す良い例は何でしょうか?いつトピックにすべきかいつパーティションにすべきか?

例として、私の(Clojure)データが次のようになっているとしましょう:

{:user-id 101 :viewed "/page1.html" :at #inst "2013-04-12T23:20:50.22Z"}
{:user-id 102 :viewed "/page2.html" :at #inst "2013-04-12T23:20:55.50Z"}

トピックはuser-idに基づいているべきですか? viewedat?パーティションはどうですか?

どうやって決めるの?

156
David J.

Kafkaのデータを構造化するとき、それが消費される方法に本当に依存します。

私の考えでは、トピックは同じタイプのメッセージのグループであり、同じタイプの消費者によって消費されるため、上記の例では、トピックが1つだけで、他の種類のメッセージをプッシュすることにした場合Kafkaを介してデータを取得する場合は、後で新しいトピックを追加できます。

トピックはZooKeeperに登録されています。つまり、トピックを追加しすぎると問題が発生する可能性があります。 100万人のユーザーがいて、ユーザーごとにトピックを作成することにした場合。

一方、パーティションはメッセージの消費を並列化する方法であり、ブローカクラスタ内のパーティションの総数は、パーティション化機能を理解するために、少なくともコンシューマグループ内のコンシューマの数と同じである必要があります。消費者グループの消費者は、パーティショニングに従ってトピックを処理する負担を自分自身に分割するため、1人の消費者は、パーティション自体のメッセージにのみ「割り当て」られることになります。

パーティショニングは、プロデューサー側でパーティションキーを使用して明示的に設定できます。指定しない場合は、メッセージごとにランダムパーティションが選択されます。

128
Lundahl

イベントストリームを分割する方法がわかったら、トピック名は簡単になるので、最初にその質問に答えましょう。

@Luddは正しいです-選択するパーティション構造は、イベントストリームの処理方法に大きく依存します。理想的には、イベント処理がpartition-localであることを意味するパーティションキーが必要です。

例えば:

  1. ユーザーの平均滞在時間を気にする場合は、:user-idで分割する必要があります。これにより、1人のユーザーのサイトアクティビティに関連するすべてのイベントが同じパーティション内で利用可能になります。つまり、 Apache Samza などのストリーム処理エンジンは、単一のパーティション内のイベントを見るだけで、特定のユーザーの平均オンサイト時間を計算できます。これにより、高価なpartition-global処理を実行する必要がなくなります。
  2. ウェブサイトで最も人気のあるページに関心がある場合は、:viewedページで分割する必要があります。繰り返しますが、Samzaは、単一のパーティション内のイベントを見るだけで、特定のページのビューのカウントを保持できます。

通常、グローバル状態(DynamoDBやCassandraなどのリモートデータベースでカウントを保持するなど)に依存することを避け、代わりにパーティションローカル状態を使用して作業できるようにしています。これは、 ローカル状態はストリーム処理の基本プリミティブ であるためです。

上記の両方のユースケースが必要な場合、Kafkaの一般的なパターンは、最初に:user-idでパーティションを作成し、次にre-partition by :viewed次の処理フェーズの準備ができました。

トピック名について-ここで明らかなものはeventsまたはuser-eventsです。具体的には、events-by-user-idおよび/またはevents-by-viewedを使用できます。

55
Alex Dean

これは質問とはまったく関係ありませんが、トピックに基づいてレコードの論理的な分離を既に決定しており、Kafkaでトピック/パーティションカウントを最適化する場合は、 this blogが便利です。

要点をまとめると:

  • 一般に、Kafkaクラスター内にパーティションが多いほど、達成できるスループットが高くなります。実稼働用の単一パーティションで達成可能な全体の最大値をpとし、消費量をc。目標スループットがtであるとしましょう。次に、少なくともmax(t/が必要ですpt/c)パーティション。

  • 現在、Kafkaでは、各ブローカーがすべてのログセグメントのインデックスとデータファイルの両方のファイルハンドルを開きます。そのため、パーティションが多いほど、基盤となるオペレーティングシステムで開くファイルハンドルの制限を構成する必要が高くなります。例えば。実稼働システムでは、too many files are openというエラーが一度表示されましたが、約3600のトピックパーティションがありました。

  • ブローカーが不意にシャットダウンされた場合(例:-9を強制終了)、観察された非可用性はパーティションの数に比例する可能性があります。

  • Kafkaのエンドツーエンドのレイテンシは、メッセージがプロデューサーによってパブリッシュされてからメッセージがコンシューマーによって読み取られるまでの時間によって定義されます。経験則として、遅延を気にする場合は、ブローカーごとのパーティション数を100 xbxrに制限することをお勧めします。 、ここでbはKafkaクラスター内のブローカーの数であり、rはレプリケーション係数。

5
Bitswazsky

トピック名は一種のメッセージの結論であり、プロデューサーはトピックにメッセージを発行し、コンシューマーはサブスクライブトピックを通じてメッセージをサブスクライブします。

トピックには多くのパーティションがあります。パーティションは並列処理に適しています。パーティションは複製の単位でもあるため、Kafkaでは、リーダーとフォロワーはパーティションのレベルでも言われます。実際には、パーティションは順序付けされたキューであり、その順序はメッセージが到着した順序です。そして、トピックは単純なWordの1つ以上のキューで構成されます。これは、構造をモデル化するのに役立ちます。

Kafkaは、ログの集約と配信のためにLinkedInによって開発されました。このシーンは例として非常に良いです。

Webまたはアプリでのユーザーのイベントは、Webサーバーによって記録され、プロデューサーを介してKafkaブローカーに送信されます。プロデューサーでは、たとえば、イベントタイプ(異なるイベントは異なるパーティションに保存されます)またはイベント時間(アプリロジックに応じて1日を異なる期間にパーティションする)またはユーザータイプまたはロジックなしですべてのログのバランスを取るなど、パーティションメソッドを指定できます多くのパーティションに。

問題のケースについては、「page-view-event」というトピックを1つ作成し、ハッシュキーを使用してN個のパーティションを作成して、ログをすべてのパーティションに均等に分散できます。または、パーティションロジックを選択して、自分のスピリットでログを配布することもできます。

4
GuangshengZuo