Canal 解析與 Spring Boot 整合實戰

一、Canal 簡介

1.1 Canal 是什么?

Canal 是阿里巴巴開源的一款基于 MySQL 數據庫增量日志解析(Binlog)中間件,它模擬 MySQL 的從機(Slave)行為,監聽 MySQL 主機的二進制日志(Binlog),并解析出數據變更事件(DML 和 DDL),然后將這些事件轉發給下游應用,從而實現數據的實時同步和處理。

1.2 Canal 的應用場景

  • 數據同步:將 MySQL 數據庫的變更數據實時同步到其他存儲系統,如 Redis、Elasticsearch 等。

  • 數據備份:實時備份 MySQL 數據庫的變更數據,用于數據恢復或異地備份。

  • 數據一致性:在分布式系統中,保證 MySQL 數據庫和緩存(如 Redis)的數據一致性。

  • 業務解耦:通過消息隊列(如 Kafka)將數據變更事件傳遞給下游應用,實現業務系統的解耦。

二、Canal 工作原理

2.1 MySQL 主從復制原理

在介紹 Canal 的工作原理之前,我們先復習一下 MySQL 的主從復制原理。MySQL 主從復制主要涉及以下幾個步驟:

  1. 主庫記錄二進制日志:主庫將數據變更操作(如 INSERT、UPDATE、DELETE)記錄到二進制日志(Binlog)中。

  2. 從庫讀取二進制日志:從庫連接到主庫,請求二進制日志,并將日志內容寫入到本地的中繼日志(Relay Log)中。

  3. 從庫應用中繼日志:從庫的 SQL 線程讀取中繼日志,并將日志中的數據變更操作應用到從庫的數據庫中。

2.2 Canal 模擬從庫行為

Canal 模擬了 MySQL 從庫的行為,通過以下步驟實現數據的監聽和解析:

  1. 連接到 MySQL 主庫:Canal 以從庫的身份連接到 MySQL 主庫,并請求二進制日志。

  2. 解析二進制日志:Canal 解析二進制日志中的數據變更事件(DML 和 DDL),并將其轉換為 Canal 自定義的事件格式。

  3. 轉發數據變更事件:Canal 將解析后的數據變更事件轉發給下游應用,如 Redis、Kafka 等。

2.3 Canal 的核心組件

  • Canal Server:負責與 MySQL 主庫建立連接,監聽二進制日志,并解析數據變更事件。

  • Canal Client:負責接收 Canal Server 轉發的數據變更事件,并進行相應的處理。

  • Canal Filter:用于過濾二進制日志中的數據變更事件,只處理感興趣的表和字段。

三、Canal 安裝與配置

3.1 開啟 MySQL 二進制日志

在使用 Canal 之前,需要確保 MySQL 的二進制日志已經開啟。可以通過以下命令查看二進制日志是否開啟:

SHOW VARIABLES LIKE 'log_bin';

如果 log_bin 的值為 OFF,則需要在 MySQL 配置文件中開啟二進制日志:

[mysqld]
log-bin=mysql-bin

3.2 創建 Canal 用戶

為了保證數據安全,建議為 Canal 創建一個專用的 MySQL 用戶,并授予其必要的權限:

CREATE USER canal@'%' IDENTIFIED BY 'canal';
GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT, SUPER ON *.* TO 'canal'@'%';
ALTER USER 'canal'@'%' IDENTIFIED WITH mysql_native_password BY 'canal';
FLUSH PRIVILEGES;

3.3 使用 Docker 安裝 Canal

Canal 提供了 Docker 鏡像,可以通過以下命令安裝并啟動 Canal:

docker pull canal/canal-server:v1.1.5docker run -p 11111:11111 --name canal \
-e canal.destinations=tingshuTopic \
-e canal.instance.master.address=192.168.200.130:3306  \
-e canal.instance.dbUsername=canal  \
-e canal.instance.dbPassword=canal  \
-e canal.instance.connectionCharset=UTF-8 \
-e canal.instance.tsdb.enable=true \
-e canal.instance.gtidon=false  \
-e canal.instance.filter.regex=.*\\..* \
-d canal/canal-server:v1.1.5

四、Spring Boot 整合 Canal

4.1 創建 Spring Boot 工程

使用 Spring Initializr 創建一個新的 Spring Boot 工程

4.2 添加依賴

pom.xml 文件中添加以下依賴:

  • 目前canal不支持jdk17,變成jdk8版本

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.atguigu</groupId><artifactId>service-cdc</artifactId><version>1.0-SNAPSHOT</version><packaging>jar</packaging><name>service-cdc</name><url>http://maven.apache.org</url><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.6.RELEASE</version><relativePath/></parent><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!--web 需要啟動項目--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>top.javatool</groupId><artifactId>canal-spring-boot-starter</artifactId><version>1.2.1-RELEASE</version></dependency><!--    起到監聽的作用     --><dependency><groupId>javax.persistence</groupId><artifactId>persistence-api</artifactId><version>1.0</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency></dependencies>
</project>

4.3 配置 Canal 和 Redis

一個canal服務器有很多個客戶端,每個客戶端有自己的通道名字

application-dev.yml 文件中配置 Canal 和 Redis 的連接信息:

server:port: 7080
#canal配置
canal:destination: tingshuTopic #Canal服務端發送數據的話題名稱跟上面容器里參數destinations的一樣server: 192.168.200.130:11111spring:redis:host: 192.168.200.130port: 6379

4.4 創建實體類

通過實體類監聽到mysql變化的數據,但因為不同表的數據都不一樣,所以每個實體類的字段都不一樣,但是每個表都會有id,所以在實體類中加上變化字段的id

import lombok.Data;
import javax.persistence.Column;@Data
public class CDCEntity {// 注意Column 注解必須是persistence包下的,表示監聽表中的一個字段@Column(name = "id")private Long id;
}

4.5 創建 Canal 處理類

創建一個類實現 EntryHandler 接口,用于處理 Canal 解析的數據變更事件:它定義了三個方法,分別對應 INSERTUPDATEDELETE 操作:

import com.alibaba.otter.canal.client.adapter.support.EntryHandler;
import org.springframework.stereotype.Component;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;@Slf4j
@Component
@CanalTable("album_info")
public class AlbumInfoCdcHandler implements EntryHandler<CDCEntity> {@Autowiredprivate RedisTemplate redisTemplate;@Overridepublic void insert(CDCEntity cdcEntity) {log.info("監聽到數據添加,ID: {}", cdcEntity.getId());}@Overridepublic void update(CDCEntity before, CDCEntity after) {log.info("監聽到數據更新,ID: {}", after.getId());String key = "album:info:" + after.getId();redisTemplate.delete(key);}@Overridepublic void delete(CDCEntity cdcEntity) {log.info("監聽到數據刪除,ID: {}", cdcEntity.getId());}
}

實例:

@Slf4j
@Component
@CanalTable("album_info") 監聽變更表
public class AlbumInfoCdcHandler implements EntryHandler<CDCEntity> {@Autowiredprivate RedisTemplate redisTemplate;//mysql執行添加操作,這個方法執行public void insert(CDCEntity cdcEntity) {log.info("監聽到數據修改,ID:{}", cdcEntity.getId());}//mysql執行修改操作,這個方法執行public void update(CDCEntity before, CDCEntity after) {log.info("監聽到數據修改,ID:{}", after.getId());String key = "album:info:" + after.getId();redisTemplate.delete(key);}//mysql執行刪除操作,這個方法執行public void delete(CDCEntity cdcEntity) {log.info("監聽到數據修改,ID:{}", cdcEntity.getId());}
}

?

五、總結

Canal 是一款強大的 MySQL 數據庫增量日志解析中間件,通過模擬 MySQL 從庫的行為,實現數據的實時同步和處理。在本文中,我們詳細介紹了 Canal 的工作原理、安裝配置方法以及如何與 Spring Boot 進行整合。通過 Canal,我們可以輕松地實現 MySQL 數據庫與 Redis 等其他存儲系統的數據一致性,為分布式系統的開發提供了有力的支持。

希望本文對你有所幫助。如果有任何問題或建議,歡迎在評論區留言。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/73940.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/73940.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/73940.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

《論語別裁》第01章 學而(31) 詩的人生

不過這句話研究起來有一個問題&#xff0c;是詩的問題。我們知道中國文化&#xff0c;在文學的境界上&#xff0c;有一個演變發展的程序&#xff0c;大體的情形&#xff0c;是所謂漢文、唐詩、宋詞、元曲、明小說&#xff0c;到了清朝&#xff0c;我認為是對聯&#xff0c;尤其…

筆記本運行邊緣計算

筆記本電腦可以用來運行PCDN&#xff08;Peer-to-Peer Content Delivery Network&#xff09;服務。實際上&#xff0c;如果你有閑置的筆記本電腦&#xff0c;并且它具備一定的硬件條件和網絡環境&#xff0c;那么它可以成為一個不錯的PCDN節點。 運行PCDN的基本要求 硬件需求…

暗光增強技術研究進展與產品落地綜合分析(2023-2025)

一、引言 暗光增強技術作為計算機視覺與移動影像領域的核心研究方向之一,近年來在算法創新、硬件適配及產品落地方面取得了顯著進展。本文從技術研究與產業應用兩個維度,系統梳理近三年(2023-2025)該領域的關鍵突破,并對比分析主流手機廠商的影像技術優劣勢。 二、暗光增…

多維array和多維視圖std::mdspan

多維數組 這個特性用于訪問多維數組&#xff0c;之前C operator[] 只支持訪問單個下標&#xff0c;無法訪問多維數組。 因此要訪問多維數組&#xff0c;以前的方式是&#xff1a; 重載operator()&#xff0c;于是能夠以m(1, 2) 來訪問第1 行第2 個元素。但這種方式容易和函數…

Python標準庫之os模塊常用方法

一、os模塊簡介 os模塊是Python標準庫中與操作系統交互的一個重要模塊。它提供了非常豐富的方法來處理文件、目錄以及與操作系統相關的操作&#xff0c;讓我們可以編寫跨平臺的代碼&#xff0c;無論是在Windows、Linux還是macOS系統上都能運行。 二、文件和目錄操作 獲取當前…

利用AI讓數據可視化

1. 從問卷星上下載一份答題結果。 序號用戶ID提交答卷時間所用時間來源來源詳情來自IP總分1、《中華人民共和國電子商務法》正式實施的時間是&#xff08;&#xff09;。2、&#xff08;&#xff09;可以判斷企業在行業中所處的地位。3、&#xff08;&#xff09;是指店鋪內有…

K8S學習之基礎三十五:k8s之Prometheus部署模式

Prometheus 有多種部署模式&#xff0c;適用于不同的場景和需求。以下是幾種常見的部署模式&#xff1a; 1. 單節點部署 這是最簡單的部署模式&#xff0c;適用于小型環境或測試環境。 特點&#xff1a; 單個 Prometheus 實例負責所有的數據采集、存儲和查詢。配置簡單&…

【第14節】windows sdk編程:進程與線程介紹

目錄 一、進程與線程概述 1.1 進程查看 1.2 何為進程 1.3 進程的創建 1.4 進程創建實例 1.5 線程查看 1.6 何為線程 1.7 線程的創建 1.8 線程函數 1.9 線程實例 二、內核對象 2.1 何為內核對象 2.2 內核對象的公共特點 2.3 內核對象句柄 2.4 內核對象的跨進程訪…

Python簡單爬蟲實踐案例

學習目標 能夠知道Web開發流程 能夠掌握FastAPI實現訪問多個指定網頁 知道通過requests模塊爬取圖片 知道通過requests模塊爬取GDP數據 能夠用pyecharts實現餅圖 能夠知道logging日志的使用 一、基于FastAPI之Web站點開發 1、基于FastAPI搭建Web服務器 # 導入FastAPI模…

uniapp工程中解析markdown文件

在uniapp中如何導入markdown文件&#xff0c;同時在頁面中解析成html&#xff0c;請參考以下配置&#xff1a; 1. 安裝以下3個依賴包 npm install marked highlight.js vite-plugin-markdown 2. 創建vite.config.js配置文件 // vite.config.js import { defineConfig } fro…

sass介紹

1、Sass簡介 Sass 是一種 CSS 的預編譯語言。它提供了 變量&#xff08;variables&#xff09;、嵌套&#xff08;nested rules&#xff09;、 混合&#xff08;mixins&#xff09;、 函數&#xff08;functions&#xff09;等功能&#xff0c;并且完全兼容 CSS 語法。Sass 能…

[JavaScript]如何利用作用域塊避免閉包內存泄漏?

出自《你不知道的JavaScript》上卷 以下是本書給出的反例: function process (data) {...} var bigdata{...} process(bigdata); var btn document.getElementById(x); btn.addEventListener(click, function click{...});click會被回調在其他位置, 在addEventListener函數內…

leetcode hot100(五)

11. 盛最多水的容器 給定一個長度為 n 的整數數組 height 。有 n 條垂線&#xff0c;第 i 條線的兩個端點是 (i, 0) 和 (i, height[i]) 。 找出其中的兩條線&#xff0c;使得它們與 x 軸共同構成的容器可以容納最多的水。 返回容器可以儲存的最大水量。 說明&#xff1a;你…

Unity 云渲染本地部署方案

Unity Render Streaming 云渲染環境搭建 0.安裝 Unity Render Streaming 實現原理: 服務器與客戶端實現功能包括: 詳細內容見官方文檔&#xff1a; 官方文檔: https://docs.unity3d.com/Packages/com.unity.renderstreaming3.1/manual/tutorial.html Unity 流送云渲染介紹: …

洛谷 P3986 斐波那契數列

P3986 斐波那契數列 題目描述 定義一個數列&#xff1a; f ( 0 ) a , f ( 1 ) b , f ( n ) f ( n ? 1 ) f ( n ? 2 ) f(0) a, f(1) b, f(n) f(n - 1) f(n - 2) f(0)a,f(1)b,f(n)f(n?1)f(n?2) 其中 a, b 均為正整數&#xff0c;n ≥ 2。 問有多少種 (a, b)&…

【java面型對象進階】------繼承實例

繼承結構下的標準Javabean 代碼如下&#xff1a; package demo10;//定義員工父類 public class Employee {private String id;private String name;private double salary;//構造方法public Employee(){}public Employee(String id,String name,double salary){this.idid;thi…

Vitis 2024.1 無法正常編譯custom ip的bug(因為Makefile里的wildcard)

現象&#xff1a;如果在vivado中&#xff0c;添加了自己的custom IP&#xff0c;比如AXI4 IP&#xff0c;那么在Vitis&#xff08;2024.1&#xff09;編譯導出的原本的.xsa的時候&#xff0c;會構建build失敗。報錯代碼是&#xff1a; "Compiling blank_test_ip..."…

【圖論】并查集的學習和使用

目錄 并查集是什么&#xff1f; 舉個例子 組成 父親數組&#xff1a; find函數&#xff1a; union函數&#xff1a; 代碼實現&#xff1a; fa[] 初始化code: find code&#xff1a; 遞歸實現: 非遞歸實現: union code : 畫圖模擬&#xff1a; 路徑壓縮&#xff1a…

Java使用FFmpegFrameGrabber進行視頻拆幀,結合Thumbnails壓縮圖片保存到文件夾

引入依賴 <dependency><groupId>net.coobird</groupId><artifactId>thumbnailator</artifactId><version>0.4.17</version></dependency><dependency><groupId>org.bytedeco</groupId><artifactId>ja…

mysql與redis的日志策略

MySQL 和 Redis 在日志記錄方面采用了不同的策略&#xff0c;分別對應寫前日志&#xff08;Write-Ahead Logging, WAL&#xff09;和寫后日志&#xff08;Write-After Logging&#xff09;。以下是它們的詳細說明&#xff1a; 1. MySQL&#xff1a;寫前日志&#xff08;Write-A…