Published on

Implementation of the Change Data Capture (CDC) solution with Debezium and Kafka, on the SQL Server database

Authors

Alrighty, buckle up and hold onto your hats, folks! We're about to go on a magical journey through the kingdom of Change Data Capture (CDC), where the gallant knights Debezium and Kafka safeguard the land of SQL Server Database. As the grand wizard of software architecture, I am your guide, so let's set off, shall we?

Act 1: Summoning Kafka

Kafka, the noble steed of our architecture, is the messenger that carries our magical scrolls (a.k.a. messages) far and wide. To conjure Kafka, we'll invoke the all-powerful Docker spell:

docker run -d --name kafka -p 9092:9092 -e KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181 -e KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://localhost:9092 -e KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR=1 confluentinc/cp-kafka:latest

Act 2: Bringing Debezium to Life

Next, we summon Debezium, our faithful spy who watches our SQL Server Database with the eye of a hawk. Once again, we call upon Docker:

docker run -it --rm --name debezium -p 8083:8083 -e GROUP_ID=1 -e CONFIG_STORAGE_TOPIC=my_connect_configs -e OFFSET_STORAGE_TOPIC=my_connect_offsets -e STATUS_STORAGE_TOPIC=my_connect_statuses --link zookeeper:zookeeper --link kafka:kafka debezium/connect:latest

Act 3: Briefing Debezium

Debezium is a faithful servant but needs to be told exactly what to watch. So we prepare a magical scroll (also known as a JSON file):

{
    "name": "inventory-connector",
    "config": {
        "connector.class": "io.debezium.connector.sqlserver.SqlServerConnector",
        "tasks.max": "1",
        "database.hostname": "sqlserver",
        "database.port": "1433",
        "database.user": "sa",
        "database.password": "Password!",
        "database.dbname": "testDB",
        "database.server.name": "fulldb",
        "table.include.list": "dbo.customers",
        "database.history.kafka.bootstrap.servers": "kafka:9092",
        "database.history.kafka.topic": "dbhistory.full" ,
        "include.schema.changes": "true"
    }
}

And deliver it using a magical raven (or a REST API call, if you will):

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

Act 4: Wreaking Havoc (Testing!)

Let's see our Debezium-Kafka combo in action! We'll create a table in our SQL Server Database and then change it:

USE testDB;
GO

UPDATE dbo.customers SET email = 'j.doe@example.com' WHERE id = 1;
GO

INSERT INTO dbo.customers
VALUES (3, 'Jimmy', 'Doe', 'jimmy.doe@example.com');
GO

Act 5: Reading the Tea Leaves

Finally, we'll use Kafka's consumer to read the magical scrolls (i.e., change data):

docker exec -it kafka /usr/bin/kafka-console-consumer --bootstrap-server localhost:9092 --topic fulldb.dbo.customers --from-beginning

Voila! Debezium has spied the changes and Kafka has carried the news. If all's gone well, you'll see something like this:

{
    "schema": { ... },
    "payload": {
        "before": {
            "id": 1,
            "first_name": "John",
            "last_name": "Doe",
            "email": "john.doe@example.com"
        },
        "after": {
            "id": 1,
            "first_name": "John",
            "last_name": "Doe",
            "email": "j.doe@example.com"
        },
        "source": { ... },
        "op": "u",
        "ts_ms": 1234567890123,
        "transaction": null
    }
}

And for the new entry:

{
    "schema": { ... },
    "payload": {
        "before": null,
        "after": {
            "id": 3,
            "first_name": "Jimmy",
            "last_name": "Doe",
            "email": "jimmy.doe@example.com"
        },
        "source": { ... },
        "op": "c",
        "ts_ms": 1234567890124,
        "transaction": null
    }
}

Bask in the glory of your magical prowess! You've successfully implemented a CDC solution with Debezium and Kafka on SQL Server Database. You have mastered the art of software magic, and I, as the grand wizard, couldn't be prouder.

Now, go forth and use your newfound powers wisely, my apprentice. And remember, "with great power, comes great responsibility." 🧙‍♂️