liunx下通过Canal将MySQL数据同步到Elasticsearch

liunx下通过Canal将MySQL数据同步到Elasticsearch

一、canal背景信息

Canal是Github中开源的ETL(Extract Transform Load)软件

在这里插入图片描述

canal,译意为水道/管道/沟渠,主要用途是基于 MySQL 数据库增量日志解析,提供增量数据订阅和消费

当前的 canal 支持源端 MySQL 版本包括 5.1.x , 5.5.x , 5.6.x , 5.7.x , 8.0.x

在这里插入图片描述

MySQL master 将数据变更写入二进制日志( binary log, 其中记录叫做二进制日志事件binary log events,可以通过 show binlog events 进行查看)
MySQL slave 将 master 的 binary log events 拷贝到它的中继日志(relay log)
MySQL slave 重放 relay log 中事件,将数据变更反映它自己的数据

canal 工作原理:

1.1 canal 模拟 MySQL slave 的交互协议,伪装自己为 MySQL slave ,向 MySQL master 发送dump 协议
1.2 MySQL master 收到 dump 请求,开始推送 binary log 给 slave (即 canal )
1.3 canal 解析 binary log 对象(原始为 byte 流)

二、mysql相关配置

1、由于canal是通过订阅MySQL的binlog来实现数据同步的,所以我们需要开启MySQL的binlog写入功能,并设置binlog-format为ROW模式,我的配置文件为/etc/my.cnf,改为如下内容即可

[mysqld]
log-bin=mall-mysql-bin  #开启二进制日志功能 或者 log_bin=on #开启bin-log日志
binlog_format=row  #设置使用的二进制日志格式(mixed,statement,row)
server_id=101  #设置server_id,同一局域网中需要唯一 , 注意server_id不要和canal的slaveId重复

binlog-ignore-db=mysql    #指定不需要同步的数据库名称
binlog_cache_size=1M  #设置二进制日志使用内存大小(事务)
expire_logs-days=7  #二进制日志过程清理时间。默认为0,表示不自动清理
slave_skip_errors=1062  #跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断  #如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
symbolic-links = 0: #符号连接,如果设置为1,则mysql数据库和表里的数据支持储存在datadir目录之外的路径下,默认都是0(较新版本的mysql下默认是1)
pid-file=/usr/local/mysql/data/mysql.pid
log-error=/usr/local/mysql/data/mysql.log
socket=/var/lib/mysql/mysql.sock
datadir=/usr/local/mysql/data
log-bin=/usr/local/mysql/data/mysql-bin    #设置logbin日志存放目录

2、配置完成后需要重新启动MySQL,重启成功后通过如下命令查看binlog是否启用

SHOW VARIABLES LIKE '%log_bin%';

在这里插入图片描述

3、再查看下MySQL的binlog模式

SHOW VARIABLES LIKE 'binlog_format';

在这里插入图片描述

4、接下来需要创建一个拥有从库权限的账号,用于订阅binlog,这里创建的账号为canal:canal

GREAT USER canal IDENTIFIED BY 'canal';

5、赋予canal用户权限

GRANT SELECT, INSERT,REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%';
FLUSH PRIVILEGES;

6、创建库和创建表

create database elasticsearch;
CREATE TABLE `es_test` (
  `id` int NOT NULL AUTO_INCREMENT,
  `count` text,
  `name` text,
  `color` text,
  PRIMARY KEY (`id`)
) 

三、canal的下载及使用

1、由于不同版本的MySQL、Elasticsearch和canal会有兼容性问题,下面介绍本文涉及到组件的版本

组件 端口 版本
elasticsearch 9200 7.13.2 结合openjdk11使用
kibana 5601 7.13.2 结合openjdk11使用
mysql 3306 8.0.20 结合openjdk11使用
canal-admin 8089 1.16 结合openjdk11使用
canal-server 11111 1.16 结合openjdk11使用
canal-adapter 8081 1.16 结合openjdk11使用

2、下载canal的各个组件canal-servercanal-adaptercanal-admin,下载地址:https://github.com/alibaba/canal/releases

3、canal各个组件功能介绍

canal-server(canal-deploy):可以直接监听MySQL的binlog,把自己伪装成MySQL的从库,只负责接收数据,并不做处理。

canal-adapter:相当于canal的客户端,会从canal-server中获取数据,然后对数据进行同步,可以同步到MySQL、Elasticsearch和HBase等存储中去。

canal-admin:为canal提供整体配置管理、节点运维等面向运维的功能,提供相对友好的WebUI操作界面,方便更多用户快速和安全的操作。
4、canal-server的使用

将我们下载好的压缩包canal.deployer-1.1.6-SNAPSHOT.tar.gz上传到Linux服务器,然后解压到指定目录/home/server,可使用如下命令解压

tar xvzf canal.deployer-1.1.5-SNAPSHOT.tar.gz -C /home/server/

canal-server工作目录如下

在这里插入图片描述

修改conf/example/instance.properties文件,主要注意以下几处:

canal.instance.master.address=127.0.0.1:3306     #mysql主数据库地址
# username/password
canal.instance.dbUsername=canal
canal.instance.dbPassword=canal
canal.instance.connectionCharset = UTF-8
canal.instance.filter.regex=.*\\..*    #需要订阅binlog的表过滤正则表达式

启动canal-server并查看日志

./bin/startup.sh  或者: sh bin/startup.sh
cat logs/canal/canal.log 或者:tail -f logs/example/example.log

在这里插入图片描述

5、canal-adapter的使用

将我们下载好的压缩包canal.adapter-1.1.5-SNAPSHOT.tar.gz上传到Linux服务器,然后解压到指定目录/home/adpter,解压完成后目录结构如下

在这里插入图片描述

修改配置文件conf/application.yml,按如下配置即可,可以注释不需要的配置,主要是修改canal-server配置、数据源配置和客户端适配器配置

在这里插入图片描述

#同步的数据库
  srcDataSources:
    defaultDS:
      url: jdbc:mysql://192.**.**.**:3306/elasticsearch?useUnicode=true&useSSL=true&allowMultiQueries=true&verifyServerCertificate=false&serverTimezone=Asia/Shanghai
      username: canal
      password: canal
  canalAdapters:   # 适配器列表
  - instance: example  #与canal-server中canal.properties的实例名相同
    groups:
    - groupId: g1  #与下面适配器对应
      outerAdapters:
      - name: es7  #es配置,这里使用9200通信 也就是rest模式
        key: es7Key   #对应es的适配器key
        hosts: http://192.**.**.**:9200  # hosts使用的是es的9200端口
        properties:
          mode: rest # or rest
          security.auth: usernama:password
          cluster.name: elasticsearch  #es的集群名称

添加配置文件canal-adapter/conf/es7/es_test.yml,用于配置MySQL中的表与Elasticsearch中索引的映射关系

dataSourceKey: defaultDS
outerAdapterKey: es7Key     # 对应application.yml中es配置的key
destination: example #和上面配置文件对应
groupId: g1 #和配置文件对应
esMapping:
  _index: es_test   #es索引名称
  _id: id   # 需要同步到Elasticsearch实例的文档的id,可自定义。本文使用_id, 如果不配置该项必须配置下面的pk项_id则会由es自动分配
#  relations:
#    customer_order:
#      name: customer
  sql: "select es.id, es.count, es.name,es.color from es_test es" #SQL语句,用来查询需要同步到Elasticsearch中的字段               
#  etlCondition: "where a.c_time>={}"  #etl的条件参数
  commitBatch: 200   # 批量提交的大小

启动Canal-adapter服务,并查看日志

./bin/startup.sh   或者: sh bin/startup.sh
cat logs/adapter/adapter.log  或者:tail -f logs/adapter/adapter.log

四、数据同步演示

经过上面的一系列步骤,canal的数据同步功能已经基本可以使用了,下面我们来演示下数据同步功能。

首先我们需要在Elasticsearch中创建索引,和MySQL中的product表相对应,直接在Kibana的Dev Tools中使用如下命令创建即可;

创建index :

PUT es_test
{
  "settings": {
    "index": {
      "number_of_shards": "3",    #主分片数,默认为1,索引分片对ES的查询性能有很大的影响,在应用环境,应该选择适合的分片大小。
      "number_of_replicas": "0"   #设置默认索引副本个数,默认为1个副本。此处的1个副本是指index.number_of_shards的一个完全拷贝;如果有5个主分片1个副本分片,即总分片数为10。
    }
  }
}
注意:可以在线修改副本分片数 number_of_replicas ,但主分片数 number_of_shards 不可以在线改

定义mappering,由于上面数据库字段类型为text,:

PUT es_test/_doc/_mapping
{
        "properties": {
          "color": {
            "type": "keyword"
          },
          "count": {
            "type": "keyword"
          },
          "name": {
            "type": "keyword"
          }
        }
}

创建成功:

在这里插入图片描述

创建完成后查看索引结构:

在这里插入图片描述

在mysql数据库中插入一条数据:

INSERT INTO `elasticsearch`.`es_test` (`id`, `count`, `name`, `color`) VALUES (1, '99', '不知好歹', '黑色');

Elasticsearch在kibana中搜索下,发现数据已经同步了

GET es_test/_search

在这里插入图片描述

五、canal adpter常见启动报错

java.nio.ByteBuffer.clear()Ljava/nio/ByteBuffer;

解决:canal1.1.6 对应 jdk1.6,版本不对应

missing authentication credentials for REST request  401

五、canal adpter常见启动报错

java.nio.ByteBuffer.clear()Ljava/nio/ByteBuffer;

解决:canal1.1.6 对应 jdk1.6,版本不对应

missing authentication credentials for REST request  401

解决:/home/adpter/conf/application.yml 添加凭证:security.auth

猜你喜欢

转载自blog.csdn.net/lljddddd/article/details/127863611