Apache Kafka z Avro i Schema Repo-gdzie w wiadomości znajduje się Id schema?

Chcę użyć Avro do serializacji danych dla moich wiadomości Kafka i chciałbym używać go z repozytorium schematu Avro, więc nie muszę dołączać schematu do każdej wiadomości.

Używanie Avro z Kafką wydaje się być popularną rzeczą do zrobienia, a wiele blogów / pytań o przepełnienie stosu / grup użytkowników itp. odwołuje się do wysyłania identyfikatora schematu z wiadomością, ale nie mogę znaleźć rzeczywistego przykładu, gdzie powinien się udać.

Myślę, że powinno się to gdzieś znaleźć w nagłówku wiadomości Kafka, ale ja nie mogę znaleźć oczywistego miejsca. Jeśli to było w wiadomości Avro będziesz musiał dekodować go według schematu, aby uzyskać zawartość wiadomości i ujawnić schemat, który musisz dekodować, co ma oczywiste problemy.

Używam klienta C#, ale przykład w dowolnym języku byłby świetny. Klasa message posiada następujące pola:

public MessageMetadata Meta { get; set; }
public byte MagicNumber { get; set; }
public byte Attribute { get; set; }
public byte[] Key { get; set; }
public byte[] Value { get; set; }
Ale żadna z nich nie wydaje się poprawna. MessageMetaData ma tylko Offset i Partionid.

Więc, gdzie powinien iść Id schematu Avro?

Author: jheppinstall, 2015-07-03

1 answers

Identyfikator schematu jest zakodowany w samej wiadomości avro. Spójrz na to {[4] } aby zobaczyć, jak Enkodery/dekodery są zaimplementowane.

Ogólnie co się dzieje kiedy wysyłasz wiadomość Avro do Kafki:

  1. koder pobiera schemat z obiektu do zakodowania.
  2. koder prosi rejestr schematu o id dla tego schematu. Jeśli schemat jest już zarejestrowany, otrzymasz istniejący identyfikator, jeśli nie - rejestr zarejestruje schemat i zwróci nowy dowód.
  3. obiekt jest zakodowany w następujący sposób: [magic byte] [schema id] [actual message] gdzie magic byte jest tylko bajtem 0x0, który jest używany do rozróżniania tego rodzaju wiadomości, schema id jest 4-bajtową wartością całkowitą reszta jest rzeczywistą zakodowaną wiadomością.

Kiedy odkodujesz wiadomość z powrotem oto co się dzieje:

  1. dekoder odczytuje pierwszy bajt i upewnia się, że jest to 0x0.
  2. dekoder odczytuje kolejne 4 bajty i konwertuje je na wartość całkowitą. W ten sposób dekodowany jest identyfikator schematu.
  3. Teraz, gdy dekoder ma identyfikator schematu, może poprosić rejestr schematu o rzeczywisty schemat dla tego identyfikatora. Voila!

Jeśli twój klucz jest zakodowany w formacie Avro, Twój klucz będzie miał format opisany powyżej. To samo dotyczy wartości. W ten sposób klucz i wartość mogą być zarówno wartościami Avro, jak i używać różnych schematów.

Edit Aby odpowiedzieć na pytanie w komentarzu:

Rzeczywisty schemat jest przechowywany w repozytorium schematu (czyli cały sens repozytorium schematów właściwie-do przechowywania schematów :)). Format Avro Object Container Files nie ma nic wspólnego z formatem opisanym powyżej. KafkaAvroEncoder / Dekoder używa nieco innego formatu wiadomości (ale rzeczywiste wiadomości są zakodowane dokładnie w ten sam sposób).

Główną różnicą między tymi formatami jest to, że pliki kontenerów obiektów zawierają rzeczywisty schemat i mogą zawierać wiele komunikatów odpowiadających temu schematowi, podczas gdy format opisany powyżej zawiera tylko identyfikator schematu i dokładnie jeden komunikat odpowiadający temu schematowi.

Przekazywanie komunikatów zakodowanych przez obiekt-kontener-plik prawdopodobnie nie byłoby oczywiste, aby śledzić/utrzymywać, ponieważ jedna wiadomość Kafka zawierałaby wtedy wiele komunikatów Avro. Możesz też upewnić się, że jedna wiadomość Kafka zawiera tylko jedną wiadomość Avro, ale spowodowałoby to przenoszenie schematu z każdą wiadomością.

Schematy Avro mogą być dość duże (widziałem Schematy takie jak 600 KB i więcej) i przenoszenie schemat z każdą wiadomością byłby bardzo kosztowny i marnotrawny, więc to jest miejsce, w którym repozytorium schematu kopie - schemat jest pobierany tylko raz i jest buforowany lokalnie, a wszystkie inne lookups są tylko map lookups, które są szybkie.

 23
Author: serejja,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-04 17:01:52