在实际项目开发中,当数据量规模非常大的时候,通常需要借助ElasticSearch(下面用ES代称)等搜索引擎来解决查询性能压力,但数据库和ES之间如何进行数据同步也是一个重要问题。同步的方案有很多,本文是使用Canal中间件,来模拟成MySQL的Slave,实时接收MySQL的增量数据binlog,然后通过RESTful API将数据写入到ES中。
因为Canal是开源的,可以直接到官方github下载canal.adapter和canal.deployer,我在站里也上传了1.1.5版本。
首先需要开启Mysql的binlog写入功能(8.0版本是默认开启),其它版本可以通过修改my.ini(my.cnf)配置开启,默认位置在Mysql的安装目录,也有的是在隐藏的PeogramData中Mysql目录,添加配置如下:
#开启binlog模式
log_bin=mysql-bin
binlog-format=row
#single DB
binlog-ignore-db=mysql
修改完后,使用命令show variables like ‘%log_bin%’; 查看binlog是否开启成功,成功图例如下:
建立测试数据库test,新建表student:
CREATE TABLE `student` (
`id` bigint NOT NULL AUTO_INCREMENT,
`name` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`city` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`adress` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;
打开canal.deployer安装目录,找到配置文件conf/example/instance.properties,主要修改以下配置:
# 同步数据库地址
canal.instance.master.address=127.0.0.1:3306
# 同步数据库账号密码
canal.instance.dbUsername=root
canal.instance.dbPassword=123456
# 数据库连接编码
canal.instance.connectionCharset = UTF-8
修改完后在bin目录中启动startup.bat,linux环境则启动startup.sh,这样canal服务端就开启了,成功图例如下:
打开canal.adapter安装目录,找到配置文件conf/application.yml,主要修改以下配置:
srcDataSources:
defaultDS: #同步数据库配置
url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true
username: root
password: 123456
canalAdapters: #适配器列表
- instance: example # canal instance Name or mq topic name
groups:
- groupId: g1
outerAdapters:
- name: logger #日志打印
- name: es7 #ES同步适配器
key: es7Key
hosts: http://127.0.0.1:9200 #ES连接地址
properties:
mode: rest
这个配置文件还可以设置很多东西,可以参考其它博主的文章
接着找到conf/es7,在目录下新建student.yml文件,打开配置:
dataSourceKey: defaultDS # 源数据源的key, 对应上面配置的srcDataSources中的值
destination: example
groupId: g1
esMapping:
_index: test_topic #ES的索引名称
_id: _id
sql: "SELECT
s.id as _id,
s.name,
s.city,
s.adress
FROM
student s" # sql映射
etlCondition: "where a.c_time>={}"
commitBatch: 3000 #提交批大小
配置完后在bin目录中启动startup.bat,linux环境则启动startup.sh,这样canal客户端就开启了,成功图例如下:
使用Kibana或者postMan在ES中建立student表索引:
PUT test_topic
{
"mappings": {
"properties": {
"name": {
"type": "text"
},
"city": {
"type": "text"
},
"adress": {
"type": "text"
}
}
}
}
GET test_topic/_search #查看索引
向数据库插入一条数据:
INSERT INTO student (name, city, adress ) VALUES ( '陈先生', ' 广州', '幸福小区99号' );
成功结果:
结果出现ESSyncService记录时才算同步成功,若只有LoggerAdapterExample日志可能发生了jar包冲突
至此就完成了使用Canal实现ElasticSearch和Mysql数据同步的小测试,当然这只是入门,在实际的项目开发中使用Canal则需要更加深入了解…