【Windows】搭建canal服务
Canal介绍
一般在统计分析功能中,我们会采取Feign服务调用获取统计数据,这样耦合度高,效率相对较低,目前采取另一种实现方式,通过实时同步数据库表的方式实现,例如我们要统计每天注册与登录人数,我们只需把会员表同步到统计库中,实现本地统计就可以了,这样效率更高,耦合度更低,Canal就是一个很好的数据库同步工具。canal是阿里巴巴旗下的一款开源项目,纯Java开发。基于数据库增量日志解析,提供增量数据订阅&消费,目前主要支持了MySQL。
canal的原理是基于mysql binlog技术,所以这里一定需要开启mysql的binlog写入功能。
检查binlog功能是否有开启
-- OFF 表示功能未开启
show variables like 'log_bin';
binlog格式
binlog记录格式有两种,statement/row,其中statment记录SQL格式,row格式记录每行的变更内容,控制格式的参数有三种,statement/mix/row,其中mix表示两者的混合
show variables like '%binlog_format%';
如何开启binlog功能
配置my.ini,在[mysqld] 下添加:
log-bin=mysql-bin
binlog_format=ROW
server-id=1
注意:mysql实例id,不能和canal的slaveId重复
binlog命令行参数详解:
- log-bin [=file_name] 此参数表示启用binlog日志功能,并可以定制文件名称,默认为mysql-bin。存放目录是mysql安装目录的data文件夹下。
- binlog_format 此参数配置binlog的日志格式,默认为mixed。
- max_binlog_size此参数配置binlog的日志最大值,最大和默认值是1GB。
- max_binlog_cache_size此参数表示binlog使用最大内存的数。
- binlog-do-db=db_name 此参数表示只记录指定数据库的二进制日志。
- binlog-ignore-db=db_name此参数表示不记录指定的数据库的二进制日志。
- expire_logs_days 此参数表示binlog日志保留的时间,默认单位是天。
重启mysql
-- 关闭服务
net stop mysql
-- 开启服务
net start mysql
重启后在D:\softinstall\mysql\mysql-5.7.38-winx64\data\目录下会产生mysql-bin.000001 和 mysql-bin.index 两个文件。
查看二进制文件
在dos命令行中,进入到mysql的安装目录下,即D:\softinstall\mysql\mysql-5.7.38-winx64,再进到bin/目录下,执行mysqlbinlog命令查看日志:
mysqlbinlog ../data/mysql-bin.000001
为了方便查看日志内容 可以导出到.sql文件
mysqlbinlog ../data/mysql-bin.000001 ->a.sql
可以通过show master status来查看当前写入的binlog的位点,其中:
- File表示下一个binlog的bytes内容即将写入的文件名
- position表示下一个binlog的bytes内容写入到file中的位点的起点(byte字节数)
- Binlog_Do_DB表示需要记录binlog的库名列表,也就是白名单
- Binlog_Ignore_DB表示需要忽略的binlog的库名列表,也就是黑名单
- Executed_Gtid_Set表示本库中已经执行完的全局事务的id集合
可以通过show binary logs来查看binlog列表,表示本地保存的binlog及其大小(byte字节数)
在mysql里面添加以下的相关用户和权限
CREATE USER 'canal'@'%' IDENTIFIED BY 'canal';
-- 注意权限问题,否则在后续的一些操作中会提示没有权限
GRANT ALL PRIVILEGES ON *.* TO 'canal'@'%';
FLUSH PRIVILEGES;
下载安装Canal服务
推荐canal1.1.5,只需要使用jdk1.8。canal1.1.6,该版本需要使用jdk11+
1)canal角色
- canal-admin:canal控制台,可以统一管理canal服务
- canal-deployer:也是canal-server:canal的一个节点服务
- canal-instance:canal-server中的一个处理实例,可以处理不同的业务逻辑
- canal-adaper:canal适配器,canal 1.1.1之后,提供了适配器功能,可将canal server的数据直接输出到目的地,不需要用户编写客户端(个性化需求还需要用户编写客户端实现)
2)下载地址
https://github.com/alibaba/canal/releases
安装canal-admin
下载canal-admin,解压。
执行脚本
SQL脚本位置:conf/canal_manager.sql
脚本中是单独创建了一个数据库canal_manager,我们也可以不单独创建数据库,与其他业务表放在一起
替换mysql connector
因为我是用的mysql8.0,而canal-admin中默认提供的驱动器是mysql5.0的,因此要替换一下(canal-admin解压目录的lib文件夹),同时确认是否需要授权(Linux下可能需要有权限)
下载地址:https://dev.mysql.com/downloads/connector/j/
修改配置文件
conf/application.yml
修改内容:
server:
port: 8089
spring:
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
spring.datasource:
address: 127.0.0.1:3306
database: test
username: canal
password: canal
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://${spring.datasource.address}/${spring.datasource.database}?useUnicode=true&characterEncoding=UTF-8&useSSL=false
hikari:
maximum-pool-size: 30
minimum-idle: 1
#canal admin账号和密码
canal:
adminUser: admin
adminPasswd: 123456
启动
点击bin/startup.bat
2023-06-17 13:53:04.350 [main] INFO com.alibaba.otter.canal.admin.CanalAdminApplication - Started CanalAdminApplication in 4.537 seconds (JVM running for 5.09)
启动成功后,访问:http://127.0.0.1:8089/,输入默认账号admin/123456
集群管理
在集群管理中,点击新建集群,新建一个集群配置。这里的zk地址就是服务端集群的zk地址。
Canal的集群原理是指如何将多个Canal节点组成一个集群,以提高系统的可用性和扩展性。
注意:如果数据库的canal用户权限受限,是无法成功保存集群信息的,此时需要为canal用户重新授权,并重新启动canal-admin。
服务端deployer配置
下载canal-deployer,解压。
替换mysql connector
因为我是用的mysql8.0,而canal-admin中默认提供的驱动器是mysql5.0的,因此要替换一下(canal-deployer解压目录的lib文件夹)
修改配置文件
在conf目录下,备份canal.properties,将canal_local.properties重命名为canal.properties。
修改内容:
# 当前节点ip
canal.register.ip = 127.0.0.1
# admin的地址和账号密码
canal.admin.manager = 127.0.0.1:8089
canal.admin.port = 11110
canal.admin.user = admin
# admin密码,使用了mysql的password加密后的密码,与admin的conf/applicaiton.yml中设置的密码对应
canal.admin.passwd = 6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9
# 开启自动注册模式
canal.admin.register.auto = true
# 指定注册的集群名
canal.admin.register.cluster = cluster-one
# 注册到admin上的服务名,默认为当前ip
canal.admin.register.name = server-01
如果要调整admin密码,可以通过如下mysql指令设置:
# mysql5.0
select password('xxx')
# mysql8.0
select upper(sha1(unhex(sha1('xxx'))))
启动服务
startup.bat
管理端admin配置
一般情况server启动后会自动注册到admin中。
如果没有自动注册的话,就点击“新建Server”手动添加一下
之后我们就可以在【操作-日志】中查看到server的日志情况
网上有朋友遇到以下问题,那是因为jdk的版本问题。canal1.1.5使用jdk1.8即可,我使用的是canal1.1.6,该版本需要使用jdk11+,否则会报错NoSuchMethodError。
java.lang.NoSuchMethodError: java.nio.ByteBuffer.clear()Ljava/nio/ByteBuffer;
at com.alibaba.otter.canal.client.impl.SimpleCanalConnector.readNextPacket(SimpleCanalConnector.java:412) ~[na:na]
at com.alibaba.otter.canal.client.impl.SimpleCanalConnector.readNextPacket(SimpleCanalConnector.java:397) ~[na:na]
at com.alibaba.otter.canal.client.impl.SimpleCanalConnector.doConnect(SimpleCanalConnector.java:155) ~[na:na]
at com.alibaba.otter.canal.client.impl.SimpleCanalConnector.connect(SimpleCanalConnector.java:116) ~[na:na]
at com.alibaba.otter.canal.connector.tcp.consumer.CanalTCPConsumer.connect(CanalTCPConsumer.java:63) ~[na:na]
at com.alibaba.otter.canal.adapter.launcher.loader.AdapterProcessor.process(AdapterProcessor.java:185) ~[client-adapter.launcher-1.1.6.jar:na]
在主配置中统一修改集群下的服务端deployer的配置文件,也可以统一的查看集群下的服务端实例。
在【Instance管理】中新增一个实例,也就是我们之前在服务端的conf文件夹下配置的,每一个子文件夹就代表了一个实例,每个实例都有自己的instance.properties配置文件,这里新增的实例就是这个配置文件:
在使用canal进行数据库日志获取的时候,第一次获取需要获取全量日志。在instance.properties中是可以进行配置的。其中:
- canal.instance.master.journal.name
- canal.instance.master.position
- canal.instance.master.timestamp
这几个属性可以控制获取日志时候的起始位置。但是配置后重启canal并没有起作用。这是因为还需要消除canal目前的状态,就是将与instance.properties平级的meta.dat文件删除,这样canal才能从指定的位置获取日志。
配置示例:
# 需要连接的数据库地址及端口
canal.instance.master.address=127.0.0.1:3306
#需要读取的起始的binlog文件
canal.instance.master.journal.name=mysql-bin.000003
#需要读取的起始的binlog文件的偏移量,通过show master status可以查看
canal.instance.master.position=14445
#需要读取的起始的binlog的时间戳
canal.instance.master.timestamp=
# 数据库账号
canal.instance.dbUsername=canal
# 数据库密码
canal.instance.dbPassword=canal
# 数据库解析编码格式
canal.instance.connectionCharset = UTF-8
# mysql 数据解析关注的表,Perl正则表达式
canal.instance.filter.regex=.*\\..*
# canal将会过滤那些不符合要求的table,这些table的数据将不会被解析和传送
canal.instance.filter.black.regex=
点击"操作-启动"就可以启用该实例
客户端adapter配置
针对客户端adapter,admin是不做管理的,如上我们配置了一个cluster的实例,如果要实现数据同步,我们还需要配置该实例对应的客户端来将该数据同步到目标数据源。
Canal Java 入门与使用
Canal提供了各种语言的客户端,当Canal监听到binlog变化时,会通知Canal的客户端。不过这里我们会使用GitHub上的第三方开源的canal-starter。
引入依赖:
<dependency>
<groupId>top.javatool</groupId>
<artifactId>canal-spring-boot-starter</artifactId>
<version>1.2.1-RELEASE</version>
</dependency>
编写配置文件:
canal:
server: 127.0.0.1:11111
destination: test-instance # canal实例名
编写监听器:
import com.alibaba.fastjson2.JSONObject;
import com.harvey.entity.HistoryLog;
import org.springframework.stereotype.Component;
import top.javatool.canal.client.annotation.CanalTable;
import top.javatool.canal.client.handler.EntryHandler;
@CanalTable("history_log") //需要监听的表
@Component
public class HistoryLogHandler implements EntryHandler<HistoryLog> {//指定表关系实体类
@Override
public void insert(HistoryLog historyLog) {
//新增数据时执行此方法
System.out.println("insert:" + JSONObject.toJSONString(historyLog));
}
@Override
public void update(HistoryLog before, HistoryLog after) {
//更新数据时执行此方法
System.out.println("update before:" + JSONObject.toJSONString(before));
System.out.println("update after:" + JSONObject.toJSONString(after));
}
@Override
public void delete(HistoryLog historyLog) {
//删除数据时执行此方法
System.out.println("delete:" + JSONObject.toJSONString(historyLog));
}
}
实体类定义如下:
import lombok.Data;
import javax.persistence.Column;
import javax.persistence.Table;
import java.util.Date;
@Data
@Table(name = "history_log")
public class HistoryLog {
@Column(name = "log_id")
private Long logId;
@Column(name = "log_msg")
private String logMsg;
@Column(name = "create_time")
private Date createTime;
}
项目启动后,我们往数据库中插入数据,在控制台可以看到日志就证明成功了。
Canal总结
canal的好处在于对业务代码没有侵入,因为是基于监听binlog日志去进行同步数据的。实时性也能做到准实时,其实是很多企业一种比较常见的数据同步的方案。
实际项目我们是配置MQ模式,配合RocketMQ或者Kafka,canal会把数据发送到MQ的topic中,然后通过消息队列的消费者进行处理。
Canal的部署也是支持集群的,需要配合ZooKeeper进行集群管理。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
2022-06-09 随机数字工具类
2022-06-09 随机日期工具类
2022-06-09 随机字符串工具类
2022-06-09 Java创建文件及写文件
2022-06-09 日期时间工具类
2022-06-09 多种文件上传的方式