Apache Kafka avec Avro et Schema Repo-où va l'Id de schema dans le message?
Je veux utiliser Avro pour sérialiser les données pour mes messages Kafka et je voudrais l'utiliser avec un dépôt Avro schema donc je n'ai pas à inclure le schéma avec chaque message.
utiliser Avro avec Kafka semble comme une chose populaire à faire, et beaucoup de blogs / Stack Overflow questions / usergroups etc référence envoyer le schéma Id avec le message, mais je ne peux pas trouver un exemple réel de l'endroit où il devrait aller.
je pense qu'il devrait aller dans le Kafka en-tête de message quelque part mais je ne trouve pas un endroit évident. Si C'était dans le message Avro, vous auriez à le décoder contre un schéma pour obtenir le contenu du message et révéler le schéma que vous devez décoder contre, ce qui a des problèmes évidents.
j'utilise le client C# mais un exemple dans n'importe quelle langue serait génial. La classe message a ces champs:
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; }
mais aucune de celles-ci ne semble correcte. Le MessageMetaData a seulement Offset et PartitionId.
alors, où devrait l'Avro Schéma Id aller?
1 réponses
l'id du schéma est en fait encodé dans le message avro lui-même. Jetez un oeil à pour voir comment les encodeurs/décodeurs sont mis en œuvre.
en général ce qui se passe quand vous envoyez un message Avro à Kafka:
- l'encodeur récupère le schéma de l'objet à encoder.
- Encoder demande au registre du schéma un identifiant pour ce schéma. Si le schéma est déjà enregistré, vous obtiendrez un id existant, sinon - le registre s'enregistrera le schéma et la nouvelle carte d'identité.
- l'objet est codé comme suit: [magic byte][schema id] [message actuel] où magic byte est juste un
0x0
byte qui est utilisé pour distinguer ce genre de messages, schema id est une valeur entière de 4 bytes le reste est le message encodé réel.
Lorsque vous décoder le message de retour ici ce qui se passe:
- le décodeur lit le premier octet et s'assure qu'il est
0x0
. - Le décodeur lit les 4 octets et les convertit en une valeur entière. C'est ainsi que le schéma est décodé.
- lorsque le décodeur a un ID de schéma, il peut demander au registre de schéma le schéma réel pour cet id. Voila!
si votre clé est encodée Avro alors votre clé sera du format décrit ci-dessus. La même chose s'applique pour la valeur. De cette façon, votre clé et votre valeur peuvent être à la fois des valeurs Avro et utiliser des schémas différents.
Modifier pour répondre à la question en commentaire:
le schéma actuel est stocké dans le dépôt schema (c'est - à-dire le point entier du dépôt schema en fait-pour stocker les schémas :)). Le format de conteneur de fichiers objet Avro n'a rien à voir avec le format décrit ci-dessus. KafkaAvroEncoder / Decoder utilisent un format de message légèrement différent (mais les messages réels sont encodés exactement de la même façon sure).
la principale différence entre ces formats est que les fichiers de conteneur objet portent le réel schéma et peut contenir plusieurs messages correspondant à ce schéma, alors que le format décrit ci-dessus ne comporte que l'id du schéma et exactement un message correspondant à ce schéma.
passer des messages encodés objet-conteneur-fichier ne serait probablement pas évident à suivre/maintenir car un message Kafka contiendrait alors plusieurs messages Avro. Ou vous pouvez vous assurer qu'un message Kafka ne contient qu'un seul message Avro, mais cela aurait pour résultat de transporter le schéma avec chaque message.
les schémas Avro peuvent être assez grands (j'ai vu des schémas comme 600 Ko et plus) et transporter le schéma avec chaque message serait très coûteux et coûteux, donc c'est là que le dépôt de schéma entre en jeu - le schéma n'est récupéré qu'une seule fois et est mis en cache localement et toutes les autres recherches sont juste des mappages qui sont rapides.