主要用途是基于 MySQL 数据库增量日志解析,提供增量数据订阅和消费
工作原理
- canal 模拟 MySQL slave 的交互协议,伪装自己为 MySQL slave ,向 MySQL master 发送 dump 协议
- MySQL master 收到 dump 请求,开始推送 binary log 给 slave (即 canal )
- canal 解析 binary log 对象(原始为 byte 流)
本文主要讲解MySQL利用cannal将数据同步至Elasticsearch,实现数据读写分离。
1. MySQL操作
开启MySQL的binlog写入功能。此处以MySQL8为例,修改my.cnf文件,示例:
[mysqld]
## MySQL服务ID(局域网内唯一)
server_id=8080
## 指定不需同步的数据库名称
binlog-ignore-db=mysql
## 开启二进制日志功能
log-bin=mall-mysql-bin
## 设置二进制使用内存大小(单次事务)
binlog_cache_szie=1M
## 设置使用二进制日志格式(mixed / statement / row)
binlog_format=row
## 二进制过期清理时间,默认0(不清理)
expire_logs_days=7
## 跳过复制时产生异常的状态码,避免中断(1062:主键重复异常)
slave_skip_errors=1062
配置完成后重启MySQL,并查看是否配置成功:
show variables like '%log_bin%'
查看MySQL的binlog模式:
show variables like '%binlog_format%'
创建一个拥有从库权限的账号,用于订阅binlog,用户名/密码:canal/canal,示例:
CREATE USER cannal IDENTIFIED BY 'cannal';
GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'cannal'@'%';
FLUSH PRIVILEGES;
创建数据库(cannal),创建数据表(test)
DROP TABLE IF EXISTS `test`;
CREATE TABLE `test` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(100) COLLATE utf8_bin DEFAULT NULL,
`price` double(10,5) DEFAULT NULL,
`update_time` datetime DEFAULT NULL,
`create_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
SET FOREIGN_KEY_CHECKS = 1;
2. Cannal deployer操作
修改配置文件conf/example/instance.properties,主要修改数据库配置。
启动cannal-deployer:
./bin/startup.sh
查看启动日志,判断是否启动成功:
tail -f -n 1000 logs/cannal/cannal.log
查看instance日志,判断是否运行成功:
tail -f -n 1000 logs/example/example.log
3. Cannal adapter操作
修改配置文件conf/application.yml。
添加配置文件conf/es7/product.yml,用于配置MySQL中的表与Elasticsearch中索引的映射关系;
dataSourceKey: defaultDS
destination: example
groupId: g1
esMapping:
_index: test # 索引名称
_id: _id
sql: "SELECT
t.id AS _id,
t.name,
t.price
t.update_time,
t.create_time
FROM
test t" # SQL映射
etlCondition: "where a.c_time>={}" # stl条件参数
commitBatch: 3000 # 提交批量大小
启动cannal adapter:
./bin/startup.sh
查看启动日志:
tail -f -n 1000 logs/adapter/adapter.log
4. Elasticsearch操作
创建索引:
PUT test
{
"mappings": {
"properties": {
"name": {
"type": "text"
},
"price": {
"type": "double"
},
"update_time": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
},
"create_time": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
}
}
}
}
向MySQL test数据表中插入数据,再读取ES test索引数据验证同步是否成功。