当前位置: 首页 > article >正文

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 等其他存储系统的数据一致性,为分布式系统的开发提供了有力的支持。

希望本文对你有所帮助。如果有任何问题或建议,欢迎在评论区留言。

相关文章:

Canal 解析与 Spring Boot 整合实战

一、Canal 简介 1.1 Canal 是什么&#xff1f; Canal 是阿里巴巴开源的一款基于 MySQL 数据库增量日志解析&#xff08;Binlog&#xff09;中间件&#xff0c;它模拟 MySQL 的从机&#xff08;Slave&#xff09;行为&#xff0c;监听 MySQL 主机的二进制日志&#xff08;Binl…...

「数据会说话」:让AI成为你的数据分析魔法师 ✨

文章目录 「数据会说话」&#xff1a;让AI成为你的数据分析魔法师 ✨1. 核心技术 &#x1f6e0;️1.1 LIDA智能可视化引擎1.1.1 核心优势1.1.2 核心功能 1.2 前端交互框架 2. 系统架构设计 &#x1f3d7;️2.1 功能模块组成2.2 用户隔离与数据安全 &#x1f512;2.2.1 用户身份…...

图论——Prim算法

53. 寻宝(第七期模拟笔试) 题目描述 在世界的某个区域,有一些分散的神秘岛屿,每个岛屿上都有一种珍稀的资源或者宝藏。国王打算在这些岛屿上建公路,方便运输。 不同岛屿之间,路途距离不同,国王希望你可以规划建公路的方案,如何可以以最短的总公路距离将 所有岛屿联通…...

2025年汽车加气站操作工考试精选题库

汽车加气站操作工题库中题目及答案&#xff1a; 单项选择题 1、按压力容器的设计压力分为&#xff08; &#xff09;个压力等级。 A. 3 B. 4 C. 5 答案&#xff1a;B 2、缓冲罐的安装位置在天然气压缩机&#xff08; &#xff09;。 A. 前 B. 后 C. 中间 答案&#…...

1. 初识golang微服务-gRPC

单体架构 在这里插入图片描述 微服务架构 RPC架构&#xff08;远程过程调用&#xff09; 服务端实例代码&#xff1a; package mainimport ("fmt""net""net/rpc""time" )type Hello struct { }func (h Hello) SayHello(req stri…...

C++20 指定初始化器

指定初始化器 对于聚合&#xff0c;C20 提供了一种方法来指定应该用传递的初始值初始化哪个成员&#xff0c;但只能使用它 来跳过参数。 假设有以下聚合类型: struct Value {double amount{0};int precision{2};std::string unit{"Dollar";}; }; 那么&#x…...

【从零开始学习计算机科学】设计模式(二)工厂模式、抽象工厂模式、单例模式、建造者模型、原型模式

【从零开始学习计算机科学】设计模式(二)工厂模式、抽象工厂模式、单例模式、建造者模型、原型模式 工厂模式主要特点类型适用场景抽象工厂模式主要特点工作原理适用场景举例优点缺点总结单例模式主要特点工作原理适用场景优点缺点总结建造者模式主要特点工作原理适用场景优点…...

视频翻译器免费哪个好?轻松玩转视频直播翻译

你是不是觉得看外语视频很麻烦&#xff1f;每次遇到喜欢的外语电影、电视剧或动漫&#xff0c;总是要等字幕组的翻译&#xff0c;或者因为语言不通而错过精彩的情节。 这个时候&#xff0c;掌握多语种直播翻译方案就显得尤为重要&#xff0c;有了实时字幕&#xff0c;看外语视…...

mysql 数据库异常排查

1、简单查询语句无法执行 线上问题记录&#xff0c;有个删除语句走不了索引导致锁表&#xff0c;其他所有引用该表的操作需要等待删除成功后才能执行&#xff0c;导致服务不可用 排查思路&#xff0c;先看是否有长时间未提交的事务 SELECT * FROM information_schema.INNOD…...

Python列表1

# coding:utf-8 print("———————————— 列表 ——————————————")列表 是指一系列按照特定顺序排列的元素组成 是Python中内置的可变序列 使用[]定义列表&#xff0c;元素与元素之间使用英文的逗号分隔 列表中的元素可以是任意的数据类型列表的…...

如何在前端发版时实现向客户端推送版本更新消息

前端打包发版后如何用户一个更新提示,该提示会让用户主动去更新当前正在操作的页面,或者在系统有较大更新时,让用户重新更新本地缓存信息,这一操作比较友好,且能避免用户不更新当前系统,导致某些接口依赖更新后的数据而导致接口请求失败报错。 1、后端更新提示 有些情况…...

Redis系列:深入理解缓存穿透、缓存击穿、缓存雪崩及其解决方案

在使用Redis作为缓存系统时&#xff0c;我们经常会遇到“缓存穿透”、“缓存击穿”和“缓存雪崩”等问题&#xff0c;这些问题一旦出现&#xff0c;会严重影响应用性能甚至造成服务不可用。因此&#xff0c;理解这些问题的产生原因和解决方案非常重要。 本文将全面讲解缓存穿透…...

3.19学习总结

学习了Java中的面向对象的知识点 完成一道算法题&#xff0c;找树左下角的值&#xff0c;错误的以为左下角只能是最底层的左节点&#xff0c;但指的是最底层最左边的节点...

服务创造未来 东隆科技携多款产品亮相慕尼黑

慕尼黑上海光博会依托于德国慕尼黑博览集团&#xff0c;自2006年首次举办以来&#xff0c;始终坚持将国内外先进的光电技术成果展示给观众&#xff0c;深度链接亚洲乃至全球的激光、光学、光电行业的优质企业及买家。如今已经成为了国内外专业观众信赖的亚洲激光、光学、光电行…...

AI 时代,学习 Java 应如何入手?

一、Java 的现状&#xff1a;生态繁荣与 AI 融合的双重机遇 在 2025 年的技术版图中&#xff0c;Java 依然稳坐企业级开发的 “头把交椅”。根据行业统计&#xff0c;Java 在全球企业级应用中的市场份额仍超过 65%&#xff0c;尤其在微服务架构、大数据平台和物联网&#xff0…...

LiteratureReading:[2016] Enriching Word Vectors with Subword Information

文章目录 一、文献简明&#xff08;zero&#xff09;二、快速预览&#xff08;first&#xff09;1、标题分析2、作者介绍3、引用数4、摘要分析&#xff08;1&#xff09;翻译&#xff08;2&#xff09;分析 5、总结分析&#xff08;1&#xff09;翻译&#xff08;2&#xff09;…...

JavaScript 实现导出内容自动居中:从原理到实践

引言 在前端开发中&#xff0c;我们经常会遇到需要将页面上的内容导出为文件&#xff08;如 PDF、Excel 等&#xff09;的需求。而在导出的内容中&#xff0c;让元素自动居中显示可以提升内容的美观度和专业性。本文将围绕 JavaScript 实现导出内容自动居中展开&#xff0c;详…...

Docker 速通(总结)

Docker 命令 镜像 docker build: 从 Dockerfile 构建镜像。docker pull: 从 Docker Hub 或其他注册表拉取镜像。docker push: 将镜像推送到 Docker Hub 或其他注册表。docker images: 列出本地镜像。docker rmi: 删除本地镜像。 容器 docker run: 创建并启动一个新的容器。…...

人工智能之数学基础:矩阵的降维

本文重点 在现实世界中,我们经常会遇到高维数据。例如,图像数据通常具有很高的维度,每个像素点都可以看作是一个维度。高维数据不仅会带来计算和存储上的困难,还可能会导致 “维数灾难”,即随着维度的增加,数据的稀疏性和噪声也会增加,从而影响数据分析的效果。因此,我…...

Object 转 JSONObject 并排除null和““字符串

public static JSONObject objToJSONObject(Object obj) throws Exception{//创建一个 HashMap 对象 map&#xff0c;用于存储对象的属性名和属性值。//key 是属性名&#xff08;String 类型&#xff09;&#xff0c;value 是属性值&#xff08;Object 类型&#xff09;Map<…...

mysql5.7主从部署(docker-compose版本)

mysql5.7主从部署&#xff08;docker-compose版本&#xff09; 1:docker-compose-test.yml 文件信息 version: 3services:# MySQL 数据库mysql-master:image: mysql:5.7container_name: mysql-masterenvironment:MYSQL_ROOT_PASSWORD: 123456MYSQL_DATABASE: nacosports:- 23…...

Java+Html实现前后端客服聊天

文章目录 核心组件网络通信层事件调度层服务编排层 Spring实现客服聊天技术方案对比WebScoket建立连接用户上线实现指定用户私聊群聊离线 SpringBootWebSocketHtmljQuery实现客服聊天1. 目录结构2. 配置类3. 实体类、service、controller4. ChatWebSocketHandler消息处理5.前端…...

实用工具-Another Redis Desktop Manager介绍

GitHub&#xff1a;https://github.com/qishibo/AnotherRedisDesktopManager/releases Gitee&#xff1a;AnotherRedisDesktopManager 发行版 - Gitee.com Another Redis Desktop Manager 是一款免费的 Redis 可视化管理工具&#xff0c;具有以下特点和功能&#xff1a; 特…...

MySQL如何存储表情符号?

存储表情符号 默认mysql的字符集是utf8&#xff0c;排序规则为 utf8_general_ci INSERT INTO department (name) VALUES (&#x1f604;)在存储表情的时候会报 1366 - Incorrect string value: \xF0\x9F\x98\x84 for column name at row 1, Time: 0.007000s 这时需要修改字符…...

解锁 DeepSeek 安全接入、稳定运行新路径

背景 目前&#xff0c;和 DeepSeek 相关的需求总结为两类&#xff1a; 因官方 APP/Web 服务经常无法返回结果&#xff0c;各类云厂商、硬件或软件企业提供满血版或蒸馏版的 API 算力服务&#xff0c;还有不少基于开源家用计算和存储设备的本地部署方案&#xff0c;以分担 De…...

Spring Boot 配置属性 (Configuration Properties) 详解:优雅地管理应用配置

引言 Spring Boot 的 配置属性 (Configuration Properties) 是其另一个核心特性&#xff0c;它提供了一种 类型安全、结构化 的方式来管理应用的配置信息。 与自动配置相辅相成&#xff0c;配置属性允许开发者 以声明式的方式将外部配置 (如 properties 文件、YAML 文件、环境…...

【LangChain入门 1】安装

文章目录 一、安装LangChain二、安装Ollama三、Ollama下载DeepSeekR1-7b模型 本学习系列以Ollama推理后端作为大语言模型&#xff0c;展开对LangChain框架的入门学习。 模型采用deepseek-r1:7b。 毕竟是免费开源的&#xff0c;下载过程耐心等待即可。 如果可以连接外网&#x…...

HTML中required与aria required区别

在HTML中&#xff0c;required和aria-required"true"都用于标识表单字段为必填项&#xff0c;但它们的作用和适用场景有所不同&#xff1a; 1. required 属性 • 功能属性&#xff1a;属于HTML5原生属性&#xff0c;直接控制表单验证逻辑。 • 作用&#xff1a; • …...

IvorySQL 增量备份与合并增量备份功能解析

1. 概述 IvorySQL v4 引入了块级增量备份和增量备份合并功能&#xff0c;旨在优化数据库备份与恢复流程。通过 pg_basebackup 工具支持增量备份&#xff0c;显著降低了存储需求和备份时间。同时&#xff0c;pg_combinebackup 工具能够将多个增量备份合并为单个完整备份&#x…...

【css酷炫效果】纯CSS实现故障文字特效

【css酷炫效果】纯CSS实现故障文字特效 缘创作背景html结构css样式完整代码基础版进阶版(3D效果) 效果图 想直接拿走的老板&#xff0c;链接放在这里&#xff1a;https://download.csdn.net/download/u011561335/90492053 缘 创作随缘&#xff0c;不定时更新。 创作背景 刚…...