web-dev-qa-db-ja.com

Kafkaへのメッセージ送信の一部としてキーが必要ですか?

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

現在、キー付きメッセージの一部としてキーなしでメッセージを送信していますが、delete.retention.msでも引き続き機能しますか?メッセージの一部としてキーを送信する必要がありますか?これはメッセージの一部としてキーを作成するのに適していますか?

70
gaurav

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

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

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

つまり、 log compaction を有効にした場合、または同じキーを持つメッセージに厳密な順序が必要な場合は、必ずキーを使用する必要があります。それ以外の場合、nullキーはより良い配布を提供し、一部のキーが他のキーよりも多く表示される可能性がある場合の潜在的なホットスポットの問題を防ぐことができます。

130
kuujo