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

MySQL数据同步之Canal讲解

文章目录

  • 1 Canal搭建
    • 1.1 简介
      • 1.1.1 概述
      • 1.1.2 优点
      • 1.1.3 作用&核心组件
    • 1.2 搭建 Canal
      • 1.2.1 准备工作
        • 1.2.1.1 检查配置
        • 1.2.1.2 MySQL配置
      • 1.2.2 下载并安装 Canal
      • 1.2.3 配置 Canal Server
        • 1.2.3.1 全局配置
        • 1.2.3.2 实例配置
        • 1.2.3.3 配置目标系统
        • 1.2.3.4 配置 Canal Adapter
      • 1.2.4 启动服务
      • 1.2.5 使用 Docker 部署 Canal
    • 1.3 注意和问题
      • 1.3.1 注意事项
      • 1.3.2 常见问题
      • 1.3.3 为什么既要全局配置又要 实例配置
        • 1.3.3.1 Canal核心模型
        • 1.3.3.2 支持多实例运行
        • 1.3.3.3 模块化与职责分离
  • 2 SpringBoot结合使用
    • 2.1 pom和配置
    • 2.2 实体和mapper
      • 2.2.1 实体类
      • 2.2.2 sql文件
      • 2.2.3 交易Mapper接口
    • 2.3 Canal监听器类
    • 2.4 测试

1 Canal搭建

1.1 简介

1.1.1 概述

Canal 是阿里巴巴开源的一个用于高效抓取 MySQL 数据库增量变更日志(binlog)并进行处理的中间件。它可以将 MySQLbinlog 解析为结构化的 JSON 格式,并提供多种方式将这些数据推送到下游系统。

1.1.2 优点

为什么选择Canal?

  • 实时性: Canal 基于MySQLbinlog机制,能够在毫秒级内完成数据同步。
  • 批量获取数据:Canal支持批量获取数据库变更数据,减少网络开销和处理时间。
  • 多线程处理:Canal可以配置多线程来处理不同的数据变更事件,提高整体吞吐量。
  • 断点续传:Canal支持从断点继续消费数据,确保数据不会丢失。
  • 持久化存储:Canal可以将消费进度持久化到ZooKeeper中,保证在故障恢复后能够继续正常工作。
  • 容错机制:Canal内置了多种容错机制,如重试策略和自动恢复功能,提高了系统的可靠性。
  • 标准协议:Canal使用标准化的binlog协议,易于与其他系统集成。
  • 过滤机制:Canal支持灵活的过滤规则,可以选择性地订阅特定的数据库和表。
  • 动态配置:Canal支持动态配置,可以根据实际需求调整监控范围和处理逻辑。
  • 自定义处理:Canal允许开发者编写自定义的处理器,实现复杂的数据处理逻辑。
  • 精确同步:Canal能够精确地捕获和同步数据库的每一行变更,确保数据的一致性。
  • 事务支持:Canal能够处理复杂的事务场景,确保事务的原子性和完整性。
  • 冲突解决:Canal提供了多种冲突解决策略,避免数据同步过程中的冲突问题。

1.1.3 作用&核心组件

Canal 的作用:Canal 通过伪装成 MySQL 的从库(slave),从 MySQL 主库(master)接收 binlog(二进制日志),解析增量变更数据(插入、更新、删除等),并将其推送或存储到目标系统(如 Kafka、Redis、Elasticsearch 等)。
核心组件:

  • Canal Server:负责连接 MySQL,解析 binlog 并提供数据订阅服务。
  • Canal Adapter(可选):用于将 Canal Server 的数据直接写入目标存储(如 ElasticsearchHBaseMySQL 等)。
  • Canal Client(可选):如果需要自定义消费逻辑,可以开发客户端代码来订阅 Canal Server 的数据。
  • 场景需求:如果业务需要实时同步 MySQL 数据(例如同步到 Redis 缓存、Elasticsearch 搜索、Kafka 消息队列等),Canal 是一个轻量且高效的解决方案。

1.2 搭建 Canal

1.2.1 准备工作

1.2.1.1 检查配置

在搭建 Canal 之前,需要确保以下条件:

  • MySQL 配置:
    MySQL 必须开启 binlog,且 binlog 格式为 ROW(行模式)。
    MySQL 需要有一个用户账号,具备 SELECT、REPLICATION SLAVE、REPLICATION CLIENT 等权限,用于 Canal 连接。
  • 环境要求:
    Java 环境:CanalJava 开发的,需要 JDK 1.8 或更高版本。
    服务器:一台运行 Canal Server 的服务器(可以是 ECS 实例或本地机器)。
    目标系统:确保目标系统(如 Redis、Kafka、Elasticsearch)已部署并可访问。
1.2.1.2 MySQL配置

MySQL 配置步骤:

  • 检查 binlog 是否启用:
    SHOW VARIABLES LIKE 'log_bin';,如果显示 OFF,需要启用 binlog
  • 修改 MySQL 配置文件(通常是 /etc/my.cnf/etc/mysql/my.cnf):
[mysqld]
log-bin=mysql-bin          # 启用 binlog
binlog-format=ROW         # 设置 binlog 格式为 ROW
server-id=1               # 唯一服务器 ID,不能与 Canal 的 slaveId 重复

保存后重启 MySQL:service mysql restart

创建 Canal 用户并授权:

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

1.2.2 下载并安装 Canal

Canal 主要包括 canal.deployer(Canal Server),如果需要直接同步到目标存储,可能还需要 canal.adapter

访问 Canal 官方 GitHub 发布页面:https://github.com/alibaba/canal/releases
下载最新版本的 canal.deployer(例如 canal.deployer-1.1.6.tar.gz):

cd ~
wget https://github.com/alibaba/canal/releases/download/canal-1.1.6/canal.deployer-1.1.6.tar.gz

如果需要 Canal Adapter,下载 canal.adapter 包:

wget https://github.com/alibaba/canal/releases/download/canal-1.1.6/canal.adapter-1.1.6.tar.gz

解压 canal.deployer:

mkdir -p /usr/local/canal
tar -zxvf canal.deployer-1.1.6.tar.gz -C /usr/local/canal

解压 canal.adapter:

mkdir -p /usr/local/canal-adapter
tar -zxvf canal.adapter-1.1.6.tar.gz -C /usr/local/canal-adapter

1.2.3 配置 Canal Server

Canal Server 的主要配置文件位于 conf/ 目录下,包括 canal.properties(全局配置)和 conf/example/instance.properties(实例配置)。

1.2.3.1 全局配置

修改全局配置(conf/canal.properties)

打开文件
vi /usr/local/canal/conf/canal.properties确保以下关键配置正确:
# Canal Server 的 ID,Canal Server 的全局标识
canal.id = 1
# Canal 监听的 IP 和端口
canal.ip = 0.0.0.0
canal.port = 11111
# Zookeeper 地址,用于集群模式
canal.zkServers =
# 实例目录
canal.destinations = example
1.2.3.2 实例配置

修改实例配置(conf/example/instance.properties):

打开文件:
vi /usr/local/canal/conf/example/instance.properties配置 MySQL 连接信息和同步规则:
# MySQL 主库地址
canal.instance.master.address = 192.168.XX.XX:3306
# slaveId 是 Canal 实例伪装成 MySQL 从库时的标识,必须与 MySQL 主库的 server-id不同
canal.instance.slaveId = 1234
# MySQL 用户名和密码
canal.instance.dbUsername = canal
canal.instance.dbPassword = canal
# 监听的数据库和表(正则表达式)
canal.instance.filter.regex = .*\\..*  # 监听所有库的所有表
# 同步到的目标(如 Kafka 主题,留空如果直接用 Adapter)
canal.mq.topic =

关于 canal.instance.filter.regex

  • 监听所有表:.*\\..*
  • 监听特定库:mydb\\..*
  • 监听特定表:mydb\\.mytable
  • 多个规则用逗号分隔,例如:mydb\\.table1,mydb\\.table2

注意slaveIdCanal 实例伪装成 MySQL 从库时的标识,必须与 MySQL 主库的 server-id(以及其他从库的 server-id)不同,否则会导致主从复制冲突。如果未显式配置 slaveIdCanal 会使用 canal.id 作为默认 slaveId,这可能导致与 MySQLserver-id 冲突

1.2.3.3 配置目标系统

如果同步到 Kafka,需要配置 Kafka 主题:

canal.mq.topic = mysql_test
canal.mq.partition = 0
1.2.3.4 配置 Canal Adapter

如果需要将数据直接同步到目标存储(如 Elasticsearch、Redis、MySQL),需要配置 Canal Adapter

修改 Adapter 全局配置(/usr/local/canal-adapter/conf/application.yml):

canal:#Canal Server 的地址和端口server: canal-server:11111#与 canal.properties 中的 canal.destinations 一致destination: example

为目标系统添加配置:
/usr/local/canal-adapter/conf/ 下创建目标系统的配置文件,例如同步到 Elasticsearch
创建 es7/user.yml(假设同步 user 表到 Elasticsearch 的 user 索引):

dataSourceKey: defaultDS
destination: example
groupId: g1
esMapping:_index: user_id: user_idsql: "SELECT id AS user_id, username, fullname FROM user"commitBatch: 3000

确保目标系统驱动:
如果同步到 MySQL 8.xElasticsearch 7.x,可能需要更新驱动。例如,替换 MySQL 驱动:

wget https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-8.0.29.zip
unzip mysql-connector-java-8.0.29.zip
mv mysql-connector-java-8.0.29/mysql-connector-java-8.0.29.jar /usr/local/canal-adapter/lib/

1.2.4 启动服务

启动 Canal Server

cd /usr/local/canal
./bin/startup.sh查看日志文件以确保启动成功:
tail -f logs/canal/canal.log
tail -f logs/example/example.log

启动 Canal Adapter:

cd /usr/local/canal-adapter
./bin/startup.sh检查 Adapter 日志:
tail -f logs/adapter/adapter.log

1.2.5 使用 Docker 部署 Canal

如果使用 Docker,可以简化部署流程:

拉取 Canal 镜像:
docker pull canal/canal-server:v1.1.6运行 Canal 容器:
docker run -p 11111:11111 --name canal -d canal/canal-server:v1.1.6进入容器配置:
docker exec -it canal bash
vi /home/admin/canal-server/conf/example/instance.properties

1.3 注意和问题

1.3.1 注意事项

  • binlog 格式:
    确保 MySQLbinlog-formatROW,否则 Canal 无法正确解析数据。
  • 权限:
    Canal 用户需要 REPLICATION SLAVEREPLICATION CLIENT 权限,否则无法接收 binlog。
  • 网络和防火墙:
    确保 Canal Server 能连接到 MySQL(默认端口 3306)和目标系统。
    如果在云环境,配置安全组规则开放 Canal 的端口(默认 11111)。
  • 性能优化:
    对于高并发场景,考虑部署 Canal 集群,并使用 Kafka 确保消息顺序。
    调整 commitBatch(Adapter 配置)以平衡性能和实时性。
  • 版本兼容性:
    确保 Canal 版本与 MySQL 和目标系统兼容。例如,Canal 1.1.4 对 MySQL 8.x 的驱动可能需要手动更新。
  • 监控和维护:
    定期检查 Canal 日志,防止因异常(如 ECS 重启)导致同步中断。
    考虑使用 Canal Admin 提供 Web 管理界面,便于配置和监控。

1.3.2 常见问题

Canal 支持全量同步吗?

Canal 默认只支持增量同步(基于 binlog)。如果需要全量同步,可以结合 DataX 或其他工具先同步全量数据,再用 Canal 同步增量数据。

如何同步到多个目标?

配置多个 Canal Adapter 或开发 Canal Client,分别处理不同的目标系统。或者通过 Kafka 作为中间件,多个消费者订阅同一主题。

1.3.3 为什么既要全局配置又要 实例配置

1.3.3.1 Canal核心模型

Canal 的核心设计是Server-Instance 模型:

  • Canal ServerCanal 的服务端进程,负责管理一个或多个实例,监听客户端连接,提供全局的服务配置(如端口、集群模式等)。
  • Canal Instance:每个实例对应一个具体的 MySQL 数据库实例(或逻辑上的数据源),负责连接 MySQL、解析 binlog、处理数据同步逻辑。

为了支持这种分层架构,Canal 将配置分为两层:

  • 全局配置(canal.properties):定义 Canal Server 级别的通用参数,适用于整个服务进程。
  • 实例配置(instance.properties):定义每个 Instance 的具体行为,针对某个特定的 MySQL 数据源。
1.3.3.2 支持多实例运行

假如 一个 Canal Server 可以同时管理多个 MySQL 数据源(例如,同步多个数据库或多个表的增量数据)。每个数据源的连接信息、过滤规则等可能不同,因此需要为每个数据源单独配置一个 Instance

  • 全局配置的作用:
    定义 Canal Server 的运行环境,例如监听的 IP 和端口(canal.ip、canal.port)、集群模式(canal.zkServers)、全局 ID(canal.id)等。
    指定所有实例的名称列表(canal.destinations),告诉 Server 要加载哪些 Instance。
  • 实例配置的作用:
    为每个 Instance 指定具体的 MySQL 连接信息(如 canal.instance.master.addresscanal.instance.dbUsername)、数据过滤规则(canal.instance.filter.regex)、伪装从库的 ID(canal.instance.slaveId)等。
    每个 Instance 的配置独立存储在 conf/<destination>/instance.properties 中,<destination> 对应 canal.destinations 中定义的实例名称(如 example)。

假设要同步两个 MySQL 数据库(db1 和 db2):
全局配置(canal.properties):

canal.destinations = db1,db2
canal.port = 11111
实例配置:
conf/db1/instance.properties:连接 db1,过滤 db1.table1。
conf/db2/instance.properties:连接 db2,过滤 db2.table2。

一个 Canal Server 通过全局配置加载两个 Instance,分别处理 db1 和 db2 的同步

1.3.3.3 模块化与职责分离

全局配置负责 Server 级别的通用设置,与具体的数据源无关,例如:

  • 网络设置(IP、端口)。
  • 集群配置(Zookeeper 地址)。
  • 数据存储模式(内存、文件、数据库)。
  • 全局性能参数(如线程池大小)。

实例配置负责与特定 MySQL 数据源相关的设置,例如:

  • MySQL 连接信息(地址、用户名、密码)。
  • binlog 解析规则(过滤哪些库或表)。
  • 伪装从库的行为(slaveId)。
  • 目标系统的推送逻辑(例如 Kafka 主题)

2 SpringBoot结合使用

2.1 pom和配置

<dependency><groupId>com.alibaba.otter</groupId><artifactId>canal.client</artifactId><version>1.1.5</version>
</dependency>

application.properties

# 数据源配置
spring.datasource.url=jdbc:mysql://localhost:3306/your_database?useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver# Canal配置
canal.server.ip=127.0.0.1
canal.port=11111
canal.destination=example

2.2 实体和mapper

2.2.1 实体类

@Data
public class Transaction {private Long id;          // 主键IDprivate String transactionId; // 交易IDprivate Double amount;      // 交易金额private String status;      // 交易状态
}

2.2.2 sql文件

CREATE TABLE transaction (id BIGINT AUTO_INCREMENT PRIMARY KEY,transaction_id VARCHAR(50) NOT NULL,amount DECIMAL(18, 2) NOT NULL,status VARCHAR(20) NOT NULL
);

2.2.3 交易Mapper接口

/*** 交易Mapper接口*/
@Mapper
public interface TransactionMapper {/*** 插入一条新的交易记录*/@Insert("INSERT INTO transaction(transaction_id, amount, status) VALUES(#{transaction.transactionId}, #{transaction.amount}, #{transaction.status})")void insert(@Param("transaction") Transaction transaction);/*** 更新一条交易记录*/@Update("UPDATE transaction SET amount=#{transaction.amount}, status=#{transaction.status} WHERE transaction_id=#{transaction.transactionId}")void update(@Param("transaction") Transaction transaction);
}

2.3 Canal监听器类

/*** Canal监听器类,用于监听数据库的变化并进行相应的处理*/
@Component
public class CanalListener {private final String destination = "example"; // 这个值需要与Canal配置中的destination一致private final String serverIp = "127.0.0.1";private final int port = 11111;@Autowiredprivate TransactionMapper transactionMapper;/*** 在Bean初始化后启动Canal监听器*/@PostConstructpublic void start() {// 创建Canal连接器CanalConnector connector = CanalConnectors.newSingleConnector(new InetSocketAddress(serverIp, port), destination, "", "");try {// 连接到Canal服务器connector.connect();// 订阅所有数据库的所有表connector.subscribe(".*\\..*");// 回滚到上次中断的位置connector.rollback();while (true) {// 获取一批消息,最多100条Message message = connector.getWithoutAck(100);long batchId = message.getId();int size = message.getEntries().size();if (batchId == -1 || size == 0) {// 如果没有消息,则等待1秒Thread.sleep(1000);} else {// 处理消息processMessage(message.getEntries());}// 提交确认connector.ack(batchId);}} catch (Exception e) {e.printStackTrace();} finally {// 断开连接connector.disconnect();}}/*** 处理Canal发送过来的消息** @param entryList 消息列表*/private void processMessage(List<CanalEntry.Entry> entryList) {for (CanalEntry.Entry entry : entryList) {// 忽略事务开始和结束事件if (entry.getEntryType() == CanalEntry.EntryType.TRANSACTIONBEGIN || entry.getEntryType() == CanalEntry.EntryType.TRANSACTIONEND) {continue;}CanalEntry.RowChange rowChage;try {// 解析RowChange数据rowChage = CanalEntry.RowChange.parseFrom(entry.getStoreValue());} catch (Exception e) {throw new RuntimeException("ERROR ## parser of eromanga-event has an error , data:" + entry.toString(), e);}CanalEntry.EventType eventType = rowChage.getEventType();// 打印日志System.out.println(String.format("================> binlog[%s:%s] , name[%s,%s] , eventType : %s",entry.getHeader().getLogfileName(), entry.getHeader().getLogfileOffset(),entry.getHeader().getSchemaName(), entry.getHeader().getTableName(),eventType));// 处理每一行数据变化for (CanalEntry.RowData rowData : rowChage.getRowDatasList()) {Transaction transaction = convertToTransaction(rowData.getAfterColumnsList());if (eventType == CanalEntry.EventType.DELETE) {// 处理删除事件(如果需要)} elseif (eventType == CanalEntry.EventType.INSERT) {// 插入新记录transactionMapper.insert(transaction);} else {// 更新现有记录transactionMapper.update(transaction);}}}}/*** 将Canal列数据转换为Transaction对象** @param columns 列数据列表* @return 转换后的Transaction对象*/private Transaction convertToTransaction(List<CanalEntry.Column> columns) {Transaction transaction = new Transaction();for (CanalEntry.Column column : columns) {switch (column.getName()) {case"id":transaction.setId(Long.parseLong(column.getValue()));break;case"transaction_id":transaction.setTransactionId(column.getValue());break;case"amount":transaction.setAmount(Double.parseDouble(column.getValue()));break;case"status":transaction.setStatus(column.getValue());break;}}return transaction;}
}

2.4 测试

插入一条交易记录

curl -X POST http://localhost:8080/api/transactions \
-H "Content-Type: application/json" \
-d '{"transactionId": "TX123", "amount": 100.00, "status": "PENDING"}'

更新一条交易记录

curl -X PUT http://localhost:8080/api/transactions/TX123 \
-H "Content-Type: application/json" \
-d '{"transactionId": "TX123", "amount": 100.00, "status": "COMPLETED"}'

观察后台日志

================> binlog[mysql-bin.000001:1234] , name[your_database,transaction] , eventType : INSERT
id : 1    update=true
transaction_id : TX123    update=true
amount : 100.00    update=true
status : PENDING    update=true
================> binlog[mysql-bin.000001:5678] , name[your_database,transaction] , eventType : UPDATE
-------> before
id : 1    update=false
transaction_id : TX123    update=false
amount : 100.00    update=false
status : PENDING    update=false
-------> after
id : 1    update=false
transaction_id : TX123    update=false
amount : 100.00    update=false
status : COMPLETED    update=true

相关文章:

MySQL数据同步之Canal讲解

文章目录 1 Canal搭建1.1 简介1.1.1 概述1.1.2 优点1.1.3 作用&核心组件 1.2 搭建 Canal1.2.1 准备工作1.2.1.1 检查配置1.2.1.2 &#xff2d;&#xff59;SQL配置 1.2.2 下载并安装 Canal1.2.3 配置 Canal Server1.2.3.1 全局配置1.2.3.2 实例配置1.2.3.3 配置目标系统1.2…...

完整迁移物理机Windows XP到PVE8

计划对2007年部署的windows_xp_professional _service_pack_2_x86系统主机&#xff0c;进行重新部署&#xff0c;由于确实环境包和软件包&#xff0c;无法从头部署&#xff0c;只能考虑带系统环境迁移。原主机年代台久远&#xff08;1Ghz处理器&#xff0c;1G内存&#xff09;G…...

量子加密通信:打造未来信息安全的“铜墙铁壁”

在数字化时代&#xff0c;信息安全已成为全球关注的焦点。随着量子计算技术的飞速发展&#xff0c;传统的加密算法面临着前所未有的挑战。量子计算机的强大计算能力能够轻易破解现有的加密体系&#xff0c;这使得信息安全领域急需一种全新的加密技术来应对未来的威胁。量子加密…...

11.多边形的三角剖分 (Triangulation) : 画廊问题

目录 1.Methodology ​编辑2. Definition 3. Lower & Upper Bound 4.Hardness 5.Approximation & Classification 6. Necessity of floor(n/3) 1.Methodology 多边形三角剖分 点集三角剖分 2. Definition 假设存在一个艺术馆&#xff0c;里面存在很大艺术品需…...

[蓝桥杯 2023 国 Python B] 划分 Java

import java.util.*;public class Main {public static void main(String[] args) {Scanner sc new Scanner(System.in);int[] arr new int[41];int sum 0;for (int i 1; i < 40; i) {arr[i] sc.nextInt();sum arr[i];}sc.close();int target sum / 2; // 最接近的两…...

计算机网络——HTTP/IP 协议通俗入门详解

HTTP/IP 协议通俗入门详解 一、什么是 HTTP 协议&#xff1f;1. 基本定义2. HTTP 是怎么工作的&#xff1f; 二、HTTP 协议的特点三、HTTPS 是什么&#xff1f;它和 HTTP 有啥区别&#xff1f;1. HTTPS 概述2. HTTP vs HTTPS 四、HTTP 的通信过程步骤详解&#xff1a; 五、常见…...

渗透测试中的那些“水洞”:分析与防御

1. Nginx 版本泄露 风险分析&#xff1a; Nginx 默认会在响应头中返回 Server: nginx/x.x.x&#xff0c;攻击者可利用该信息匹配已知漏洞进行攻击。 防御措施&#xff1a; 修改 nginx.conf 配置文件&#xff0c;隐藏版本信息&#xff1a;server_tokens off;使用 WAF 进行信息…...

攻防世界 - Misc - Level 3 | 3-1

&#x1f31f; 关注这个靶场的其它相关笔记&#xff1a;CTF 靶场笔记 —— 攻防世界&#xff08;XCTF&#xff09; 过关思路合集 0x01&#xff1a;考点速览 本题考察的是 Misc 中的流量分析题&#xff0c;想要通过此关&#xff0c;你需要具备以下技术&#xff1a; 会通过 010 …...

安装linux下的idea

1.有可能传不了文件 2.按这个包里的流程装 通过网盘分享的文件&#xff1a;idea旗下所有产品.txt 链接: https://pan.baidu.com/s/1kHHkW3DB3z3a6CG0qnMkWA?pwdgg3f 提取码: gg3f...

【音频】基础知识

1、原始数据 1)音频信号:声音是一种机械波,经过麦克风等设备转化为电信号,再经过模数转换(ADC)变成数字信号,这个数字信号就是音频信号。 2)音频信号的参数: 采样率:一秒钟内对音频的模拟信号采样的个数; 8000Hz:主要用于电话通信 、满足基本的语音通信需求,同时…...

系统思考:企业效率提升关键

最近在辅导一家企业时&#xff0c;我们一起画出了这张图。老板说&#xff1a;“我每天都在救火&#xff0c;员工效率不高&#xff0c;我只能不断加班加点&#xff0c;亲自盯、亲自跑、亲自上阵……” 但图画出来才发现&#xff0c;问题不是出在员工不够努力&#xff0c;也不是老…...

MySQL 查找指定表名的表的主键

原理 SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE TABLE_NAME 表名 AND CONSTRAINT_NAME PRIMARY方法 public static String getPk(String tableName) {String sql "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE TA…...

华为eNSP:IS-IS认证

一、什么是IS-IS认证&#xff1f; 华为eNSP中的IS-IS认证 IS-IS认证是华为eNSP网络中用于保障中间系统到中间系统&#xff08;IS-IS&#xff09;协议通信安全性的核心机制&#xff0c;通过身份验证和数据完整性校验防止非法路由信息注入或篡改。其实现方式与关键特性如下&…...

qemu(4) -- qemu-system-arm使用

1. 前言 参考网上的资料&#xff0c;使用qemu中的vexpress_a9板子&#xff0c;跑一下Linux环境。 2. 源码 2.1 u-boot 可以到U-Boot官网下载对应的源码&#xff0c;我下载的是u-boot-2025.04-rc5.tar.gz&#xff0c;大约24MB。 3.2 linux 可以到The Linux Kernel Archive…...

JavaScript基础-递增和递减运算符

在JavaScript编程中&#xff0c;递增()和递减(--)运算符是操作数值变量的快捷方式。它们能够简洁地对变量值进行加一或减一的操作。尽管看似简单&#xff0c;但正确理解这两种运算符的不同使用方式&#xff08;前缀与后缀&#xff09;对于编写高效且无误的代码至关重要。本文将…...

解决Win10虚拟机“网络连接不上”,“Ethernet0 网络电缆被拔出”的问题

一、情景引入 今天用Win10虚拟机打开浏览器发现&#xff1a; 很奇怪&#xff0c;平常都没有这个问题。 二、检查网络状态 点击更改适配器选项&#xff0c;发现如下&#xff1a; 三、解决问题 打开任务管理器&#xff0c;点击服务&#xff0c;搜索栏搜索&#xff1a;VM …...

【Redis】String详细介绍及其应用场景

文章目录 String类型存储方式set命令get命令mset命令mget命令setnx命令setex和psetex命令incr和decr命令系列append命令--raw选项让redis尝试将二进制数据翻译 getrange命令setrange命令strlen命令字符串类型命令小结string内部的编码方式string类型的典型应用场景1.RedisMySQL…...

C++负载均衡远程调用学习之消息路分发机制

目录 1.LARV0.5-TCP_server链接管理的功能实现及测试 2.LARV0.6 3.LARV0.6 4.LARV0.6 5.LARV0.6-tcp_server集成 6.LARV0.6-tcp_server集成消息路由分发机制总结 7.LARV0.6回顾 1.LARV0.5-TCP_server链接管理的功能实现及测试 ### 16.2 完成Lars Reactor V0.12开发 ###…...

实现了一个基于寄存器操作STM32F103C8t6的工程, 并实现对PA1,PA2接LED正极的点灯操作

#include "stm32f10x.h"// 基于寄存器开发的项目了 int main(){RCC->APB2ENR 0x00000004; // 开启时钟GPIOA->CRL 0x00003330; // 配置引脚 // 0011 0011 0000GPIOA->ODR 0x0000000E; // 1110while(1){} }...

Python字典(dict)详解:从创建到操作全掌握

前言 字典是可变容器&#xff0c;可存储任意类型对象 字典以键(key)-值(value)对的形式进行映射&#xff0c;键值对用冒号分割&#xff0c;对之间用逗号分割 d {key1 : value1, key2 : value2, key3 : value3 } 字典的数据是无序的 字典的键只能用不可变类型&#xff0c;且…...

UDP数据包和TCP数据包的区别;网络编程套接字;不同协议的回显服务器

目录 一、UDP 数据包与 TCP 数据包的区别&#xff1a; 连接方面&#xff1a; 传输方面&#xff1a; 面向对象&#xff1a; 双工模式&#xff1a; 二、UDP 网络编程套接字&#xff1b;基于 UDP 协议的回显服务器&#xff1a; 1. UDP 数据报套接字核心类 DatagramSocket &…...

Python 应用异常追踪实战:如何集成 Sentry 进行高效错误监控

Python 应用异常追踪实战:如何集成 Sentry 进行高效错误监控 引言 在现代应用开发中,异常处理和错误监控至关重要。一个小的运行时错误可能会导致整个系统崩溃,而难以发现的逻辑漏洞可能长期影响用户体验。为了提升代码的稳定性,我们需要一个高效的异常监控机制,以便能够…...

【数据结构】--- 双向链表的增删查改

前言&#xff1a; 经过了几个月的漫长岁月&#xff0c;回头时年迈的小编发现&#xff0c;数据结构的内容还没有写博客&#xff0c;于是小编赶紧停下手头的活动&#xff0c;补上博客以洗清身上的罪孽 目录 前言&#xff1a; 概念&#xff1a; 双链表的初始化 双链表的判空 双链表…...

【C语言练习】014. 使用数组作为函数参数

014. 使用数组作为函数参数 014. 使用数组作为函数参数示例1&#xff1a;使用数组作为函数参数并修改数组元素函数定义输出结果 示例2&#xff1a;使用数组作为函数参数并计算数组的平均值函数定义输出结果 示例3&#xff1a;使用二维数组作为函数参数函数定义输出结果 示例4&a…...

本地服务器备份网站数据,本地服务器备份网站的操作步骤

本地服务器备份网站数据的完整操作指南 一、明确备份需求与目标 核心备份对象 网站文件&#xff1a; 上传的媒体文件&#xff08;图片、视频、PDF等&#xff09; 配置文件&#xff08;如.htaccess、wp-config.php&#xff09; 附加内容&#xff08;根据需求选择&#xff…...

机器学习Day15 LightGBM算法

浅谈LightGBM算法:我们之前讲的集成学习算法分为三要素吧&#xff0c;就是形式&#xff0c;损失函数&#xff0c;优化方法&#xff0c;但是LightGBM算法并没有固定的形式&#xff0c;它主要是针对具体算法给出一些优化&#xff0c;它更像是前向分步算法一样&#xff0c;像一个框…...

算法查找目录

1. 基础数据结构 数组与链表 动态数组 实现与自动扩容机制均摊分析ArrayList/Vector实现 单向链表 基本操作(插入、删除、查找)链表反转环检测(Floyd判圈算法) 双向链表 插入删除操作优化双向遍历优势边界情况处理 循环链表 约瑟夫环问题单向循环链表双向循环链表 跳表 基本原…...

【HarmonyOS】作业三 UI

目录 一. 单选题&#xff08;共10题&#xff0c;10分&#xff09; 1. (单选题, 1分)关于Tabs组件页签的位置设置&#xff0c;下面描述错误的是 2. (单选题, 1分)下面哪个组件不能包含子组件? 3. (单选题, 1分)ArkTS语言的实现计数器功能的组件名称是以下哪个? 4. (单选题…...

2025五一杯数学建模B题:矿山数据处理问题,详细问题分析,思路模型

一、尊重原创&#xff1a;详细内容文末名片获取 二、数据文件解读 &#xff08;一&#xff09;数据文件 1&#xff1a;矿山监测一维数值样例数据.csv 想象一下&#xff0c;这就像是一本简单的记录册&#xff0c;里面记录着一组一维数值序列&#xff0c;每个数据点如同册子里的…...

ES6-Set-Map对象小记

Set 对象 添加元素 set.add(value)常用方法 方法描述has()判断 Set 对象中特定元素是否存在delete()从 Set 对象中删除指定元素clear()清空 Set 对象 遍历方法 很容易想到使用set.forEach(callBackFn, thisArg)方法来进行遍历&#xff0c;其中callBackFn回调的形式如下&am…...

WGCLOUD使用 - 如何监控RabbitMQ运行参数

WGCLOUD是一款开源免费的运维监控软件&#xff0c;开箱即用&#xff0c;实用轻量&#xff0c;高效简单。 RabbitMQ指标数据的采集工作是由server-backup来做的&#xff0c;所以我们需要部署server-backup&#xff0c;它是一个server的辅助工具&#xff0c;作用相当于agent Rabb…...

FreeSWITCH 发送 sip message 的 lua 程序

-- chat.lualocal from argv[1] local to argv[2] local body argv[3] local profile "internal" -- 改成自己的 sip_profileif not body thenstream:write("-ERR miss ie")return endlocal api freeswitch.API() local domain api:executeString(&q…...

安全学习基础入门5集

前言&#xff1a; 来源于b站小迪安全v2023第5天&#xff1a;基础入门-反弹SHELL&不回显带外&正反向连接&防火墙出入站&文件下载_哔哩哔哩_bilibili 环境准备&#xff1a; 通过网盘分享的文件&#xff1a;netcat-1.11 链接: https://pan.baidu.com/s/1zgyYvPf…...

Python结合QT进行开发

Python结合Qt进行开发指南 1. Qt for Python简介 Qt for Python(PySide/PyQt)是Python的官方Qt绑定,允许使用Python语言开发跨平台的GUI应用程序。PySide是Qt官方支持的Python绑定,而PyQt是Riverbank Computing提供的商业/开源版本。 主要特点: 跨平台支持(Windows/macOS…...

Python与深度学习:自动驾驶中的物体检测,如何让汽车“看懂”世界

Python与深度学习:自动驾驶中的物体检测,如何让汽车“看懂”世界 一、引言:自动驾驶的“眼睛”——物体检测 在自动驾驶技术的浪潮中,如何让汽车像人类一样“看懂”周围的环境,成为了最为关键的一环。汽车需要感知道路上的行人、障碍物、交通标志、其他车辆等信息,做出实…...

深度学习-神经网络参数优化的约束与迭代策略

文章目录 前言一、正则化惩罚1、权重正则化&#xff08;Weight Regularization&#xff09;2、结构正则化&#xff08;Structural Regularization&#xff09;3、其他正则化方法 二、梯度下降1、基本原理&#xff08;1&#xff09;梯度下降的计算&#xff08;2&#xff09; 算法…...

PyTorch 与 TensorFlow:深度学习框架的深度剖析与实战对比

PyTorch 与 TensorFlow&#xff1a;深度学习框架的深度剖析与实战对比 摘要 &#xff1a;本文深入对比 PyTorch 与 TensorFlow 两大深度学习框架&#xff0c;从核心架构、优缺点、适用场景等多维度剖析&#xff0c;结合实例讲解&#xff0c;帮助开发者清晰理解两者特性&#x…...

Meta公司于2025年4月29日正式推出了全新Meta AI应用程序的首个版本

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…...

【数据结构】- 栈

前言&#xff1a; 经过了几个月的漫长岁月&#xff0c;回头时年迈的小编发现&#xff0c;数据结构的内容还没有写博客&#xff0c;于是小编赶紧停下手头的活动&#xff0c;补上博客以洗清身上的罪孽 目录 前言&#xff1a; 栈的应用 括号匹配 逆波兰表达式 数制转换 栈的实…...

MATLAB R2024a安装教程

安装步骤&#xff1a; 软件大小&#xff1a;约12.08G 安装环境&#xff1a;Win10~Win11或更高 下载好安装包&#xff0c;可以在网上找个安装包&#xff0c;比如我用国内镜像matlab地址github.com/futureflsl/matlab-chinese-mirror&#xff0c;这样下载稍微快点 1.开始安装…...

【Linux网络】I/O多路转接技术 - poll

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;博客仓库&#xff1a;https://gitee.com/JohnKingW/linux_test/tree/master/lesson &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &…...

24.Linux中RTC的驱动实验_csdn

这个在裸机开发也有&#xff0c;如果有过裸机开发经验的同学就比较入手了&#xff01; 1、Linux 内核 RTC 驱动简介 2、STM32MP1 内部 RTC 驱动分析 像这里的读取时间&#xff0c;是在之前的代码里面已经写好了有关时间计数的代码&#xff0c;直接引用两个寄存器就行。 3、…...

C++负载均衡远程调用学习之TCP连接封装与TCPCLIENT封装

目录 1.LARSV0.3回顾 2.解决粘包问题的message结构体定义 3.LARSV0.4链接对象的方法和属性的定义 4.LARSv0.4 TCP_conn链接的初始化 5.LARV0.4-tcp_conn处理读事件方法do_read 6.LARV0.4-tcp_conn模块回顾 7.LARV0.4-tcp_send_message主动发包实现 8.LARV0.4-tcp_conn处…...

Python TensorFlow库【深度学习框架】全面讲解与案例

一、TensorFlow 基础知识 1. 核心概念 张量 (Tensor): 多维数组&#xff0c;是 TensorFlow 的基本数据单位&#xff08;标量、向量、矩阵等&#xff09;。计算图 (Graph): 早期版本中的静态图机制&#xff08;TF2.x 默认启用动态图&#xff09;。会话 (Session): 在 TF1.x 中…...

日志之ClickHouse部署及替换ELK中的Elasticsearch

文章目录 1 ELK替换1.1 Elasticsearch vs ClickHouse1.2 环境部署1.2.1 zookeeper 集群部署1.2.2 Kafka 集群部署1.2.3 FileBeat 部署1.2.4 clickhouse 部署1.2.4.1 准备步骤1.2.4.2 添加官方存储库1.2.4.3 部署&启动&连接1.2.4.5 基本配置服务1.2.4.6 测试创建数据库和…...

Git 基本操作(一)

目录 git add git commit git log git status git diff git 版本回退 git reset git add git add 指令为添加工作区中的文件到暂存区中。 git add file_name; //将工作区名称为file_name的文件添加进暂存区 git add .; //将工作区中的所有文件添加进暂存区 git comm…...

加密解密记录

一、RSA 加密解密 密钥对生成 1.前端加密解密 &#xff08;1&#xff09;.vue页面引入 npm install jsencrypt&#xff08;2&#xff09;工具 jsencrypt.js import JSEncrypt from jsencrypt/bin/jsencrypt.min// 密钥对生成 http://web.chacuo.net/netrsakeypairconst p…...

Playwright MCP 入门实战:自动化测试与 Copilot 集成指南

什么是 MCP&#xff1f; MCP&#xff08;Model Context Protocol&#xff09; 是一种为大语言模型&#xff08;LLM&#xff09;设计的协议&#xff0c;MCP充当 LLM 与实际应用之间的桥梁或“翻译器”&#xff0c;将自然语言转化为结构化指令&#xff0c;使得模型可以更精确、高…...

存算一体架构下的新型AI加速范式:从Samsung HBM-PIM看近内存计算趋势

引言&#xff1a;突破"内存墙"的物理革命 冯诺依曼架构的"存储-计算分离"设计正面临根本性挑战——在GPT-4等万亿参数模型中&#xff0c;数据搬运能耗已达计算本身的200倍。存算一体&#xff08;Processing-In-Memory, PIM&#xff09;技术通过‌在存储介…...

为 Unity 项目添加自定义 USB HID 设备支持 (适用于 PC 和 Android/VR)-任何手柄、无人机手柄、摇杆、方向盘

这是一份关于如何在 Unity 中为特定 USB HID 设备&#xff08;如 Phoenix SM600 手柄&#xff09;添加支持&#xff0c;并确保其在打包成 APK 安装到独立 VR 设备后仍能正常工作的教程。 目标: 使 Unity 能够识别并处理特定 USB HID&#xff08;Human Interface Device&#x…...