Schlüssel sind meistens nützlich / notwendig, wenn Sie eine starke Ordnung für einen Schlüssel benötigen und so etwas wie eine Zustandsmaschine entwickeln. Wenn Sie benötigen, dass Nachrichten mit demselben Schlüssel (z. B. einer eindeutigen ID) immer in der richtigen Reihenfolge angezeigt werden, wird durch Anhängen eines Schlüssels an Nachrichten sichergestellt, dass Nachrichten mit demselben Schlüssel immer an dieselbe Partition in einem Thema gesendet werden. Kafka garantiert die Reihenfolge innerhalb einer Partition, jedoch nicht über Partitionen in einem Thema hinweg. Wenn Sie also alternativ keinen Schlüssel angeben, was zu einer Round-Robin-Verteilung über Partitionen führt, wird diese Reihenfolge nicht beibehalten.
Im Fall einer Zustandsmaschine können Schlüssel mit log.cleaner.enable verwendet werden, um Einträge mit demselben Schlüssel zu deduplizieren . In diesem Fall geht Kafka davon aus, dass sich Ihre Anwendung nur um die letzte Instanz eines bestimmten Schlüssels kümmert und der Protokollbereiniger ältere Duplikate eines bestimmten Schlüssels nur löscht, wenn der Schlüssel nicht null ist. Diese Form der Protokollkomprimierung wird von der Eigenschaft log.cleaner.delete.retention gesteuert und erfordert Schlüssel.
Alternativ dazu löscht die standardmäßig aktivierte Eigenschaft log.retention.hours , die standardmäßig aktiviert ist, vollständige Segmente des Protokolls, die veraltet sind. In diesem Fall müssen keine Schlüssel angegeben werden. Kafka löscht einfach Teile des Protokolls, die älter als die angegebene Aufbewahrungsdauer sind.
Das ist alles zu sagen, wenn Sie die Protokollkomprimierung aktiviert haben oder eine strikte Reihenfolge für Nachrichten mit demselben Schlüssel benötigen, sollten Sie auf jeden Fall Schlüssel verwenden. Andernfalls bieten Nullschlüssel möglicherweise eine bessere Verteilung und verhindern potenzielle Hot-Spotting-Probleme, wenn einige Schlüssel häufiger als andere angezeigt werden.
ProducerRecord
Neben der sehr hilfreichen akzeptierten Antwort möchte ich noch einige Details hinzufügen
Partitionierung
Standardmäßig verwendet Kafka den Schlüssel der Nachricht, um die Partition des Themas auszuwählen, in das geschrieben wird. Dies geschieht durch so etwas wie
Wenn kein Schlüssel angegeben ist, partitioniert Kafka die Daten zufällig im Round-Robin-Verfahren.
Bestellung
Wie in der angegebenen Antwort angegeben, hat Kafka Garantien für die Bestellung der Nachrichten nur auf Partitionsebene.
Angenommen, Sie möchten Finanztransaktionen für Ihre Kunden in einem Kafka-Thema mit zwei Partitionen speichern. Die Nachrichten könnten so aussehen (Schlüssel: Wert)
Da wir keinen Schlüssel definiert haben, werden die beiden Partitionen vermutlich so aussehen
Ihr Verbraucher, der dieses Thema liest, könnte Ihnen am Ende mitteilen, dass der Kontostand zu einem bestimmten Zeitpunkt 600 beträgt, obwohl dies nie der Fall war! Nur weil alle Nachrichten in Partition 0 vor den Nachrichten in Partition 1 gelesen wurden.
Mit einem sinnvollen Schlüssel (wie customerId) könnte dies vermieden werden, da das Partitoning folgendermaßen aussehen würde:
Protokollverdichtung
Ohne Schlüssel als Teil Ihrer Nachrichten, werden Sie nicht in der Lage sein , das Thema Konfiguration einstellen
cleanup.policy
zucompacted
. Laut Dokumentation "stellt die Protokollkomprimierung sicher, dass Kafka immer mindestens den letzten bekannten Wert für jeden Nachrichtenschlüssel im Datenprotokoll für eine einzelne Themenpartition beibehält."Diese nette und hilfreiche Einstellung ist ohne Schlüssel nicht verfügbar.
Verwendung von Schlüsseln
In realen Anwendungsfällen kann der Schlüssel einer Kafka-Nachricht einen großen Einfluss auf Ihre Leistung und Klarheit Ihrer Geschäftslogik haben.
Ein Schlüssel kann zum Beispiel natürlich zum Partitionieren Ihrer Daten verwendet werden. Da Sie Ihre Konsumenten so steuern können, dass sie von bestimmten Partitionen lesen, kann dies als effizienter Filter dienen. Der Schlüssel kann auch einige Metadaten zum tatsächlichen Wert der Nachricht enthalten, mit denen Sie die nachfolgende Verarbeitung steuern können. Schlüssel sind normalerweise kleiner als Werte und es ist daher bequemer, einen Schlüssel anstelle des gesamten Werts zu analysieren. Gleichzeitig können Sie alle mit Ihrem Wert vorgenommenen Serialisierungen und Schema-Registrierungen auch mit dem Schlüssel anwenden.
Hinweis: Es gibt auch das Konzept des Headers , mit dem Informationen gespeichert werden können (siehe Dokumentation) .
quelle