apache-kafka avro

Apache Kafka con Avro y Schema Repo: ¿en qué parte del mensaje va la identificación del esquema?



apache-kafka (1)

Quiero usar Avro para serializar los datos de mis mensajes Kafka y me gustaría usarlo con un repositorio de esquemas Avro para no tener que incluir el esquema en cada mensaje.

El uso de Avro con Kafka parece ser algo popular, y muchos blogs / preguntas de desbordamiento de pila / grupos de usuarios, etc. remiten la identificación del esquema con el mensaje, pero no puedo encontrar un ejemplo real de dónde debería ir.

Creo que debería ir en el encabezado del mensaje Kafka en alguna parte, pero no puedo encontrar un lugar obvio. Si estuviera en el mensaje de Avro, tendría que descodificarlo contra un esquema para obtener el contenido del mensaje y revelar el esquema contra el que necesita descodificarse, lo cual tiene problemas obvios.

Estoy usando el cliente C # pero un ejemplo en cualquier idioma sería genial. La clase de mensaje tiene estos campos:

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

Pero ninguno de estos parece correcto. El MessageMetaData solo tiene Offset y PartitionId.

Entonces, ¿dónde debería ir la identificación del esquema de Avro?


El id del esquema está realmente codificado en el propio mensaje avro. Eche un vistazo a this para ver cómo se implementan los codificadores / decodificadores.

En general, qué sucede cuando envías un mensaje de Avro a Kafka:

  1. El codificador obtiene el esquema del objeto a codificar.
  2. El codificador solicita al registro de esquema una identificación para este esquema. Si el esquema ya está registrado, obtendrá una identificación existente; de ​​lo contrario, el registro registrará el esquema y devolverá la nueva identificación.
  3. El objeto se codifica de la siguiente manera: [byte mágico] [id de esquema] [mensaje real] donde el byte mágico es solo un byte 0x0 que se usa para distinguir ese tipo de mensajes, la identificación del esquema es un valor entero de 4 bytes, el resto es el real mensaje codificado.

Cuando decodifiques el mensaje, esto es lo que sucede:

  1. El decodificador lee el primer byte y se asegura de que sea 0x0 .
  2. El decodificador lee los siguientes 4 bytes y los convierte en un valor entero. Así es como se decodifica el id del esquema.
  3. Ahora, cuando el decodificador tiene un id de esquema, puede solicitar al registro de esquemas el esquema real para este id. Voila!

Si su clave está codificada en Avro, entonces su clave será del formato descrito anteriormente. Lo mismo se aplica para el valor. De esta manera, su clave y valor pueden ser tanto valores de Avro como usar esquemas diferentes.

Editar para responder la pregunta en el comentario:

El esquema real se almacena en el repositorio de esquemas (que es el punto entero del repositorio de esquemas en realidad - para almacenar esquemas :)). El formato de Avro Object Container Files no tiene nada que ver con el formato descrito anteriormente. KafkaAvroEncoder / Decoder utiliza un formato de mensaje ligeramente diferente (pero los mensajes reales están codificados exactamente de la misma manera).

La principal diferencia entre estos formatos es que los Archivos de Contenedor de Objetos llevan el esquema real y pueden contener múltiples mensajes correspondientes a ese esquema, mientras que el formato descrito anteriormente solo lleva la identificación del esquema y exactamente un mensaje correspondiente a ese esquema.

Pasar mensajes objeto-contenedor-archivo codificado probablemente no sería obvio seguir / mantener porque un mensaje Kafka contendría múltiples mensajes Avro. O puede asegurarse de que un mensaje Kafka contenga solo un mensaje Avro, pero que resulte en llevar un esquema con cada mensaje.

Los esquemas de Avro pueden ser bastante grandes (he visto esquemas como 600 KB y más) y llevar el esquema con cada mensaje sería realmente costoso y derrochador, de modo que es donde entra en juego el repositorio de esquemas: el esquema se recupera solo una vez y se almacena en caché localmente. y todas las demás búsquedas son solo búsquedas de mapas que son rápidas.