En la primera parte expliqué la arquitectura de la demo y las decisiones de diseño detrás de SQL Server, Debezium, Kafka Connect, Kafka UI y el visor web. En esta segunda parte me concentro en la ejecución: cómo levantar el entorno, validar que CDC esté funcionando y probar el flujo completo con cambios reales.
Prerrequisitos
Antes de arrancar, necesitas Docker Desktop o Docker Engine con Docker Compose v2, puertos libres para SQL Server, Kafka Connect, Kafka UI, Kafka y Web Viewer, y memoria suficiente para que SQL Server no estrangule el resto del stack. Si estás en Windows, la demo trae scripts tanto en PowerShell como en bash.
- Docker Compose v2 operativo
- Puertos 1433, 8083, 8080, 9092 y 3000 disponibles o remapeados
- Al menos unos 4 GB libres, porque SQL Server es el servicio más pesado
- Acceso a bash o PowerShell según tu flujo
Paso 1: levantar la infraestructura
El arranque base se hace con docker compose up -d. Eso levanta SQL Server, Kafka en KRaft, Kafka Connect, Kafka UI y el Web Viewer. El orden importa, y por eso el stack usa healthchecks y dependencias condicionales para que Connect no intente arrancar antes de que Kafka y SQL Server estén listos.

Una vez arriba, lo primero que vale la pena comprobar es el estado de los contenedores. Todos deberían aparecer como running y, cuando aplique, como healthy.
docker compose ps
Paso 2: inicializar SQL Server y habilitar CDC
La imagen oficial de SQL Server no ejecuta automáticamente scripts de inicialización como sí hacen otras bases en algunos escenarios, así que la demo incluye scripts dedicados para aplicar la base DemoCDC, crear dbo.Clientes, habilitar CDC e insertar datos semilla.
./scripts/apply-sql.sh
# o en PowerShell
./scripts/apply-sql.ps1
Ese paso hace cuatro cosas importantes:
- Crea la base de datos DemoCDC.
- Crea la tabla dbo.Clientes con clave primaria.
- Habilita CDC a nivel de base y de tabla.
- Inserta tres registros semilla para que el snapshot inicial tenga contenido visible.
Si quieres verificar que CDC quedó realmente activo, puedes consultar sys.databases o usar sp_cdc_help_change_data_capture dentro del contenedor.
Paso 3: registrar el connector Debezium
Con la base preparada, el siguiente paso es registrar el connector en Kafka Connect. La configuración vive en un JSON comentado, lo que facilita entender cada parámetro clave: host y puerto de SQL Server, base capturada, tabla incluida, topic prefix, modo de snapshot y topic interno de historial de esquema.
./connect/register-connector.sh
# o en PowerShell
./connect/register-connector.ps1
En cuanto se registra, Debezium ejecuta el snapshot inicial. Ese snapshot emite un evento por cada fila ya existente, usando op = "r". Después de eso, el connector entra en modo streaming para capturar INSERT, UPDATE y DELETE nuevos.
Paso 4: validar el snapshot inicial
La demo permite observar los mismos eventos por tres caminos: Kafka UI, consola y Web Viewer. Para una explicación técnica, Kafka UI es muy útil; para una presentación o demo en vivo, el Web Viewer suele ser el más efectivo porque hace visible el patrón sin pedirle al espectador que lea JSON desde el minuto uno.
- Kafka UI: ideal para ver topics, mensajes y estado del connector.
- Consola: útil para validar rápidamente el stream en texto plano.
- Web Viewer: pensado para mostrar el snapshot y los cambios como tarjetas y contadores en tiempo real.
Si todo salió bien, deberías ver tres eventos del snapshot inicial, uno por cada cliente semilla.
Paso 5: probar INSERT, UPDATE y DELETE
Una vez validado el snapshot, toca probar cambios reales. La demo incluye tres scripts listos para disparar un INSERT, un UPDATE y un DELETE. Lo ideal es ejecutarlos uno a uno y observar cómo aparecen en el topic y en el visor web.
./scripts/apply-sql.sh 03-test-insert.sql
./scripts/apply-sql.sh 04-test-update.sql
./scripts/apply-sql.sh 05-test-delete.sql
Cada uno se refleja como una operación distinta:
- INSERT:
op = "c" - UPDATE:
op = "u"conbeforeyafter - DELETE:
op = "d", seguido de un tombstone para compaction
Anatomía de un evento Debezium
Uno de los puntos más didácticos de Debezium es que no solo te dice que algo cambió, sino qué cambió y de dónde vino. Un evento típico de UPDATE trae el estado previo, el nuevo estado, el tipo de operación y metadatos como base, esquema, tabla y posición en el log.
{
"payload": {
"before": { "Id": 1, "Estado": "ACTIVO" },
"after": { "Id": 1, "Estado": "INACTIVO" },
"op": "u",
"ts_ms": 1751277900000,
"source": {
"connector": "sqlserver",
"db": "DemoCDC",
"schema": "dbo",
"table": "Clientes"
}
}
}
Ese formato hace que luego sea mucho más fácil alimentar consumidores técnicos, dashboards, ETL o sistemas de auditoría.
Troubleshooting más común
Hay cuatro fallos que concentran la mayoría de los problemas en esta clase de demo:
- Login failed for user sa: la contraseña del connector no coincide con la del entorno.
- CDC no habilitado: la inicialización SQL no se ejecutó o se hizo antes de que SQL Server Agent estuviera listo.
- Connector en FAILED: suele verse enseguida en el endpoint de status de Kafka Connect.
- Web Viewer desconectado: el topic no existe todavía o el consumidor arrancó antes del registro del connector.
Por eso vale la pena apoyarse en docker compose logs y en el endpoint de estado del connector desde el principio.
Qué cambiaría para llevar esta demo a producción
Una demo local tiene que optimizar por claridad, no por dureza operativa. En producción yo cambiaría al menos estas piezas:
- Más de un broker Kafka y replicación mayor a 1.
- TLS, autenticación y ACLs en Kafka.
- Schema Registry y serialización Avro o Protobuf.
- Un usuario mínimo en SQL Server en lugar de usar sa.
- Métricas y alertas con Prometheus y Grafana.
- Al menos un sink connector para materializar eventos en otro destino.
Esas mejoras no invalidan la demo; al contrario, la convierten en una buena base pedagógica desde la que puedes evolucionar el patrón sin tener que rediseñarlo por completo.
Conclusión
Si tu objetivo es entender CDC de forma práctica, esta demo cubre el recorrido esencial: habilitas captura en SQL Server, registras Debezium, validas el snapshot y observas cómo cada cambio se convierte en un evento consumible. Ese es el valor real del patrón.
Si aún no viste el contexto completo de arquitectura, vuelve a la primera parte, donde explico por qué esta demo está diseñada así y qué trade-offs asume.
La demo de todo lo anteriormente explicado, pueden revisarla en el siguiente video.

Finalmente, les comparto el repositorio:
Deja un comentario