From 99f97c61889840b26331fbd5d0ec10e6efa31051 Mon Sep 17 00:00:00 2001 From: mfvitale Date: Fri, 20 Sep 2024 18:05:53 +0200 Subject: [PATCH 1/4] DBZ-8256 Database Activity metrics blog post --- ...-data-mutation-patterns-with-Debezium.adoc | 172 ++++++++++++++++++ .../activity-monitoring-dashboard.png | Bin 0 -> 54789 bytes 2 files changed, 172 insertions(+) create mode 100644 _posts/2024-09-20-Detect-data-mutation-patterns-with-Debezium.adoc create mode 100644 assets/images/2024-09-20-Detect-data-mutation-patterns-with-Debezium/activity-monitoring-dashboard.png diff --git a/_posts/2024-09-20-Detect-data-mutation-patterns-with-Debezium.adoc b/_posts/2024-09-20-Detect-data-mutation-patterns-with-Debezium.adoc new file mode 100644 index 00000000000..2d44fe40a3c --- /dev/null +++ b/_posts/2024-09-20-Detect-data-mutation-patterns-with-Debezium.adoc @@ -0,0 +1,172 @@ +--- +layout: post +title: "Detect data mutation patterns with Debezium" +date: 2024-09-20 11:11:11 +0100 +tags: [ debezium, features, monitoring, analytics, metrics ] +featured: true +author: mfvitale +--- +In today's dynamic data environments, detecting and understanding data mutation patterns is critical for system reliability. +In this blog post, we'll explore how to use Debezium for comprehensive database activity logging and analysis in microservice architectures. +We'll delve into how Debezium captures row-level changes and streams them in real-time, enabling immediate visibility into database operations. +By integrating with analytics tools, we'll see how to build detailed activity dashboards that reveal the volume and nature of operations per table. +These insights are invaluable for identifying unexpected patterns, such as a sudden drop in inserts caused by a new microservice deployment with a bug. +You will learn how to set up Debezium, configure it for this specific use case, and utilize the generated data to create actionable dashboards. + +++++++ + +== The concept and the idea behind +In recent years, observability has become an essential part of modern systems due to a grown complexity, this especially in distributed architectures like microservices, containerized applications, and cloud environments. + +Here are some important reasons why observability is crucial today: + +* *Faster Troubleshooting and Incident Response*: Observability provides deep insights into system behavior, helping teams quickly identify and resolve issues by correlating logs, metrics, and traces, reducing downtime and improving response times. +* *Proactive Issue Detection: Observability enables* proactive monitoring by identifying anomalies and patterns in real-time, allowing teams to address potential problems before they impact users. + +An application typically exposes different types of metrics to provide insights into its behavior, performance, and overall health. These metrics can be categorized into several key types: + +Infrastructure Metrics:: These track the resource usage of the underlying infrastructure, such as: CPU Usage, Memory Usage, Disk I/O, Network I/O. +Application Performance Metrics:: These measure the application’s operational performance to ensure the application performs optimally and meets user expectations. For example: Request Rate, Error Rate, Latency, Throughput. +Business Metrics:: These focus on the application's impact on business goals, such as: Number of Transactions, Conversion Rate, Revenue, User Signups. + +Usually, infrastructure and application metrics are quite "standard," and there are frameworks/tools that can be easily used to instruct your application to expose those metrics. +On the other hand, business metrics can vary between applications, so you need to implement custom code every time to expose those metrics. + +The idea is to think at a lower level and leverage change data capture (CDC) to extract data that can be used as business metrics. + +Suppose we have an order service that processes and stores orders made by our customers. +An important business metric to monitor would be the number of orders made. +This number is very relevant to the business because it is directly correlated with the company’s earnings. +A relevant drop in number of orders should alter the team responsible for that service as soon as possible. + +Normally, we would need to modify our application to instruct a https://prometheus.io/docs/concepts/metric_types/#counter[counter] metric that increments every time an order is correctly placed and stored in the database. +But what if we could extract this information just by monitoring the database through CDC? + +Let’s explore how Debezium offers this possibility. + +== How Debezium Exposes Metrics + +Debezium exposes three categories of metrics: + +Snapshot metrics:: Provide information about connector operation while performing a snapshot, such as RowsScanned, RemainingTableCount, TotalTableCount. +Streaming metrics:: Provide information about connector operation when the connector is reading the database log, such as TotalNumberOfCreateEventsSeen, QueueRemainingCapacity, QueueTotalCapacity. +Schema history metrics:: Provide information about the status of the connector’s schema history, such as ChangesApplied, ChangesRecovered, Status. + +All these metrics are exposed through JMX. You can read more in our https://debezium.io/documentation/reference/stable/operations/monitoring.html[documentation]. + +=== Database Activity Metrics + +Starting from the 3.0.0.Final release (specifically 3.0.0.Beta1), the following new streaming metrics have been introduced: + +NumberOfCreateEventsSeen:: Counts the number of create events per table. +NumberOfDeleteEventsSeen:: Counts the number of delete events per table. +NumberOfUpdateEventsSeen:: Counts the number of update events per table. +NumberOfTruncateEventsSeen:: Counts the number of truncate events per table. + +Since these metrics are experimental, you need to opt-in to enable them by setting the internal.advanced.metrics.enable property to true. + +== Demo: Order service monitoring dashboard + +After you exposed these metrics with Debezium you can easily create a dashboard with alerts to monitor an eventual drastic drop that is significant for you business. +We'll set up our order service with its own PostgreSQL database, Debezium PostgreSQL connector on the Kafka Connect runtime and Prometheus and Grafana as our observability platform. + +For this demo you need to clone the code in the https://github.com/debezium/debezium-examples[Debezium examples repository] and go to the `db-activity-monitoring` directory. + +== Components overview + +=== Order service +The order service is a https://quarkus.io/[Quarkus] application that, per default, stores 100 orders every 10s, this mean a rate of ~10 orders per second. +To simulate a wrong deployment, if you set the `app.version` application properties with a value different from `1.0`, it will start to insert orders with a drop of 50% of standard insert rate. + +The application also exposes the `application.info` metric with a constant value of `1.0` but with two labels: `version` and `name`. +We will use this metric to put a label on the graph to indicate the version of the deployed service. + +=== JMX exporter configuration +We saw that Debezium exposes metrics as a JMX bean so normally to expose those metrics to Prometheus we can use the https://github.com/prometheus/jmx_exporter[JMX exporter]. +In the `debezium-jmx-exporter` the `config.yml` file contain its configuration. The most important the following pattern + +[source, yaml] +---- +- pattern: "debezium.([^:]+)]+)><>NumberOfCreateEventsSeen" + name: "debezium_metrics_create_events_count" + labels: + plugin: "$1" + context: "$2" + name: "$3" + table: "$4" + type: "COUNTER" +---- + +Given that the name of the MBean is `debezium.postgres<>NumberOfCreateEventsSeen`, the rule above simply creates the following metric: + +[source, text] +---- +# TYPE debezium_metrics_create_events_count_total counter +debezium_metrics_create_events_count{context="streaming",name="monitoring",plugin="postgres",table="inventory.orders",} 100.0 +---- + +=== Components start up + +After that you are ready to start the demo with the following steps: + +. Build our order service. + ++ +[source,shell] +---- +order-service/mvnw package -f order-service/pom.xml +---- + +. Run our compose file to start everything is needed. + ++ +[source,shell] +---- +export DEBEZIUM_VERSION=3.0.0.Beta1 +docker-compose up -d --build +---- + +. When all service are up and running we can register our connector + ++ +[source,shell] +---- +curl -i -X POST -H "Accept:application/json" -H "Content-Type:application/json" http://localhost:8083/connectors/ -d @postgres-activity-monitoring.json +---- + +=== Accessing the dashboard + +Open a web browser and go to the Grafana UI at http://localhost:3000[http://localhost:3000]. +Login into the console as user `admin` with password `admin`. +When asked either change the password (you also can skip this step). + +Then, to monitor the order service activity, we have created the `General/ Microservices activity monitoring` dashboard. + +After a couple of minutes you should see that the order rate will be ~10 per second. + +To simulate a drop, we can just update the `APP_VERSION` env to a value different to `1.0`. + +```shell +docker stop order-service +docker rm -f order-service && \ +docker compose run -d -e APP_VERSION=1.1 --name order-service order-service +``` + +After a while you will see that the service will start creating orders with a ~50% drop (see _Figure 1_). + +Since we have also configured an alert to fire when the order rate is below 7, you can also check that it is firing in the alert panel. + +:imagesdir: /assets/images/2024-09-20-Detect-data-mutation-patterns-with-Debezium + +.{nbsp} +image::activity-monitoring-dashboard.png[role=centered-image] + +But that's not all, we have also configured a mail notification that you can check accessing the Fake SMTP UI at http://localhost:8085[http://localhost:8085]. + +== Conclusion +We have seen how Change Data Capture (CDC) can be used to extract insight from the database that can serve as key business metrics for our services. +This approach allows us to avoid modifying our service to expose these metrics and instead rely on Debezium for data collection. + +While not all business metrics can be derived from database operations, a significant portion can be. + +Any comments, suggestions, or questions are welcome, so please feel free to reach out to me to discuss further. diff --git a/assets/images/2024-09-20-Detect-data-mutation-patterns-with-Debezium/activity-monitoring-dashboard.png b/assets/images/2024-09-20-Detect-data-mutation-patterns-with-Debezium/activity-monitoring-dashboard.png new file mode 100644 index 0000000000000000000000000000000000000000..fe55a8724f264d279bea9ef4e92248c05a6fe422 GIT binary patch literal 54789 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 UBWd2f;9%;vv<+`oYu*e0UsUzw+W-In literal 0 HcmV?d00001 From 9fd815728e6604e52ae2ced571e0edc6a4d69632 Mon Sep 17 00:00:00 2001 From: mfvitale Date: Mon, 23 Sep 2024 16:53:35 +0200 Subject: [PATCH 2/4] DBZ-8256 Address review comments --- ...-data-mutation-patterns-with-Debezium.adoc | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/_posts/2024-09-20-Detect-data-mutation-patterns-with-Debezium.adoc b/_posts/2024-09-20-Detect-data-mutation-patterns-with-Debezium.adoc index 2d44fe40a3c..39dfdc46529 100644 --- a/_posts/2024-09-20-Detect-data-mutation-patterns-with-Debezium.adoc +++ b/_posts/2024-09-20-Detect-data-mutation-patterns-with-Debezium.adoc @@ -20,8 +20,8 @@ In recent years, observability has become an essential part of modern systems du Here are some important reasons why observability is crucial today: -* *Faster Troubleshooting and Incident Response*: Observability provides deep insights into system behavior, helping teams quickly identify and resolve issues by correlating logs, metrics, and traces, reducing downtime and improving response times. -* *Proactive Issue Detection: Observability enables* proactive monitoring by identifying anomalies and patterns in real-time, allowing teams to address potential problems before they impact users. +Faster Troubleshooting and Incident Response:: Observability provides deep insights into system behavior, helping teams quickly identify and resolve issues by correlating logs, metrics, and traces, reducing downtime and improving response times. +Proactive Issue Detection:: Observability enables proactive monitoring by identifying anomalies and patterns in real-time, allowing teams to address potential problems before they impact users. An application typically exposes different types of metrics to provide insights into its behavior, performance, and overall health. These metrics can be categorized into several key types: @@ -36,10 +36,10 @@ The idea is to think at a lower level and leverage change data capture (CDC) to Suppose we have an order service that processes and stores orders made by our customers. An important business metric to monitor would be the number of orders made. -This number is very relevant to the business because it is directly correlated with the company’s earnings. -A relevant drop in number of orders should alter the team responsible for that service as soon as possible. +This number is very relevant to the business because it directly correlates to the company’s earnings.. +A relevant drop in number of orders should alert the team responsible for that service as soon as possible. -Normally, we would need to modify our application to instruct a https://prometheus.io/docs/concepts/metric_types/#counter[counter] metric that increments every time an order is correctly placed and stored in the database. +Normally, we would need a https://prometheus.io/docs/concepts/metric_types/#counter[counter] metric that increments every time an order is correctly placed and stored in the database. But what if we could extract this information just by monitoring the database through CDC? Let’s explore how Debezium offers this possibility. @@ -56,18 +56,18 @@ All these metrics are exposed through JMX. You can read more in our https://debe === Database Activity Metrics -Starting from the 3.0.0.Final release (specifically 3.0.0.Beta1), the following new streaming metrics have been introduced: +Starting from the 3.0.0.Final release (specifically 3.0.0.Beta1), the following new streaming metrics were introduced: NumberOfCreateEventsSeen:: Counts the number of create events per table. NumberOfDeleteEventsSeen:: Counts the number of delete events per table. NumberOfUpdateEventsSeen:: Counts the number of update events per table. NumberOfTruncateEventsSeen:: Counts the number of truncate events per table. -Since these metrics are experimental, you need to opt-in to enable them by setting the internal.advanced.metrics.enable property to true. +Since these metrics are experimental, you need to opt-in to enable them by setting the `internal.advanced.metrics.enable` property to true. == Demo: Order service monitoring dashboard -After you exposed these metrics with Debezium you can easily create a dashboard with alerts to monitor an eventual drastic drop that is significant for you business. +After you expose these metrics with Debezium, you can easily create a dashboard with alerts to monitor any significant change that can influence your business. We'll set up our order service with its own PostgreSQL database, Debezium PostgreSQL connector on the Kafka Connect runtime and Prometheus and Grafana as our observability platform. For this demo you need to clone the code in the https://github.com/debezium/debezium-examples[Debezium examples repository] and go to the `db-activity-monitoring` directory. @@ -75,8 +75,9 @@ For this demo you need to clone the code in the https://github.com/debezium/debe == Components overview === Order service -The order service is a https://quarkus.io/[Quarkus] application that, per default, stores 100 orders every 10s, this mean a rate of ~10 orders per second. -To simulate a wrong deployment, if you set the `app.version` application properties with a value different from `1.0`, it will start to insert orders with a drop of 50% of standard insert rate. +The order service is a https://quarkus.io/[Quarkus] application that, per default, stores 100 orders every 10 seconds, or a rate of ~10 orders per second. +You can simulate a bad deployment by setting the `app.version` property in application.properties to anything other than `1.0`. +This will force the application to perform order inserts at half the standard rate. The application also exposes the `application.info` metric with a constant value of `1.0` but with two labels: `version` and `name`. We will use this metric to put a label on the graph to indicate the version of the deployed service. @@ -164,7 +165,7 @@ image::activity-monitoring-dashboard.png[role=centered-image] But that's not all, we have also configured a mail notification that you can check accessing the Fake SMTP UI at http://localhost:8085[http://localhost:8085]. == Conclusion -We have seen how Change Data Capture (CDC) can be used to extract insight from the database that can serve as key business metrics for our services. +We have seen how Change Data Capture (CDC) can extract insights from the database to serve as key performance indicators (KPIs) in the reliability and observability of microservices. This approach allows us to avoid modifying our service to expose these metrics and instead rely on Debezium for data collection. While not all business metrics can be derived from database operations, a significant portion can be. From bd43f8fa14403530921afbe0022db765db5c9d85 Mon Sep 17 00:00:00 2001 From: mfvitale Date: Tue, 24 Sep 2024 14:45:40 +0200 Subject: [PATCH 3/4] DBZ-8256 Address review comments --- ...4-09-20-Detect-data-mutation-patterns-with-Debezium.adoc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/_posts/2024-09-20-Detect-data-mutation-patterns-with-Debezium.adoc b/_posts/2024-09-20-Detect-data-mutation-patterns-with-Debezium.adoc index 39dfdc46529..2db1c07d6f9 100644 --- a/_posts/2024-09-20-Detect-data-mutation-patterns-with-Debezium.adoc +++ b/_posts/2024-09-20-Detect-data-mutation-patterns-with-Debezium.adoc @@ -16,7 +16,7 @@ You will learn how to set up Debezium, configure it for this specific use case, ++++++ == The concept and the idea behind -In recent years, observability has become an essential part of modern systems due to a grown complexity, this especially in distributed architectures like microservices, containerized applications, and cloud environments. +In recent years, observability has become an essential part of modern systems due to the increasing complexity of architectures like microservices, containerized applications, and cloud environments. Here are some important reasons why observability is crucial today: @@ -36,7 +36,7 @@ The idea is to think at a lower level and leverage change data capture (CDC) to Suppose we have an order service that processes and stores orders made by our customers. An important business metric to monitor would be the number of orders made. -This number is very relevant to the business because it directly correlates to the company’s earnings.. +This number is very relevant to the business because it directly correlates to the company’s earnings. A relevant drop in number of orders should alert the team responsible for that service as soon as possible. Normally, we would need a https://prometheus.io/docs/concepts/metric_types/#counter[counter] metric that increments every time an order is correctly placed and stored in the database. @@ -139,7 +139,7 @@ curl -i -X POST -H "Accept:application/json" -H "Content-Type:application/json" Open a web browser and go to the Grafana UI at http://localhost:3000[http://localhost:3000]. Login into the console as user `admin` with password `admin`. -When asked either change the password (you also can skip this step). +When asked either change the password or skip this step. Then, to monitor the order service activity, we have created the `General/ Microservices activity monitoring` dashboard. From 1e1f2379d9672d4b909df124337eb118383d6ad9 Mon Sep 17 00:00:00 2001 From: mfvitale Date: Mon, 14 Oct 2024 09:49:36 +0200 Subject: [PATCH 4/4] DBZ-8256 Change publication date for "Detect data mutation patterns with Debezium" --- ...24-10-14-Detect-data-mutation-patterns-with-Debezium.adoc} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename _posts/{2024-09-20-Detect-data-mutation-patterns-with-Debezium.adoc => 2024-10-14-Detect-data-mutation-patterns-with-Debezium.adoc} (99%) diff --git a/_posts/2024-09-20-Detect-data-mutation-patterns-with-Debezium.adoc b/_posts/2024-10-14-Detect-data-mutation-patterns-with-Debezium.adoc similarity index 99% rename from _posts/2024-09-20-Detect-data-mutation-patterns-with-Debezium.adoc rename to _posts/2024-10-14-Detect-data-mutation-patterns-with-Debezium.adoc index 2db1c07d6f9..c9b81b94819 100644 --- a/_posts/2024-09-20-Detect-data-mutation-patterns-with-Debezium.adoc +++ b/_posts/2024-10-14-Detect-data-mutation-patterns-with-Debezium.adoc @@ -1,7 +1,7 @@ --- layout: post title: "Detect data mutation patterns with Debezium" -date: 2024-09-20 11:11:11 +0100 +date: 2024-10-14 10:10:10 +0100 tags: [ debezium, features, monitoring, analytics, metrics ] featured: true author: mfvitale @@ -123,7 +123,7 @@ order-service/mvnw package -f order-service/pom.xml + [source,shell] ---- -export DEBEZIUM_VERSION=3.0.0.Beta1 +export DEBEZIUM_VERSION=3.0.0.Final docker-compose up -d --build ----