canal安装可参考:alibaba canal的安装配置及简单使用
版本
mysql 8.0.23
elasticsearch 7.9.3
canal 1.1.5
创建表
先创建要同步的表:
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;
BEGIN;
INSERT INTO `users` VALUES ('1', '杜子腾', '13181838112', '哈皮', '2021-09-17 17:13:00');
COMMIT;
SET FOREIGN_KEY_CHECKS = 1;
创建索引
必须要先创建索引,才能使用canal-adapter同步数据,不然启动canal-adapter会报index_not_found_exception
的错误。打开kibana Dev Tools,创建索引。
PUT /mytest_user/
{
"mappings": {
"properties": {
"username": {
"type": "text"
},
"password": {
"type": "text"
},
"nickname": {
"type": "text"
},
"last_modified":{
"type": "date"
}
}
}
}
修改canal-adapter配置
修改canal-adapter目录下conf/application.yml
为以下内容,并修改srcDataSources
数据库为你的配置。
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 rabbitMQ
flatMessage: true
zookeeperHosts:
syncBatchSize: 1000
retries: 0
timeout:
accessKey:
secretKey:
consumerProperties:
# canal tcp consumer
canal.tcp.server.host: 127.0.0.1:11111
canal.tcp.zookeeper.hosts:
canal.tcp.batch.size: 500
canal.tcp.username:
canal.tcp.password:
srcDataSources:
defaultDS:
url: jdbc:mysql://127.0.0.1:3306/你的数据库名称?useUnicode=true
username: 用户名
password: 密码
canalAdapters:
- instance: example # canal instance Name or mq topic name
groups:
- groupId: g1
outerAdapters:
- name: logger
- name: es7 # or es6
hosts: 127.0.0.1:9200 # 127.0.0.1:9200 for rest mode
properties:
mode: rest #transport # or rest
cluster.name: elasticsearch
修改canal-adapter目录下conf/es7/mytest_user.yml
为以下内容。
dataSourceKey: defaultDS # 源数据源的key, 对应上面配置的srcDataSources中的值
destination: example # cannal的instance或者MQ的topic
groupId: g1 # 对应MQ模式下的groupId, 只会同步对应groupId的数据
esMapping:
_index: mytest_user # 索引名称
_id: _id # es 的_id, 如果不配置该项必须配置下面的pk项_id则会由es自动分配
upsert: true
pk: id
sql: "SELECT id as _id,username as username,phone as phone,nickname as nickname,last_modified as last_modified FROM users"
# objFields:
# _labels: array:;
# etlCondition: "where a.c_time>={}"
commitBatch: 3000 # 提交批大小
启动canal-adapter,sh bin/startup.sh
。
全量同步
输入命令或者Postman发送请求同步全量数据,看到下面的返回就是同步成功了。
curl http://localhost:8081/etl/es7/mytest_user.yml -X POST
查看索引数据,可以看到表中数据已经同步到es。
增量同步
打开日志:tail -f logs/adapter/adapter.log
。
- 新增
mysql表中新增一条数据,可以看到日志输出:
查看索引数据,可以看到新增的数据已经同步到es。
- 删除:
- 更新:
遇到的问题
druid类型转换错误:
查看github issues,# java.lang.ClassCastException: com.alibaba.druid.pool.DruidDataSource cannot be cast to com.alibaba.druid.pool.DruidDataSource,得到两种解决方案:
1、下载源码,将client-adapter.escore的pom.xml的关于druid的配置,设置scope为provider,重新打包后,把canal-adapter安装目录下的plugin/client-adapter.es7x-1.1.5-jar-with-dependencies.jar
替换为新打的包canal/client-adapter/es7x/target/client-adapter.es7x-1.1.5-jar-with-dependencies.jar
。
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<scope>provided</scope>
</dependency>
2、本文使用这种方式,直接下载canal-1.1.5-alpha-2,将canal.adapter-1.1.5-SNAPSHOT
下的plugin/client-adapter.es7x-1.1.5-SNAPSHOT-jar-with-dependencies.jar
名称改为plugin/client-adapter.es7x-1.1.5-jar-with-dependencies.jar
,然后替换到canal-1.1.5的plugin目录下。