2015-07-03 14 views
16

Desidero utilizzare Avro per serializzare i dati per i miei messaggi Kafka e vorrei utilizzarlo con un repository di schemi Avro in modo da non dover includere lo schema con ogni messaggio.Apache Kafka con Avro e Schema Repo - dove nel messaggio viene inviato l'ID schema?

L'uso di Avro con Kafka sembra una cosa molto popolare da fare, e molti blog/Stack Overflow domande/gruppi di utenti ecc. Fanno riferimento all'invio dell'ID schema con il messaggio ma non riesco a trovare un esempio reale di dove dovrebbe andare.

Penso che dovrebbe andare nell'intestazione del messaggio Kafka da qualche parte ma non riesco a trovare un posto ovvio. Se fosse nel messaggio Avro dovresti decodificarlo rispetto a uno schema per ottenere il contenuto del messaggio e rivelare lo schema su cui devi decodificare, il che ha problemi evidenti.

Sto utilizzando il client C# ma un esempio in qualsiasi lingua sarebbe ottimo. La classe messaggio ha questi campi:

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; } 

ma non sembrano corretti. MessageMetaData ha solo Offset e PartitionId.

Quindi, dove dovrebbe andare l'ID schema Avro?

risposta

21

L'ID schema è effettivamente codificato nel messaggio avro stesso. Dai uno sguardo allo this per vedere come vengono implementati gli encoder/decodificatori.

In generale quello che succede quando si invia un messaggio di Avro a Kafka:

  1. L'encoder ottiene lo schema dall'oggetto da codificare.
  2. Il codificatore richiede al registro schema un ID per questo schema. Se lo schema è già registrato otterrai un ID esistente, in caso contrario - il registro registrerà lo schema e restituirà il nuovo ID.
  3. L'oggetto viene codificato come segue: [byte magico] [id schema] [messaggio effettivo] dove il byte magico è solo un byte 0x0 che viene utilizzato per distinguere quel tipo di messaggi, l'id dello schema è un valore intero di 4 byte il resto è il vero messaggio codificato.

Quando si decodificare il messaggio di nuovo qui è quello che succede:

  1. Il decoder legge il primo byte e si assicura che è 0x0.
  2. Il decodificatore legge i 4 byte successivi e li converte in un valore intero. Ecco come viene decodificato l'id dello schema.
  3. Ora, quando il decodificatore ha un ID schema, può chiedere al registro dello schema lo schema effettivo per questo ID. Ecco!

Se la chiave è codificata Avro, la chiave sarà del formato sopra descritto. Lo stesso vale per il valore. In questo modo la chiave e il valore potrebbero essere entrambi valori Avro e utilizzare schemi diversi.

Modifica Per rispondere alla domanda in commento:

Lo schema attuale viene memorizzata nel repository schema (che è il punto centrale di repository schema in realtà - per memorizzare schemi :)). Il formato file contenitore oggetti di Avro non ha nulla a che fare con il formato descritto sopra.KafkaAvroEncoder/Decoder utilizzano un formato di messaggio leggermente diverso (ma i messaggi effettivi sono codificati esattamente nello stesso modo sicuro).

La differenza principale tra questi formati è che i file contenitore oggetto contengono lo schema effettivo e possono contenere più messaggi corrispondenti a tale schema, mentre il formato descritto sopra riporta solo l'id dello schema e esattamente un messaggio corrispondente a tale schema.

Il passaggio di messaggi codificati di file contenitore-oggetto attorno probabilmente non sarebbe ovvio da seguire/mantenere poiché un messaggio di Kafka conterrebbe quindi più messaggi Avro. Oppure si potrebbe garantire che un messaggio di Kafka contenga solo un messaggio Avro, ma che risulterebbe nel trasportare lo schema con ciascun messaggio.

Gli schemi di Avro possono essere abbastanza grandi (ho visto schemi come 600 KB e più) e trasportare lo schema con ogni messaggio sarebbe davvero costoso e dispendioso, quindi è qui che entra in gioco il repository dello schema: lo schema viene recuperato una sola volta e viene memorizzato nella cache localmente e tutte le altre ricerche sono solo ricerche di mappe veloci.

+0

Ciao serejja, sai dov'è lo schema di codifica? La specifica su https://avro.apache.org/docs/1.7.7/spec.html parla di file contenitore oggetti contenenti lo schema completo ma non penso che questo sia lo stesso che descrivi. – jheppinstall

+0

@jheppinstall si prega di vedere la mia risposta aggiornata – serejja

+0

Grazie a @serejja, credo che la mia domanda fosse più simile a come i membri del Confluent decidono di usare [byte magico] [schema id] [messaggio effettivo] come formato del messaggio? lo hanno definito, o è specificato altrove? – jheppinstall

Problemi correlati