非常に役立つ承認された回答に加えて、もう少し詳細を追加したいと思います
パーティショニング
デフォルトでは、Kafkaはメッセージのキーを使用して、書き込み先のトピックのパーティションを選択します。これは次のような方法で行われます
hash(key) % number_of_partitions
キーが提供されない場合、Kafkaはデータをランダムにラウンドロビン方式で分割します。
ご注文
与えられた回答で述べたように、Kafkaはパーティションレベルでのみメッセージの順序付けを保証しています。
2つのパーティションを持つKafkaトピックに顧客の金融トランザクションを格納するとします。メッセージは(key:value)のようになります。
null:{"customerId": 1, "changeInBankAccount": +200}
null:{"customerId": 2, "changeInBankAccount": +100}
null:{"customerId": 1, "changeInBankAccount": +200}
null:{"customerId": 1, "changeInBankAccount": -1337}
null:{"customerId": 1, "changeInBankAccount": +200}
キーを定義していないため、2つのパーティションはおそらく次のようになります。
// partition 0
null:{"customerId": 1, "changeInBankAccount": +200}
null:{"customerId": 1, "changeInBankAccount": +200}
null:{"customerId": 1, "changeInBankAccount": +200}
// partition 1
null:{"customerId": 2, "changeInBankAccount": +100}
null:{"customerId": 1, "changeInBankAccount": -1337}
そのトピックを読んでいる消費者は、アカウントの残高が特定の時間に600であると言ってしまう可能性があります。パーティション1のメッセージの前に、パーティション0のすべてのメッセージを読み取っていたからです。
意味のあるキー(customerIdなど)を使用すると、パーティショニングが次のようになるため、これを回避できます。
// partition 0
1:{"customerId": 1, "changeInBankAccount": +200}
1:{"customerId": 1, "changeInBankAccount": +200}
1:{"customerId": 1, "changeInBankAccount": -1337}
1:{"customerId": 1, "changeInBankAccount": +200}
// partition 1
2:{"customerId": 2, "changeInBankAccount": +100}
ログ圧縮
メッセージの一部としてキーがないと、トピック構成cleanup.policy
をに設定できませんcompacted
。ドキュメントによると、「ログ圧縮により、Kafkaは常に、少なくとも1つのトピックパーティションのデータのログ内の各メッセージキーの最後の既知の値を保持します。」
この便利で便利な設定は、キーがないと使用できません。
キーの使い方
実際の使用例では、Kafkaメッセージのキーは、パフォーマンスとビジネスロジックの明確さに大きな影響を与える可能性があります。
たとえば、キーはデータを分割するために自然に使用できます。特定のパーティションから読み取るようにコンシューマーを制御できるため、これは効率的なフィルターとして役立ちます。また、キーには、後続の処理の制御に役立つメッセージの実際の値に関するメタデータを含めることができます。キーは通常値よりも小さいため、値全体ではなくキーを解析する方が便利です。同時に、すべてのシリアライゼーションとスキーマ登録を、キーと一緒に値を使用して行うように適用できます。
注意として、情報を格納するために使用できるヘッダーの概念もあります。ドキュメントを参照してください。