146
KeyedMessage<String, byte[]> keyedMessage = new KeyedMessage<String, byte[]>(request.getRequestTopicName(), SerializationUtils.serialize(message)); 
producer.send(keyedMessage);

現在、キー付きメッセージの一部としてキーなしでメッセージを送信していますが、それでも動作しdelete.retention.msますか? メッセージの一部としてキーを送信する必要がありますか? メッセージの一部としてキーを作成するのはこれでよいでしょうか?

4

3 に答える 3

247

キーに強い順序が必要で、ステート マシンのようなものを開発している場合、キーはたいてい便利/必要です。同じキー (一意の ID など) を持つメッセージが常に正しい順序で表示されるようにする必要がある場合は、キーをメッセージに添付すると、同じキーを持つメッセージが常にトピック内の同じパーティションに送信されるようになります。Kafka はパーティション内の順序を保証しますが、トピック内のパーティション間では保証しません。そのため、代わりにキーを提供しないと (結果としてパーティション間でラウンドロビン分散が行われます)、そのような順序は維持されません。

ステート マシンの場合、log.cleaner.enableでキーを使用して、同じキーでエントリを重複排除できます。その場合、Kafka は、アプリケーションが特定のキーの最新のインスタンスのみを考慮し、ログ クリーナーが特定のキーの古い重複をキーが null でない場合にのみ削除すると想定します。この形式のログ圧縮はlog.cleaner.delete.retentionプロパティによって制御され、キーが必要です。

または、デフォルトで有効になっているより一般的なプロパティlog.retention.hoursは、古くなったログの完全なセグメントを削除することによって機能します。この場合、キーを提供する必要はありません。Kafka は、指定された保持期間よりも古いログのチャンクを単純に削除します。

つまり、ログの圧縮を有効にしている場合、または同じキーを持つメッセージに厳密な順序が必要な場合は、間違いなくキーを使用する必要があります。それ以外の場合は、null キーを使用すると、分散が向上し、一部のキーが他のキーよりも多く表示される可能性がある場合に、潜在的なホット スポットの問題を防ぐことができます。

于 2015-04-08T13:14:04.767 に答える
1

メッセージ付きのキーは基本的に、特定のフィールドのメッセージ順序を取得するために送信されます。

  • key=null の場合、データはラウンド ロビンで送信されます (分散環境内の別のパーティションと別のブローカー、そしてもちろん同じトピックに)。
  • キーが送信された場合、そのキーのすべてのメッセージは常に同じパーティションに送信されます。

説明と例

  • キーは任意の文字列または整数などにすることができます。キーとして整数の employee_id の例を取り上げます。
  • したがって、emplyee_id 123 は常にパーティション 0 に移動し、emplyee_id 345 は常にパーティション 1 に移動します。これは、パーティションの数に依存するキー ハッシュ アルゴリズムによって決定されます。
  • キーを送信しない場合、メッセージはラウンドロビン手法を使用して任意のパーティションに送信できます。
于 2020-09-28T10:00:26.020 に答える