利用canal实时同步mysql数据至elasticsearch

本次测试环境为单机,测试中需要用到docker环境,关于docker的安装配置不在本文讨论范围

操作系统为centos7.5,mysql版本为5.7.25

通过canal对mysql数据库的增删改进行实时同步测试

elasticsearch和kibana安装配置

采用docker安装这两个软件,具体步骤如下:

# 拉取elasticsearch镜像
docker pull elasticsearch:6.4.2  # 版本号可自行选择,但不大于6
# 启动elasticsearch容器
docker run -d -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:6.4.2
# 运行完以上命令后,在浏览器访问es所在服务器ip和端口9200即可访问到es

# 拉取kibana镜像
docker pull kibana:6.4.2
# 启动kibana容器,注意es_container_id是上边启动的es容器的id
docker run -d --link es_container_id:elasticsearch -p 5601:5601 kibana:6.4.2
# 运行起来后,可在浏览器访问 服务器ip和端口5601即可访问kibana了,在kibana中可以操作es

关于es和kibana的操作不在此赘述

mysql配置

mysql需要开启binlog,本次设置如下:

[mysqld]
server_id=1
log_bin = mysql-bin
binlog_format = ROW

jdk8安装

网上搜索即可,资料很多,可参考 https://www.cnblogs.com/mituxiaogaoyang/p/9836521.html

canal server和canal adapter安装

下载网址:https://github.com/alibaba/canal/releases

下载 canal.deployer-1.1.4.tar.gz

在服务器创建 目录 canal,将canal.deployer-1.1.4.tar.gz放入canal内解压tar -zxvf canal.deployer-1.1.4.tar.gz

修改conf/example/instance.properties,主要修改以下内容

canal.instance.master.address:数据库地址,例如127.0.0.1:3306
canal.instance.dbUsername:数据库用户
canal.instance.dbPassword:数据库密码

回到bin目录下启动canal,运行./startup.sh,运行后查看logs/example/example.log是否有报错,如果有com.alibaba.druid.sql.parser.ParserException: syntax error, error in :'XX') …此类问题,解决方法是 在conf/canal.properties文件里,将如下所示的一行配置信息注释掉,然后重启就好了。

#canal.instance.tsdb.spring.xml=classpath:spring/tsdb/h2-tsdb.xml    

下载 canal.adapter-1.1.4.tar.gz
在服务器创建 目录 canal.adapter,将canal.adapter-1.1.4.tar.gz放入canal内解压tar -zxvf canal.adapter-1.1.4.tar.gz

修改conf/application.yml文件,可参考https://github.com/alibaba/canal/wiki/Sync-ES

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 # kafka rocketMQ
  canalServerHost: 127.0.0.1:11111
#  zookeeperHosts: slave1:2181
#  mqServers: 127.0.0.1:9092 #or rocketmq
#  flatMessage: true
  batchSize: 500
  syncBatchSize: 1000
  retries: 0
  timeout:
  accessKey:
  secretKey:
  srcDataSources:
    defaultDS:
    # 修改url地址,用户名密码
      url: jdbc:mysql://127.0.0.1:3306/canal_test?useUnicode=true
      username: root
      password: heyin 
  canalAdapters:
  - instance: example # canal instance Name or mq topic name
    groups:
    - groupId: g1
      outerAdapters:
#      - name: logger
#      - name: rdb
#        key: mysql1
#        properties:
#          jdbc.driverClassName: com.mysql.jdbc.Driver
#          jdbc.url: jdbc:mysql://127.0.0.1:3306/mytest2?useUnicode=true
#          jdbc.username: root
#          jdbc.password: 121212
#      - name: rdb
#        key: oracle1
#        properties:
#          jdbc.driverClassName: oracle.jdbc.OracleDriver
#          jdbc.url: jdbc:oracle:thin:@localhost:49161:XE
#          jdbc.username: mytest
#          jdbc.password: m121212
#      - name: rdb
#        key: postgres1
#        properties:
#          jdbc.driverClassName: org.postgresql.Driver
#          jdbc.url: jdbc:postgresql://localhost:5432/postgres
#          jdbc.username: postgres
#          jdbc.password: 121212
#          threads: 1
#          commitSize: 3000
#      - name: hbase
#        properties:
#          hbase.zookeeper.quorum: 127.0.0.1
#          hbase.zookeeper.property.clientPort: 2181
#          zookeeper.znode.parent: /hbase
      - name: es  # 注意这里的名称要和 conf/下的es目录保持一致
        hosts: 127.0.0.1:9300 # 127.0.0.1:9200 for rest mode
        properties:
#          mode: transport # or rest
#          # security.auth: test:123456 #  only used for rest mode
          cluster.name: docker-cluster # es cluster name,可在es的config目录内的elasticsearch.yml中找到

进入 conf/es目录内,创建文件canal_test.yml,名称自定,adapter会自动加载该目录下的所有.yml文件,编辑该文件写入如下内容:

dataSourceKey: defaultDS
destination: example
groupId: g1
esMapping:
  _index: user  # es的索引名,一定要先创建该索引
  _type: _doc  # 不改动
  _id: _id
  upsert: true
  sql: "select a.id as _id,a.uname,a.age, a.isdelete from user a"
  commitBatch: 3000

es目录中 可以一张Mysql表对应一个yml配置文件

mysql数据库建表语句

CREATE TABLE `user` (
  `id` int(11) NOT NULL,
  `uname` varchar(255) COLLATE utf8_bin DEFAULT NULL,
  `age` int(10) unsigned DEFAULT NULL,
  `isdelete` tinyint(3) unsigned DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

数据库名是 canal_test

es中建立索引

PUT /user/
{
	"settings":{
		"index":{
			"number_of_shards": 3, 
			"number_of_replicas": 0  
		}
	},
	"mappings":{
		"_doc":{
			"properties":{
				"uname": {"type": "text"},
				"age": {"type": "integer"},
				"isdelete": {"type": "integer"}
			}
		}
	}
}

最后启动,运行bin/startup.sh启动即可。

之后mysql的增删改会同步到es中

如果是多个表数据同步到多个es的index中,就需要在canal adapter 目录中的./conf/es/中创建新的yml文件,设置对应的es内容。如果发现同步失败,注意是否是index创建的较晚导致的。

目前测试,不关闭canal的情况下,建立新表,增加新的index,增加新的yml,不会生效,但是重启canal后就生效了。

参考文档:

https://github.com/alibaba/canal/wiki/Sync-ES
https://www.imooc.com/article/288273
https://toutiao.io/posts/y2wxca/preview
https://www.cnblogs.com/liuchuanfeng/articles/7059268.html
https://blog.csdn.net/xiaolong_4_2/article/details/84632753
https://docs.jdcloud.com/cn/jcs-for-elasticsearch/mysqltoes
https://www.jianshu.com/p/9677ca6ca34e
http://www.qiangweikang.com/2019/11/21/ES+Canal+Canal-adapter/

你可能感兴趣的:(数据库)