利用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/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章