Oprócz bardzo pomocnej zaakceptowanej odpowiedzi chciałbym dodać kilka dodatkowych szczegółów
Partycjonowanie
Domyślnie Kafka używa klucza wiadomości do wybrania partycji, do której pisze. Odbywa się to w DefaultPartitioner
By
kafka.common.utils.Utils.toPositive(Utils.murmur2(keyBytes)) % numPartitions;
Jeśli nie zostanie dostarczony żaden klucz, Kafka podzieli dane losowo w sposób okrężny.
W Kafce możliwe jest stworzenie własnego Partitionera poprzez rozszerzenie Partitioner
klasy. W tym celu musisz nadpisać partition
metodę, która ma podpis:
int partition(String topic,
Object key,
byte[] keyBytes,
Object value,
byte[] valueBytes,
Cluster cluster)
Zazwyczaj do wybrania partycji używany jest klucz wiadomości Kafka. Bez klucza musisz polegać na wartości, która może być znacznie bardziej złożona do przetworzenia.
Zamawianie
Jak podano w udzielonej odpowiedzi, Kafka ma gwarancje uporządkowania wiadomości tylko na poziomie partycji.
Załóżmy, że chcesz przechowywać transakcje finansowe swoich klientów w temacie Kafki z dwiema partycjami. Wiadomości mogą wyglądać następująco (klucz: wartość)
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}
Ponieważ nie zdefiniowaliśmy klucza, prawdopodobnie będą wyglądać dwie partycje
// 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}
Twój konsument czytający ten temat może w końcu powiedzieć Ci, że saldo na koncie wynosi 600 w określonym czasie, chociaż nigdy tak nie było! Tylko dlatego, że czytał wszystkie wiadomości w partycji 0 przed wiadomościami w partycji 1.
Dzięki rozsądnemu kluczowi (np. CustomerId) można tego uniknąć, ponieważ podział na partycje wyglądałby tak:
// 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}
Zagęszczanie kłód
Bez klucza jako części wiadomości nie będzie można ustawić konfiguracji tematu cleanup.policy
na compacted
. Zgodnie z dokumentacją „kompaktowanie dziennika zapewnia, że Kafka zawsze zachowa co najmniej ostatnią znaną wartość dla każdego klucza wiadomości w dzienniku danych dla jednej partycji tematu”.
To miłe i pomocne ustawienie nie będzie dostępne bez klucza.
Korzystanie z kluczy
W rzeczywistych przypadkach użycia klucz wiadomości Kafka może mieć ogromny wpływ na wydajność i przejrzystość logiki biznesowej.
Klucz może być na przykład naturalnie używany do partycjonowania danych. Ponieważ możesz kontrolować konsumentów, aby czytali z określonych partycji, może to służyć jako skuteczny filtr. Klucz może również zawierać metadane dotyczące rzeczywistej wartości wiadomości, które pomagają kontrolować dalsze przetwarzanie. Klucze są zwykle mniejsze niż wartości i dlatego wygodniej jest przeanalizować klucz zamiast całej wartości. W tym samym czasie możesz zastosować wszystkie serializacje i rejestrację schematu, tak jak zostało to zrobione z wartością, również z kluczem.
Uwaga: istnieje również koncepcja nagłówka, który może służyć do przechowywania informacji, patrz dokumentacja .