Ir al contenido principal
Ingeniería

CDC basado en push en Unity Catalog con Zerobus Ingest y Debezium

Envía eventos de cambio desde el Debezium Server de código abierto directamente a las tablas Delta, sin necesidad de ejecutar un broker

por Victoria Bukta, Omkar Mehta y Wagner Santos

  • Debezium Server y Databricks Zerobus Ingest se combinan para transmitir eventos de CDC directamente a las tablas Delta de Unity Catalog a través de una arquitectura basada en push.
  • Las redes privadas con restricciones estrictas que bloquean las conexiones entrantes ahora pueden replicar datos de manera segura hacia el exterior, evitando la necesidad de intermediarios de mensajes Kafka o conectores basados en pull.
  • Las organizaciones pueden enviar cambios de bases de datos sin procesar hacia el lakehouse, simplificando drásticamente la infraestructura necesaria para crear tablas de estado actual para análisis posteriores.

Los datos en las bases de datos operativas impulsan las decisiones empresariales, y gran parte de ese análisis se realiza en el lakehouse. Llevar los datos allí es difícil cuando la base de datos se encuentra en una red corporativa privada, un entorno controlado por el cliente o una subred restringida cuyas políticas de red bloquean las conexiones entrantes desde servicios externos.

Muchos equipos necesitan sus cambios de PostgreSQL en Databricks, pero el equipo que administra la base de datos también quiere encargarse de la captura. Ese equipo ejecuta el proceso que lee el registro de transacciones (write-ahead log) y decide qué conexiones salen de su red. Por otro lado, los cambios llegan a tablas Delta gobernadas sobre las cuales los pipelines y los analistas pueden trabajar.

Debezium es una herramienta de código abierto común cuya implementación completa puede ser gestionada por los equipos para extraer un flujo de captura de datos modificados (CDC) de una base de datos. Se coloca junto a la base de datos, lee su registro de transacciones y envía eventos hacia el exterior. Zerobus Ingest es el destino, una interfaz de envío que escribe registros directamente en las tablas Delta de Unity Catalog. El conector (sink) de código abierto Debezium Server Zerobus une ambos elementos sin necesidad de utilizar un clúster de Kafka tradicional entre la captura y el lakehouse.

Los ingenieros de NVIDIA y Databricks se unieron para crear este conector y lo aportaron al proyecto de código abierto Debezium. Databricks creó el conector tipado de Zerobus Ingest. Luego, NVIDIA aportó el modo de sobre (envelope mode), que incluye el evento de cambio completo de Debezium junto con las garantías de entrega asociadas, como las claves de idempotencia y el reconocimiento dururable antes de que los offsets de origen avancen. El conector de Zerobus Ingest se incluye en la versión 3.7 de Debezium Server.

Esta publicación explica qué hacen Debezium y Zerobus, la estructura de cambios sin procesar que NVIDIA aportó al conector y cómo los eventos recibidos se convierten en tablas de estado actual o históricas. Para ver una guía práctica, que incluye una ejecución en vivo desde una tabla de PostgreSQL local hasta una tabla de estado actual, consulte el blog práctico complementario en la comunidad de Databricks. 

El desafío

Replicar los cambios de una base de datos operativa en el lakehouse de manera confiable requiere resolver varios problemas a la vez:

  • Capturar inserciones, actualizaciones y eliminaciones de forma confiable. Una fila que se crea, modifica y luego se elimina debe generar un flujo fiel para cada evento. Esto debe incluir las eliminaciones, que los enfoques basados en consultas de "copiar la tabla" suelen pasar por alto.
  • Conservar la evidencia necesaria para el ordenamiento. La lógica posterior que reconstruye el estado actual debe aplicar los cambios en el orden de origen para replicar correctamente la tabla de origen.
  • Evitar la sobrecarga de la base de datos de origen. Consultar la base de datos según una programación (SELECT ... WHERE updated_at > ?) añade carga de consultas y escala mal.
  • Trabajar con redes privadas o controladas por el cliente. Cuando la base de datos se encuentra detrás de un perímetro protegido, sabemos que puede ser difícil conectarse a estos sistemas e ingerir los datos.
  • Evitar configurar Kafka únicamente como transporte. Kafka es un bus de eventos potente, pero operar un clúster exclusivamente para mover eventos de CDC desde una base de datos hacia un lakehouse representa una sobrecarga significativa para los equipos que no lo necesitan para otros fines.
  • Ingresar los datos para que puedan procesarse fácilmente. El flujo de cambios debe llegar en un formato que el lakehouse pueda procesar y consultar, y no en un silo que requiera un paso de exportación adicional.

Dados estos requisitos, debemos comenzar por la arquitectura que define cómo fluirán los datos desde el origen hasta el destino.

Arquitectura de destino general

En este blog, exploraremos una arquitectura de bus de mensajes tradicional en comparación con una arquitectura que utiliza Zerobus Ingest.

Arquitectura con un bus de mensajes:
Arquitectura con un bus de mensajes: captura operada por el origen

En muchos entornos empresariales, la conectividad saliente desde el interior de un perímetro es mucho más fácil de permitir que el acceso entrante. Cuando su equipo desea ejecutar una implementación del agente que extrae el flujo de cambios, un modelo de envío local permite que los datos fluyan hacia el exterior con dirección a un destino. En una configuración tradicional, esto sería un bus de mensajes como Kafka. Ejecutar Kafka requiere recursos para la planificación de capacidad con el fin de predecir el número de brokers necesarios para manejar la carga máxima en el escalado físico, y para estimar el número de particiones para el escalado lógico, que los consumidores necesitan para mantenerse al día con la tasa de producción. Esto requiere un equipo dedicado con experiencia en la implementación y gestión de Kafka.

Una vez que los datos llegan a Kafka, tiene la siguiente tarea por cumplir, que consiste en replicar esos eventos en el lakehouse. Esto se puede hacer mediante la implementación de trabajos de ingesta como Spark, Kafka Connector u otras herramientas. El resultado es una arquitectura de dos saltos desde Debezium hasta el lakehouse.

Arquitectura con Zerobus Ingest:
Arquitectura con Zerobus Ingest: captura operada por el origen

Cuando su único destino es el lakehouse, Zerobus le permite evitar saltos intermedios como el bus de mensajes. Esto agiliza su arquitectura de extremo a extremo y elimina la necesidad de implementar y administrar la infraestructura de Kafka para el tránsito de datos. Al utilizar Zerobus como conector con Debezium, este continúa funcionando durante sus horas pico sin necesidad de ajustes.

¿Qué es Debezium?

Debezium es una plataforma de captura de datos modificados de código abierto basada en registros. En lugar de consultar tablas, lee el registro de transacciones de una base de datos, por ejemplo, el registro de transacciones (WAL) de PostgreSQL, el binlog de MySQL y los flujos de cambios de MongoDB. Luego, emite cada cambio como un evento estructurado. El proyecto comenzó en 2015 y hoy en día admite un amplio ecosistema de conectores (PostgreSQL, MySQL, SQL Server, Oracle, MongoDB y más).

Cada evento de cambio incluye una estructura coherente:

  • before — el estado de la fila antes del cambio (null para inserciones)
  • after — el estado de la fila después del cambio (null para eliminaciones)\
  • op — la operación: c (creación/inserción), u (actualización), d (eliminación), r (lectura/instantánea)
  • source — metadatos: base de datos, esquema, tabla, número de secuencia del registro WAL (LSN), ID de transacción, indicador de instantánea
  • ts_ms — marca de tiempo del evento

Debezium añade una carga mínima a la base de datos principal debido a su seguimiento de registros en lugar de realizar consultas para capturar cambios con baja latencia, y preserva el orden de confirmación.

Independiente (Debezium Server) frente a la implementación de Kafka Connect

Debezium tiene dos modelos operativos. Uno que se ejecuta en Kafka Connect y otro que es un "servidor independiente" (stand-alone server) que se puede configurar en recursos informáticos estándar.

 

Debezium en Kafka Connect

Debezium Server (independiente)

Entorno de ejecución

Complemento dentro de un clúster de Kafka Connect

Aplicación Quarkus independiente

Destino nativo

Apache Kafka (luego se envía a otros sistemas)

Directamente a destinos que no son Kafka mediante un adaptador de destino (sink). (Como Zerobus Ingest)

Cuándo usar

Kafka es tu bus de eventos principal; necesitas los trabajadores distribuidos, SMTs y registro de esquemas de Connect

No usas Kafka o quieres enviar CDC directamente a un destino diseñado para este propósito

Debezium Server, el entorno de ejecución independiente, actúa como el agente del lado del origen que rastrea los registros de transacciones y envía eventos de cambio directamente a Zerobus Ingest de Databricks, sin necesidad de un clúster de Kafka como medio de transporte.

La solución: Debezium + Zerobus Ingest

Ya hemos identificado a Debezium como nuestra herramienta de seguimiento de registros. Ahora necesitamos incorporar los eventos a Databricks.

Zerobus Ingest es un servicio de ingesta sin servidor (serverless) basado en inserciones que escribe datos directamente en tablas Delta gobernadas por Unity Catalog, sin necesidad de ejecutar un intermediario de mensajes. Los productores se conectan a un punto de enlace de Zerobus y transmiten registros que se almacenan en una tabla Delta de formato abierto. Está diseñado para gestionar cargas de trabajo de alto rendimiento y alta concurrencia. Al omitir el paso del intermediario de mensajes, podemos simplificar la arquitectura y el mantenimiento de tener que escalar y ejecutar canalizaciones de ingesta para mover los datos al lakehouse.

Al combinarlo con Debezium, tus canalizaciones de CDC se verán más o menos así:

  • Debezium observa el registro de la base de datos y convierte cada cambio en un evento de CDC.
  • Zerobus Ingest transporta esos eventos directamente a Databricks y los escribe en una tabla Delta, sin un clúster de Kafka como capa de transporte intermediaria.
  • Databricks recibe el flujo de cambios en una tabla Delta y puede procesarlo en tablas depuradas posteriores.

Zerobus Ingest solo permite la adición de datos (append-only). Una vez que llegan los eventos de cambio, el siguiente paso es construir una tabla dimensional de tipo 1 ejecutando una combinación (merge) para obtener la versión más reciente de cada combinación de clave principal.

La contribución de NVIDIA: modo sobre (envelope mode)

El destino (sink) de Zerobus en Debezium ofrece dos contratos de tabla. El modo Typed (con tipos), que es el predeterminado, asigna cada evento de cambio a una tabla con las columnas propias del origen. El modo Envelope (sobre), aportado por NVIDIA, almacena el evento de cambio completo de Debezium en una tabla fija de nueve columnas:

  1. target_table
  2. destination
  3. partition
  4. operation
  5. idempotency_key
  6. key
  7. value
  8. source_position
  9. headers

Los registros se pueden codificar como JSON (almacenados en columnas VARIANT) o Protobuf.

El modo de sobre conserva la información que el procesamiento posterior necesita. source_position contiene la partición y el desplazamiento (offset) de origen, incluido el LSN de PostgreSQL. idempotency_key es una identidad SHA-256 de cada evento, derivada de su destino, partición, clave, operación y posición de origen, de modo que un evento reenviado obtiene la misma clave. La clave identifica los eventos; no los ordena ni desduplica la tabla por sí sola. 

Las puertas de durabilidad confirman el origen
Las puertas de durabilidad confirman el origen: el destino (sink) envía cada grupo contiguo de registros para una tabla, espera a que Zerobus confirme que es duradero y solo entonces permite que Debezium avance su desplazamiento (offset).

Si un grupo posterior falla, se puede volver a entregar un grupo duradero anterior, por lo que la entrega es de al menos una vez (at-least-once) y los duplicados se gestionan en las fases posteriores con idempotency_key. El modo de sobre también filtra por destino y operación, y rechaza un registro de gran tamaño antes de la ingesta para que su desplazamiento nunca se confirme.

Modelado de datos en Databricks

Una vez que los eventos de CDC llegan a Delta, un flujo común de estilo medallón convierte la fuente de cambios sin procesar en algo que los analistas y las aplicaciones pueden usar:

  • Bronze: Los eventos de cambio sin procesar, tal como se reciben. Con el modo sobre (envelope mode), se obtiene una fila por evento que incluye su operación, imágenes de las filas antes y después, posición de origen (LSN) y idempotency_key.
  • Silver: Registros de cambios analizados, deduplicados por idempotency_key y ordenados por posición de origen. Representación utilizable de los datos de origen, con inserciones, actualizaciones y eliminaciones interpretadas para reconstruir el estado actual.
  • Gold: Los datos operacionales se transforman con datos comerciales para la generación de informes, como finanzas, métricas de rendimiento, etc.

Vale la pena mencionar brevemente dos formas de dar forma al flujo de cambios:

  • Tipo 1 (estado actual): comprime el registro de cambios para que cada clave refleje su valor más reciente (una réplica del estado actual de la tabla de origen).
  • Tipo 2 (historial): conserva cada versión a lo largo del tiempo para que puedas consultar los datos tal como se veían en cualquier momento.

El blog práctico complementario en la comunidad de Databricks explica este proceso de principio a fin utilizando una tabla de PostgreSQL local. Configura Debezium Server con el receptor Zerobus, verifica una inserción, actualización y eliminación en la tabla envolvente, y luego crea la tabla de Tipo 1 (estado actual) con AUTO CDC, ordenando los cambios según el LSN de origen.

Conclusión

Elegir la arquitectura de CDC adecuada depende en última instancia de las restricciones de red, las preferencias operativas y la infraestructura existente de tu organización. 

Requisito / Característica

Debezium + Zerobus (Push local)

DIY (Debezium + Kafka + Spark)

Dirección de ingestión

Basado en push (el agente de origen envía hacia afuera)

Basado en push (el agente de origen envía hacia Kafka)

Requisitos de red

Solo requiere acceso saliente desde la red de origen

Requiere acceso saliente al clúster / intermediarios (brokers) de Kafka

Redes privadas / de clientes

Ideal para redes privadas o con restricciones de seguridad

Adecuado para redes privadas, pero requiere administrar la conectividad con Kafka

Infraestructura de Kafka

No es necesaria (transmite directamente a través de Zerobus)

Requerida (clúster de Kafka que actúa como búfer intermediario)

Gestión de conectores

Requiere ejecutar Debezium Server de forma local

Alto coste operativo (gestión de Kafka, Connect y trabajos de ingesta de Spark)

Compatibilidad con el ecosistema

Aprovecha todo el ecosistema de conectores de Debezium; el modo de sobre cerrado guarda eventos de cambio sin procesar para las tablas silver y gold de AUTO CDC

Aprovecha todo el ecosistema de Debezium y Kafka Connect con streaming personalizado de Spark a Delta (Bronze) y trabajos de AUTO CDC

Al combinar Debezium Server con Zerobus Ingest, puedes implementar una arquitectura de inserción local que transmite cambios directamente a las tablas Delta sin necesidad de usar Kafka como transporte de mensajes intermedio ni depender de áreas de almacenamiento provisional en la nube, lo que simplifica la ruta de ingesta de extremo a extremo.

Esto permite que la captura de PostgreSQL siga bajo el control del equipo propietario de la base de datos, mientras los datos se almacenan en Unity Catalog. 

Primeros pasos

Para crear este pipeline tú mismo, sigue la guía paso a paso en Databricks Community. Ejecuta los cambios de PostgreSQL a través de Debezium Server y Zerobus Ingest hacia una tabla de Unity Catalog, y luego crea una tabla con el estado actual usando AUTO CDC. Para configurar Zerobus Ingest y conocer sus otras interfaces de ingesta, consulta la documentación de Zerobus Ingest.

Preguntas frecuentes

¿Qué es el receptor Zerobus Ingest de Debezium?

Es un receptor (sink) en Debezium Server, el motor independiente de Debezium, que envía eventos de cambio directamente a Zerobus Ingest. Zerobus Ingest los escribe en tablas Delta gobernadas por Unity Catalog, por lo que no hay ningún clúster de Kafka entre la captura y el lakehouse. NVIDIA y Databricks colaboraron en esta contribución de código abierto.

¿Qué es el modo de sobre cerrado (envelope mode)?

El modo de sobre cerrado guarda cada evento de cambio completo de Debezium en una tabla fija de nueve columnas en lugar de asignarlo a las columnas propias de la fuente. NVIDIA contribuyó con esta función al receptor. Mantiene la operación, la clave, el valor, la posición de la fuente y una clave de idempotencia para el procesamiento posterior. El modo con tipos es el predeterminado.

¿El receptor entrega cada cambio exactamente una vez?

No, la entrega es de al menos una vez (at-least-once). Si un grupo posterior de registros falla, se puede volver a entregar un grupo duradero anterior. Cada evento incluye una clave de idempotencia (idempotency_key) para que puedas eliminar duplicados más adelante.

¿Cómo convierto la fuente de cambios en una tabla de estado actual?

Usa AUTO CDC para crear una tabla de Tipo 1 que conserve la versión más reciente de cada clave. Ordena los cambios según el LSN de la fuente para que se apliquen en el orden original. Si prefieres conservar todas las versiones a lo largo del tiempo, crea una tabla de Tipo 2.

(Esta entrada del blog ha sido traducida utilizando herramientas basadas en inteligencia artificial) Publicación original

Recibe las últimas publicaciones en tu bandeja de entrada

Suscríbete a nuestro blog y recibe las últimas publicaciones directamente en tu bandeja de entrada.