Desde la implantación de los sistemas de información, la mayoría de las empresas se han orientado a cubrir casos de uso muy específicos, que permiten cumplir con las necesidades del momento, sin tener en cuenta una visión global de la información.

Este enfoque ha provocado que dichas empresas se hayan encontrado en la situación de tratar con un conjunto complejo de sistemas desacoplados, donde el acceso y el uso de la información por parte de sistemas externos a ellos mismos resulta muy difícil, o prácticamente imposible. En definitiva, sistemas con nula capacidad de integración.

Dada esta situación, es común enfrentarse a una serie de situaciones problemáticas que reducen la competitividad de una empresa:

Existen distintos enfoques que permiten atacar el problema de integración de los sistemas, ofreciendo distintas características para evitar este tipo de situaciones.

El enfoque que se va a tratar es el basado en CDC (Change Data Capture), cada vez más popular en las compañías que buscan sacar mayor rédito de su información. La idea detrás de CDC es la de detectar los cambios que ocurren en las bases de datos, de manera no intrusiva, y transmitirlos de forma inmediata para poder actuar con esa información.

Este enfoque proporciona una serie de beneficios que lo hace muy interesante como manera de paliar la falta de integración de los sistemas:

Implementar soluciones de CDC ayuda a las empresas a ser más competitivas ya que les permite integrar, manejar y analizar la información de una manera más rápida y eficiente.

En este artículo, vamos a profundizar sobre una de las tecnologías para CDC que, bajo nuestro punto de vista, es una de las más sencillas de implementar: Debezium.

¿Qué es Debezium?

Debezium es un proyecto de RedHat formado por un conjunto de servicios distribuidos de código abierto que permite detectar y transmitir, como flujos de eventos, los cambios que ocurren en una base de datos, con la finalidad de que otras aplicaciones puedan ver y responder a cada cambio producido de forma inmediata.

La solución CDC implementada con Debezium está basada en los logs transaccionales de las bases de datos (log-based), lo que proporciona una serie de características que hacen muy interesante a esta tecnología en lugar de otro tipo de enfoques.

Arquitectura

El componente principal de Debezium son los conectores, que permiten monitorizar los cambios producidos en una base de datos. Debezium ofrece un conjunto de conectores para poder actuar sobre distintos tipos de bases de datos, como MySQL, Postgres, Oracle, DB2 …

Para implementar una solución CDC con Debezium que sea eficiente y confiable, los conectores deben apoyarse en otras tecnologías que ayuden a transmitir los eventos de cambio que detectan en la base de datos que monitorizan.

El uso más extendido es implementar Debezium mediante Kafka Connect, ya que los conectores Debezium son totalmente compatibles con esta tecnología, y se apoyan de la capacidad de Kafka Connect para transmitir datos a Apache Kafka de manera eficiente, escalable y confiable.

Por otro lado, el equipo de Debezium se encuentra desarrollando una nueva funcionalidad que permite implementar Debezium mediante Debezium Server, basado en usar directamente una aplicación servidor totalmente configurable, en la que bastaría indicar el tipo de origen y destino para empezar a detectar y transmitir información a una gran variedad de infraestructuras de mensajería.

Para finalizar, mencionar que existe otra alternativa al uso de conectores Debezium, que es el uso de embedded engine, que consiste en una biblioteca que se integra en aplicaciones Java. Aunque proporciona poca flexibilidad, esta posibilidad existe ya que no todas las aplicaciones necesitan el nivel de tolerancia a fallos y confiabilidad que obtenemos con los conectores Debezium o que no se quiera depender de servicios externos como Kafka Connect.

Este artículo se va a centrar en implementar un conector Debezium mediante Kafka Connect, ya que es la manera más flexible y estable para poder usarla en un entorno productivo.

Características

Una vez conocida la arquitectura y los principales componentes que la forman, se puede observar que Debezium tiene una clara naturaleza distribuida, por lo que posee las ventajas de los sistemas distribuidos.

En este tipo de soluciones, minimizar el riesgo en la pérdida de la información resulta extremadamente importante, por lo que Debezium está especialmente focalizado en ofrecer tolerancia a fallos. De hecho, apoyarse en otros componentes distribuidos para su uso, como pueden ser Apache Kafka y Kafka Connect, permite aprovecharse de todas sus características.

Por otro lado, Debezium proporciona una solución CDC basada en los logs transaccionales de las bases de datos. Este enfoque resulta clave respecto otros enfoques de soluciones CDC muy comunes, como los basados en consultas o sondeo, ya que permite reaccionar a cualquier cambio en los ficheros de logs (binlog de MySQL, registro de operaciones de MongoDB, etc.), ofreciendo una serie de características muy interesantes que veremos a continuación:

Al leer los logs transaccionales, Debezium obtiene una lista completa con todos los cambios que se han producido, en su orden exacto de aplicación. Esto resulta muy interesante para casos de uso en los que se necesite el historial completo de los cambios producidos.

Otro tipo de enfoques, como los enfoques basados en consultas, pueden perder cambios intermedios, ya que se quedan con el estado en el momento de realizar la consulta (puede darse el caso de que un registro se haya creado y eliminado entre una consulta y otra, por lo que no es capturado).

El enfoque basado en los logs transaccionales permite reaccionar casi en tiempo real a los cambios que se producen en la base de datos, por lo que Debezium tiene muy baja latencia en la propagación de los cambios y no afecta al rendimiento de la base de datos que monitoriza, sin penalizar a la CPU.

El enfoque basado en consultas suele afectar al rendimiento de la base de datos, ya que para tener poca latencia, suele aumentar la frecuencia de consultas por rango de tiempo, provocando un mayor uso de CPU. Si se disminuye la frecuencia de consultas, la latencia en la captura de los cambios en la base de datos es mayor, provocando retrasos en la propagación de los cambios y eventos perdidos.

El enfoque basado en consultas necesita que la base de datos tenga alguna marca de tiempo en sus tablas que les permita identificar aquellos registros que se han modificado desde la última consulta. Esto supone que haya que hacer un mantenimiento extra en el modelo de la base de datos. Con Debezium, y su enfoque basado en logs transaccionales, no impacta en el modelo de datos.

Debezium proporciona el estado antiguo de los registros en los procesos de actualización y eliminación y un conjunto de metadatos adicionales sobre el cambio producido, ofreciendo un mayor conocimiento y más flexibilidad a la hora de tratar con esa información. Una solución con un enfoque basado en consultas sólo obtendrá el estado actual de la fila.

Hay que tener en cuenta que esto no quiere decir que otros enfoques para crear soluciones CDC no tengan su necesidad o aplicación. Puede haber casos de uso que pueden ser resueltos de otra manera (como la propagación de datos cada cierto tiempo en los que los estados intermedios no importan), pero si se está interesado en capturar los cambios casi en tiempo real y sin perdida de eventos, Debezium le permite hacerlo.

Funcionamiento

Se ha definido que los conectores son el componente principal de Debezium. Cada tipo de conector se adapta al tipo de base de datos que quiere monitorizar, ya que la forma de detectar los cambios varía dependiendo del tipo.

Para entender mejor cómo funciona un conector Debezium, se va a mostrar el funcionamiento de un conector para una base de datos MySQL, ya que es una de las bases de datos relacionales más extendidas y más fácil de usar. Eso sí, gran parte de lo que se va a mostrar para este conector es extensible a la gran mayoría de conectores Debezium existentes para otras bases de datos, como pueden ser Postgres, MongoDB, etc.

MySQL registra todas las transacciones realizadas en la base de datos a través de un registro binario (binlog), diseñado en su origen para realizar tareas de replicación y recuperación de los datos. El conector Debezium MySQL lee este registro, genera los eventos de cambio de datos y los envía a la infraestructura de mensajería definida, en este caso, Apache Kafka.

Para permitir que el conector pueda leer el registro binario, es necesario configurar MySQL de forma que habilite su funcionamiento, lo configure de la forma correcta y que se use un usuario que permita su lectura.

Es importante tener en cuenta que cada tipo de base de datos requiere una configuración distinta, por lo que antes de usar un conector para una base de datos concreta, hay que asegurarse de permitir la lectura de los logs transaccionales.

El conector Debezium transmite los eventos con información detallada acerca del cambio producido en la base de datos. Esto implica que los eventos que se producen suelen ser de gran tamaño.

Un evento, simplificado y producido por el conector Debezium, se ve de la siguiente manera:

{
  "schema": {
    "type": "struct",
    "fields": [],
    "optional": false,
    "name": "dbserver.database1.table1.Envelope"
  },
  "payload": {
    "before": {},
    "after": {},
    "source": {},
    "op": "c",
    "ts_ms": 1618681673399,
    "transaction": null
  }
}

Los eventos de cambio de datos producidos por el conector se organizan de forma que, por cada tabla del modelo de datos, exista un topic asociado a dicha tabla. Por tanto, todos los eventos de cambio que se producen en una determinada tabla se envían a su topic asociado.

Los topics se crean de forma automática, en caso de no estar creados, en Apache Kafka por parte del conector en el momento del arranque, ya que detecta el modelo de datos y es capaz de crear los topics necesarios. Por defecto, si no se define en el fichero de configuración, sigue el siguiente patrón: dbserver.database.table

Esta manera de organización ofrece la característica de que todos los eventos de cambio dentro de un topic están totalmente ordenados, por lo que se mantendrá el orden de los eventos de cambio producidos en la base de datos.

El conector Debezium no solo detecta cambios a nivel de fila en los datos, sino también las declaraciones DDL que se aplican a la base de datos (creación de tablas, modificación de tablas, etc.). Los eventos de cambio producidos son enviados a un topic genérico, dbserver, siguiendo una estructura similar a la mostrada anteriormente.

{
   "schema": {},
   "payload": {
      "databaseName": "database1",
      "ddl": "CREATE TABLE table1 ...",
      "source": {}
   }
}

Para que el conector Debezium pueda enviar los eventos a Apache Kafka, es necesario usar la utilidad de Kafka Connect.

En la parte de arquitectura, se ha mostrado la necesidad de que los conectores de Debezium se integren con Kafka Connect para poder implementar una solución CDC completa que permita enviar los eventos producidos por el conector Debezium a Apache Kafka.

Como se ha adelantado anteriormente, los conectores Debezium son totalmente compatibles con Kafka Connect, por lo que simplemente hay que registrar el conector en el servicio Kafka Connect para permitir su uso. Para ello, se necesita definir la configuración del conector Debezium necesaria para empezar a monitorizar la base de datos. En este caso, para MySQL:

{
  "name": "inventory-connector",
   "config": {
      "connector.class": "io.debezium.connector.mysql.MySqlConnector",
      "tasks.max": "1",
      "database.hostname": "mysql",  
      "database.port": "3306",
      "database.user": "user",
      "database.password": "password",
      "database.server.id": "184054",  //
      "database.server.name": "dbserver",  
      "database.include.list": "database1",  
      "database.history.kafka.bootstrap.servers": "kafka:9092",  
      "database.history.kafka.topic": "schema-changes.database1"  
   }
}

El conector Debezium permite configurar todas las características de transformación o filtrado de Kafka Connect y aplicarlos a los distintos eventos producidos, de forma que los eventos enviados a Apache Kafka puedan ser formateados según la necesidad requerida.

Una vez definida la configuración, se usa la API que proporciona el servicio de Kafka Connect para enviar una solicitud de registro con la configuración deseada.

curl -i -X POST -H "Accept:application/json" -H "Content-Type:application/json" localhost:8083/connectors/ -d @config-file.json

En el momento que se registra el conector Debezium en Kafka Connect, el conector se inicializa y empieza a monitorizar la base de datos configurada. De esta forma, ya se podrían capturar los cambios producidos en la base de datos y actuar en consecuencia.

En este primer post hemos visto las características de Debezium, sus componentes y su funcionamiento. ¿Quieres aprender a utilizar esta herramienta? En nuestro próximo artículo te contamos cómo aplicarla a un caso de uso muy común para este tipo de tecnologías: la replicación de bases de datos en tiempo real.

Referencias

Cuéntanos qué te parece.

Los comentarios serán moderados. Serán visibles si aportan un argumento constructivo. Si no estás de acuerdo con algún punto, por favor, muestra tus opiniones de manera educada.

Suscríbete

Estamos comprometidos.

Tecnología, personas e impacto positivo.