Gobernar el dato usando Kafka y Apache Avro

Publicado por Jose Maria Hidalgo Garcia el

Arquitectura de SolucionesKafkaApache Avro

En las arquitecturas orientadas a eventos los datos contenidos en dichos eventos también requieren ser gobernados. En este post, vamos a ver cómo usando esquemas de datos, podemos conseguir gestionar el dato en arquitecturas basadas en Kafka, gracias a Apache Avro.

Introducción

Hoy en día el volumen de información que se produce y consume no para de crecer, por esta razón, es importante adquirir conciencia sobre el uso de esquemas de datos. Con el objetivo de centralizar y ofrecer más control sobre el dato.

Al usar un esquema de datos se hace responsable al propietario del dato de definir la compatibilidad (backward o forward) del esquema, aliviando de tareas de validación a los consumidores y productores que usen dicho dato.

Por ejemplo, cuando se usa JSON para compartir la información, la compatibilidad de ese dato es "backward" por defecto. Porque cuando se introduce un nuevo campo, los consumidores antiguos lo ignoran. Pero en mi opinión esto no es del todo correcto, porque esos consumidores deberían fallar a existir un nuevo campo que no es reconocido. Esta es una posible razón para empezar a usar esquemas y su proceso de validación.

Los esquemas se usan cuando se lee y escriben los datos. Los esquemas deben ser compartidos entre los servicios que envían el dato y el que los consumen. Ya sea para el uso de esquemas JSON o Avro se necesita un recurso global donde gobernar el dato.

Como ya se ha visto en entradas anteriores en el blog, Kafka es un software para el transporte de datos entre servicios y aplicaciones. Bastante común al presentar muy buen rendimiento, fácil de usar y que hace sencillo un diseño reduciendo el acoplamiento.

Apache Kafka ha evolucionado mucho en estos últimos años, convirtiéndose en una plataforma de Streaming de Datos. Donde destacan los siguientes productos:

  • Kafka Streams: Para transformar un stream de datos y republicarlos otra vez en un topic de Kafka
  • Kafka Connect: Para recibir (Source) datos desde una fuente externa (Elasticsearch, Mongo, IBM MQ, PostgreSQL, ...). También en el sentido inverso, enviar (Sink) datos a una fuente externa.
  • Schema Registry

Avro

Apache Avro viene del mundo de Hadoop donde existía la necesidad de guardar, transportar y realizar queries de forma eficiente al incorporar un control de versiones sobre el dato.

Sin entrar en muchos detalles, Avro es eficiente dado que:

  • Contiene solo datos: no hay nombres de campos, no hay ruido, solo datos en crudo.
  • Es un formato binario, pero existen herramientas para leer ficheros ".avro" o mensajes que pasan por Kafka. Como por ejemplo avro-tools.jar o kafka-avro-console-consumer dentro de Confluent Platform.
  • El esquema nunca va dentro del mensaje, sólo va el "SchemaID". En el momento de la deserialización del mensaje, a partir de ese "SchemaID" se obtiene el esquema desde el Schema Registry y se cachea.

Pero Avro es más:

  • Soporta compresión como Google’s Snappy
  • Soporta deserialización parcial, no deserializa todo sólo la  columna solicitada.
  • No es un almacenamiento por columnas como Parquet, que dispone de una mejor compresión y soporta predicado de inserción. Pero Avro se adapta mejor a grandes fragmentos de datos.

Puedes consultar más información de las diferencias en esta presentación File Format Benchmark - Avro, JSON, ORC & Parquet

Schemas

Un esquema no es solo una lista de nombres de campos. Contiene la metainformación de cada campo: descripción, tipo y alias.

Suponer una clase Java User:

public class User {  
    long id;
    String name;
}

La representación de esa clase como esquema Avro, que es un fichero de texto escrito en JSON sería la siguiente:

{
  "type": "record",
  "name": "User",
  "fields" : [
    {"name": "id", "type": "long"},
    {"name": "name", "type": "string"}
  ]
}

Avro propone los siguientes tipos: int, string, boolean, enums, arrays, maps y tambien null. Que debe especificarse. El tipo String no es null por defecto. Puede consultar más información en la documentación oficial de tipos Avro.

Como JSON, Avro es agnóstico. Cualquier lenguaje puede enviar y leer mensajes en formato Avro si disponen del esquema.

El esquema se puede versionar y distribuir considerándolo como un fuente más. Que debe ser compartido entre los proyectos. Porque a partir del esquema se debe compilar (generar los fuentes) para el lenguaje con el que se va a programar el consumidor o productor.

Recapitulando

Esta entrada no pretende ser algo obligatorio de hacer para un correcto gobierno del dato, pero el uso de esquema se puede incorporar de forma fácil y rápida si estamos usando Kafka.

Combinar Kafka y Avro proporciona:

  • Un desacoplamiento total entre consumidores y productores. Debido a que los servicios no necesitan conocer quien consumen los datos que produce.
  • Gobierno: con el Schema Registry los equipos pueden consultar los tipos de datos disponibles y sus esquemas asociados. No se necesita preguntar a otros equipos cual es el formato de los datos que están generando.
  • Que no se pueden inyectar datos incorrectos, que podrían romper los servicios consumidores.

En los siguientes artículos de esta serie se abordarán ejemplos de código con casos de uso reales. Sigue atento a nuestra cuenta de Twitter, ¡hasta pronto!.

Autor

Jose Maria Hidalgo Garcia

Arquitecto software y apasionado por todo lo que rodea al movimiento DevOps. Me encanta el terminal y tener todo automatizado en los proyectos en los que participo.
Twitter: @jhidalgo3