canal–基础–2.1–部署–实时同步MySQL数据到ES
1、准备工作
1.1、环境
IP | 应用 | 版本 |
---|---|---|
192.168.187.89 | canal-deploy | 1.1.7 |
192.168.187.89 | canal-adapter | 1.1.7 |
192.168.187.88 | es | 7.6.2 |
192.168.187.88 | mysql | 8.0.27 |
1.2、安装mysql
1.2.1、启动命令
docker run -d -p 3306:3306 --name mysql8.0.27 -e MYSQL_ROOT_PASSWORD=root --restart=always mysql:8.0.27
1.2.2、MySQL配置
由于canal是通过订阅MySQL的binlog来实现数据同步的,所以需要开启MySQL的binlog写入功能,并设置binlog-format为ROW模式
vim mysql.cnf
[mysqld]
## 指定不需要同步的数据库名称
binlog-ignore-db=mysql
## 开启二进制日志功能
log-bin=master.bin
## 设置二进制日志使用内存大小(事务)
binlog_cache_size=1M
## 设置使用的二进制日志格式(mixed,statement,row)
binlog_format=row
## 二进制日志过期清理时间。默认值为0,表示不自动清理。
expire_logs_days=7
## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断。
## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
slave_skip_errors=1062
1.2.3、重启
# 拷贝配置文件到mysql
docker cp mysql.cnf mysql8.0.27:/etc/mysql/conf.d/mysql.cnf
# 重启
docker restart mysql8.0.27
1.2.4、查看
show variables like '%log_bin%'
show variables like 'binlog_format%';
1.3、安装es
mkdir -p /root/temp/elasticsearch/config
mkdir -p /root/temp/elasticsearch/data
echo "http.host: 0.0.0.0" >> /root/temp/elasticsearch/config/elasticsearch.yml
# 加入跨域配置
echo "http.cors.enabled: true" >> /root/temp/elasticsearch/config/elasticsearch.yml
echo 'http.cors.allow-origin: "*"' >> /root/temp/elasticsearch/config/elasticsearch.yml
docker run -d -p 9200:9200 -p 9300:9300 --name elasticsearch -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms1G -Xmx1G" -v /root/temp/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml --restart=always elasticsearch:7.6.2
1.4、canal下载
# 下载地址
https://github.com/alibaba/canal/releases
1.5、上传canal压缩包
mkdir -p /home/hd/shell/canal
cd /home/hd/shell/canal
2、MySQL 配置
2.1、创建一个拥有从库权限的账号
创建一个拥有从库权限的账号,用于订阅binlog,这里创建的账号为canal:canal
CREATE USER canal IDENTIFIED BY 'canal';
GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%';
FLUSH PRIVILEGES;
2.2、创建测试表
#产品表
DROP TABLE IF EXISTS `product`;
CREATE TABLE `product` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`title` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`sub_title` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`price` decimal(10, 2) NULL DEFAULT NULL,
`pic` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
#用户
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`id` varchar(64) NOT NULL,
`username` varchar(20) NOT NULL COMMENT '用户名',
`phone` varchar(64) NOT NULL COMMENT '手机号',
`nickname` varchar(20) NOT NULL COMMENT '昵称',
`last_modified` timestamp NOT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '最后修改时间',
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`),
UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
3、canal部署–deployer
3.1、解压
cd /home/hd/shell/canal
mkdir deployer
tar -xvf canal.deployer-1.1.7.tar.gz -C deployer/
3.2、修改配置文件conf/example/instance.properties
vim deployer/conf/example/instance.properties
按如下配置即可,主要是修改数据库相关配置
# 需要同步数据的MySQL地址
canal.instance.master.address=192.168.187.88:3306
canal.instance.master.journal.name=
canal.instance.master.position=
canal.instance.master.timestamp=
canal.instance.master.gtid=
# 用于同步数据的数据库账号
canal.instance.dbUsername=canal
# 用于同步数据的数据库密码
canal.instance.dbPassword=canal
# 数据库连接编码
canal.instance.connectionCharset = UTF-8
# 需要订阅binlog的表过滤正则表达式
canal.instance.filter.regex=.*\\..*
3.3、启动
./deployer/bin/startup.sh
4、canal部署–adapter
4.1、解压
cd /home/hd/shell/canal
mkdir adapter
tar -xvf canal.adapter-1.1.7.tar.gz -C adapter/
4.2、修改配置文件conf/application.yml
vim adapter/conf/application.yml
内容
server:
port: 8081
spring:
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
default-property-inclusion: non_null
canal.conf:
mode: tcp # 客户端的模式,可选tcp kafka rocketMQ
flatMessage: true # 扁平message开关, 是否以json字符串形式投递数据, 仅在kafka/rocketMQ模式下有效
zookeeperHosts: # 对应集群模式下的zk地址
syncBatchSize: 1000 # 每次同步的批数量
retries: 0 # 重试次数, -1为无限重试
timeout: # 同步超时时间, 单位毫秒
accessKey:
secretKey:
consumerProperties:
# canal tcp consumer
canal.tcp.server.host: 127.0.0.1:11111 #设置canal-server的地址
canal.tcp.zookeeper.hosts:
canal.tcp.batch.size: 500
canal.tcp.username:
canal.tcp.password:
srcDataSources:
defaultDS:
url: jdbc:mysql://192.168.187.88:3306/test?useUnicode=true
username: canal
password: canal
canalAdapters: # 适配器列表
- instance: example # canal实例名或者MQ topic名
groups: # 分组列表
- groupId: g1 # 分组id, 如果是MQ模式将用到该值
outerAdapters:
- name: logger # 日志打印适配器
- name: es7 # ES同步适配器
hosts: http://192.168.187.88:9200 # ES连接地址
properties:
mode: rest # 模式可选transport(9300) 或者 rest(9200)
# security.auth: test:123456 # only used for rest mode
cluster.name: elasticsearch # ES集群名称
4.3、新增 conf/es7/product.yml,用于同步数据库product表
vim adapter/conf/es7/product.yml
内容
dataSourceKey: defaultDS # 源数据源的key, 对应上面配置的srcDataSources中的值
destination: example # canal的instance或者MQ的topic
groupId: g1 # 对应MQ模式下的groupId, 只会同步对应groupId的数据
esMapping:
_index: canal_product # es 的索引名称
_id: _id # es 的_id, 如果不配置该项必须配置下面的pk项_id则会由es自动分配
sql: "SELECT p.id AS _id, p.title, p.sub_title, p.price, p.pic FROM product p" # sql映射
etlCondition: "where a.c_time>={}" #etl的条件参数
commitBatch: 3000 # 提交批大小
4.4、新增 conf/es7/mytest_user.yml,用于同步数据库users表
vim adapter/conf/es7/mytest_user.yml
内容
dataSourceKey: defaultDS # 源数据源的key, 对应上面配置的srcDataSources中的值
destination: example # canal的instance或者MQ的topic
groupId: g1 # 对应MQ模式下的groupId, 只会同步对应groupId的数据
esMapping:
_index: mytest_user # es 的索引名称
_id: _id # es 的_id, 如果不配置该项必须配置下面的pk项_id则会由es自动分配
sql: "SELECT id as _id,username as username,phone as phone,nickname as nickname,last_modified as last_modified FROM users" #此处的字段需要与es中mapping能对应上
etlCondition: "where a.c_time>={}" #etl的条件参数
commitBatch: 3000 # 提交批大小
4.5、启动
./adapter/bin/startup.sh
4.6、设置配置(可不做)
4.6.1、开启增量同步
curl http://127.0.0.1:8081/syncSwitch/example/on -X PUT
example是你的destination,可以根据自己的实际情况修改。
4.6.2、查询实例example的状态
curl http://127.0.0.1:8081/syncSwitch/example
确保自己的实例是on的状态,不然就只能去log里面查:
{"stauts":"on"}
5、数据同步演示
5.1、es 新增 mapping
PUT http://192.168.187.88:9200/canal_product/
{
"mappings": {
"properties": {
"title": {
"type": "text"
},
"sub_title": {
"type": "text"
},
"pic": {
"type": "text"
},
"price": {
"type": "double"
}
}
}
}
PUT http://192.168.187.88:9200/mytest_user/
{
"mappings": {
"properties": {
"id": {
"type": "keyword"
},
"username": {
"type": "text"
},
"phone": {
"type": "text"
},
"nickname": {
"type": "text"
},
"last_modified":{
"type": "date"
}
}
}
}
5.2、插入数据
INSERT INTO product ( id, title, sub_title, price, pic ) VALUES ( 1, '测试', '测试', 1111, Null);
INSERT INTO `users` VALUES ('1', 'level', '12345678', '李老师', '2024-11-13 15:15:35');
5.3、查询es 数据
GET http://192.168.187.88:9200/canal_product/_search
GET http://192.168.187.88:9200/mytest_user/_search