canal1.1.5同步Mysql数据到ES7

文章目录

  • Mysql
    • Mysql8补充——添加mysql8.0.18连接器
  • es
    • ES补充
  • Kibana
  • head
  • canalserver
  • canaladapter
    • 增量同步能力
    • 全量同步能力
      • SQL中的DML和DDL
  • 参考文章:
  • 错误整理:

说明: 本文默认centos7已经安装好了jdk、mysql和elasticsearch

资源准备 下载地址
Mysql5.7
JDK1.8 Es7要求安装jdk11,jdk1.8能运行,不清楚坑多少
ElasticSearch7.12.1集群或单机(7.x +) elasticsearch-7.13.3-linux-x86_64.tar.gz
canal-deployer canal.deployer-1.1.5.tar.gz
canal-adapter canal.adapter-1.1.5.tar.gz
辅助资源准备 下载地址
ElasticSearch7.x—head插件安装
nodejs 或者 grunt
v1.1.5-alpha-2 canal.adapter-1.1.5-SNAPSHOT.tar.gz
kibana kibana-7.13.3-linux-x86_64.tar.gz

需要下载v1.1.5-alpha-2快照版本的canal.adapter-1.1.5.tar.gz(release1.1.5版本的jar包有bug`*)
⚠️注意!!!
⚠️注意!!!
⚠️注意!!!
分别解压缩后,将v1.1.5-alpha-2解压缩文件夹下plugin文件夹中的 client-adapter.es7x-1.1.5-SNAPSHOT-jar-with-dependencies.jar 替换 掉release版本的plugin文件的 client-adapter.es7x-1.1.5-jar-with-dependencies.jar

Mysql

  • 对于自建 MySQL , 需要先开启 Binlog 写入功能,配置 binlog-format 为 ROW 模式,my.cnf 中配置如下

    [mysqld]
    log-bin=mysql-bin # 开启 binlog
    binlog-format=ROW # 选择 ROW 模式
    server_id=1 # 配置 MySQL replaction 需要定义,不要和 canal 的 slaveId 重复
    
    • 注意:针对阿里云 RDS for MySQL , 默认打开了 binlog , 并且账号默认具有 binlog dump 权限 , 不需要任何权限或者 binlog 设置,可以直接跳过这一步
  • 授权 canal 链接 MySQL 账号具有作为 MySQL slave 的权限, 如果已有账户可直接 grant

    CREATE USER canal IDENTIFIED BY 'Canal@123';  
    GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%';
    -- GRANT ALL PRIVILEGES ON *.* TO 'canal'@'%' ;
    FLUSH PRIVILEGES;
    

Mysql8补充——添加mysql8.0.18连接器

  • 默认canal-adapter的lib中只有mysql5.x版本的连接器

    wget https://repo1.maven.org/maven2/mysql/mysql-connector-java/8.0.18/mysql-connector-java-8.0.18.jar
    mv mysql-connector-java-8.0.18.jar /usr/local/canal-adapter/lib/
    chmod 777 /usr/local/canal-adapter/lib/mysql-connector-java-8.0.18.jar #权限修改与其它lib库一致
    chmod +st /usr/local/canal-adapter/lib/mysql-connector-java-8.0.18.jar
    

es

  • 修改配置

    $ vim config/elasticsearch.yml
    cluster.name: es
    node.name: node-1
    # 如果服务器像阿里云这样的, 默认9200端口是没有开放的。如果不开放,下面的1设置不要设置,否则启动不起来
    network.host: 0.0.0.0
    http.port: 9200
    # 作用是开启HTTP对外提供服务,使Head插件能够访问Elasticsearch,修改完成后需要重启es。
    http.cors.enabled: true
    http.cors.allow-origin: “*”
    
  • 新建索引和Mapping(通过kibana或者elasticsearch-head操作)

    要求Mapping中定义的字段名称和类型与待同步数据保持一致。举例:

    PUT /"mytest_user"
    {
    	"settings":{
    		"number_of_shards":5,
    		"number_of_replicas":2
    	},
    	{
    		"mappings": {
    			"properties": {
    				"name": {
    					"type": "text"
    				},
    				"role_id": {
    					"type": "long"
    				},
    				"c_time": {
    					"type": "date"
    				}
    			}
    		}
    	}
    }
    
  • 修改linux内核参数

    vim /etc/security/limits.conf
    

    增加:

    * soft nofile 65536
    * hard nofile 65536
    * soft nproc 2048
    * hard nproc 4096
    #锁住swapping因此需要在这个配置文件下再增加两行代码
    elasticsearch soft memlock unlimited
    elasticsearch hard memlock unlimited
    
    vim /etc/sysctl.conf
    

    增加:

    vm.max_map_count=655360
    fs.file-max=655360
    
    #使系统配置生效(使用root用户)
    sysctl -p
    

ES补充

  • 查看es机群名称:
$ curl http://47.105.208.102:9200/_cat/nodes?v
  • 重建立索引:
curl -XDELETE http://172.16.1.202:9200/nt_product
curl -XPUT -H “Content-Type: application/json” http://172.16.1.202:9200/nt_product?include_type_name=true -d “@nt_product.json”
  • 全量同步一次数据
curl http://172.16.1.2:38081/etl/es/nt_product.yml -XPOST
curl http://127.0.0.1:38081/etl/es/nt_product.yml -X POST
{“timestamp”:“2020-09-23 11:20:17”,“status”:500,“error”:“Internal Server Error”,“message”:"Extension instance(name: es, class: interface com.alibaba.otter.canal.client.adapter.OuterAdapter)

Kibana

$ wget https://artifacts.elastic.co/downloads/kibana/kibana-6.4.0-linux-x86_64.tar.gz
$ tar -xzvf kibana-6.4.0-linux-x86_64.tar.gz
$ mv kibana-6.4.0-linux-x86_64 kibana
$ rm -rf kibana-6.4.0-linux-x86_64.tar.gz

$ vim kibana/config/kibana.yml

server.port: 5601
server.host: "127.0.0.1"
elasticsearch.url: "http://127.0.0.1:9200"
kibana.index: ".kibana6"
:wq!

nohup ./bin/kibana &
# 在浏览器中打开http://192.168.254.131:5601

head

  • 修改head配置
$ vim elasticsearch-head-master/Gruntfile.js
#找到connect属性,修改hostname的值为es的IP
server: {
	options: {
		hostname: ‘127.0.0.1’,
		port: 9100,
		base: ‘.’,
		keepalive: true
	}
}
  • grunt(未整理,需要网络安装)

    # 切换到elasticsearch-head-master目录下,运行启动命令:
    $ grunt server
    
    #启动成功后,输出如下信息:
    Running “connect:server” (connect) task
    Waiting forever…
    Started connect web server on http://localhost:9100
    
  • nojs(也需要安装,有的可以yum安装,可自行百度)

    $ npm run start 或者 npm run start &
    

canalserver

$ mkdir canalserver && cd canalserver
$ tar -zxvf canal.deployer-$version.tar.gz  #可以 -C 指定解压目录
$ vi conf/example/instance.properties

#修改以下属性
canal.instance.master.address=127.0.0.1:3306 # :<内网端口>
canal.instance.dbUsername=canal
canal.instance.dbPassword=Canal@123

canal.instance.connectionCharset=UTF-8 			#代表数据库的编码方式对应到 java 中的编码类型,比如 UTF-8,GBK , ISO-8859-1
canal.instance.enableDruid=false
#canal.instance.parser.parallel=false				#如果系统是1个 cpu
#需要改成同步的数据库表规则,例如只是同步一下表 canal.instance.filter.regex=guli_ucenter.ucenter_member11
#canal.instance.filter.regex=.*\\..*		
#只同步test库的全部表数据
canal.instance.filter.regex=test\\..*
#配置了filter就不用配置下面这一条
# canal.instance.defaultDatabaseName=test

:wq! #保存退出

$ sh bin/startup.sh
$ tailf logs/canal/canal.log
2013-02-05 22:45:27.967 [main] INFO  com.alibaba.otter.canal.deployer.CanalLauncher - ## start the canal server.
2013-02-05 22:45:28.113 [main] INFO  com.alibaba.otter.canal.deployer.CanalController - ## start the canal server[10.1.29.120:11111]
2013-02-05 22:45:28.210 [main] INFO  com.alibaba.otter.canal.deployer.CanalLauncher - ## the canal server is running now ......

$ tailf logs/example/example.log
2013-02-05 22:50:45.636 [main] INFO  c.a.o.c.i.spring.support.PropertyPlaceholderConfigurer - Loading properties file from class path resource [canal.properties]
2013-02-05 22:50:45.641 [main] INFO  c.a.o.c.i.spring.support.PropertyPlaceholderConfigurer - Loading properties file from class path resource [example/instance.properties]
2013-02-05 22:50:45.803 [main] INFO  c.a.otter.canal.instance.spring.CanalInstanceWithSpring - start CannalInstance for 1-example 
2013-02-05 22:50:45.810 [main] INFO  c.a.otter.canal.instance.spring.CanalInstanceWithSpring - start successful....

$ sh bin/stop.sh

mysql 数据解析关注的表,Perl正则表达式.
多个正则之间以逗号(,)分隔,转义符需要双斜杠(\\) 
常见例子:
-  	所有表:.*   or  .*\\..*
-  	canal schema下所有表: canal\\..*
-  	canal下的以canal打头的表:canal\\.canal.*
-  	canal schema下的一张表:canal.test1
-  	多个规则组合使用:canal\\..*,mysql.test1,mysql.test2 (逗号分隔)
注意:此过滤条件只针对row模式的数据有效(ps. mixed/statement因为不解析sql,所以无法准确提取tableName进行过滤)

Canal-server模拟MySQL集群的一个slave,获取MySQL集群Master节点的二进制日志(binary log),并将日志推送给Canal-adapter

canaladapter

client-adapter分为适配器和启动器两部分, 适配器为多个fat jar, 每个适配器会将自己所需的依赖打成一个包, 以SPI的方式让启动器动态加载, 目前所有支持的适配器都放置在plugin目录下

启动器为 SpringBoot 项目, 支持canal-client启动的同时提供相关REST管理接口

$ mkdir canaladapter && cd canaladapter
$ tar -zxvf canal.adapter-$version.tar.gz  #可以 -C 指定解压目录
$ vim conf/application.yml

# 修改以下配置
  srcDataSources:
    defaultDS:
      url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf-8&autoReconnect=true
      username: canal
      password: Canal@123
  - instance: example # canal instance Name or mq topic name	
    groups:							# 分组列表
    - groupId: g1				# 分组ID,如果是mq模式,将用到该值
      outerAdapters:
      - name: logger		# 将受到的变更事件通过日志打印的方式进行输出,仅此配置即可,不需要打印可以注释掉
      - name: es7
        key: es-test 		# 这里是全量导入时的taskid
        hosts: 127.0.0.1:9200 # 127.0.0.1:9200 for rest mode # es 集群地址,逗号分隔 host1:9200,host2:9200
        properties:
          mode: rest # transport # or rest
#          # security.auth: test:123456 #  only used for rest mode
          cluster.name: es		## es cluster name 可以通过 curl 172.16.1.2:9200/_cat/nodes?v 查看
:wq! 保存退出

# adapter将会自动加载 conf/es 下的所有.yml结尾的配置文件
$ vim conf/es7/mytest_user.yml

dataSourceKey: defaultDS        # 源数据源的key, 对应上面配置的srcDataSources中的值
outerAdapterKey: es-test     		# 对应application.yml中es配置的key 
destination: example            # cannal的instance或者MQ的topic
groupId:                        # 对应MQ模式下的groupId, 只会同步对应groupId的数据
esMapping:
  _index: test_user           # es 的索引名称,需要先在es中手动创建索引
# es7下无需配置此项_type,需要删除此行
  _type: _doc                   # es 的type名称,
  _id: _id                      # es 的_id, 如果不配置该项必须配置下面的pk项_id则会由es自动分配
#  pk: id                       # 如果不需要_id, 则需要指定一个属性为主键属性
# sql映射,需要自己编辑对应的sql,否则无法插入到es中
  sql: "select a.id as _id, a.name, a.role_id, a.c_time from user a"
#  objFields:
#    _labels: array:;           # 数组或者对象属性, array:; 代表以;字段里面是以;分隔的
#    _obj: object               # json对象
  etlCondition: "where a.c_time>='{0}'"     # etl 的条件参数
  commitBatch: 3000                         # 提交批大小
:wq!  # 保存退出

$ sh bin/startup.sh
$ tailf logs/adapter/adapter.log
#不报错就可以

说明:

  • 一份数据可以被多个group同时消费, 多个group之间会是一个并行执行, 一个group内部是一个串行执行多个outerAdapters, 比如例子中logger和hbase
  • 目前client adapter数据订阅的方式支持两种,直连canal server 或者 订阅kafka/RocketMQ的消息
  • zookeeperHosts填了以后,可以支持分布式锁;如果对接Canal-Server为集群模式,那么还是需要填写的,具体原因见下面高可用部分。

网上的自定义yml的另一种配置:(未验证)

canal1.1.5同步Mysql数据到ES7_第1张图片

适配器配置介绍——adapter定义配置部分

canal.conf:
  canalServerHost: 127.0.0.1:11111          # 对应单机模式下的canal server的ip:port
  zookeeperHosts: slave1:2181               # 对应集群模式下的zk地址, 如果配置了canalServerHost, 则以canalServerHost为准
  mqServers: slave1:6667 #or rocketmq       # kafka或rocketMQ地址, 与canalServerHost不能并存
  flatMessage: true                         # 扁平message开关, 是否以json字符串形式投递数据, 仅在kafka/rocketMQ模式下有效
  batchSize: 50                             # 每次获取数据的批大小, 单位为K
  syncBatchSize: 1000                       # 每次同步的批数量
  retries: 0                                # 重试次数, -1为无限重试
  timeout:                                  # 同步超时时间, 单位毫秒
  mode: tcp # kafka rocketMQ                # canal client的模式: tcp kafka rocketMQ
  srcDataSources:                           # 源数据库
    defaultDS:                              # 自定义名称
      url: jdbc:mysql://127.0.0.1:3306/mytest?useUnicode=true   # jdbc url 
      username: root                                            # jdbc 账号
      password: 121212                                          # jdbc 密码
  canalAdapters:                            # 适配器列表
  - instance: example                       # canal 实例名或者 MQ topic 名
    groups:                                 # 分组列表
    - groupId: g1                           # 分组id, 如果是MQ模式将用到该值
      outerAdapters:                        # 分组内适配器列表
      - name: logger                        # 日志打印适配器
......           

说明:

  1. 一份数据可以被多个group同时消费, 多个group之间会是一个并行执行, 一个group内部是一个串行执行多个outerAdapters, 比如例子中logger和hbase
  2. 目前client adapter数据订阅的方式支持两种,直连canal server 或者 订阅kafka/RocketMQ的消息

3)日志格式修改

logback.xml中默认日志等级为debug,线上使用时,记得改到info,否则日志会打爆

增量同步能力

  1. DML 增量同步

完成上面的配置,启动后就能正常订阅增量数据了。Adapter能够接收到mq到信息,并在目标库投递成功。

具体会打出如下日志。

canal1.1.5同步Mysql数据到ES7_第2张图片

2)DDL同步

如果需要使用DDL同步能力,必须配置mirroDb为true才可以。

基于canal的client-adapter数据同步必读指南

全量同步能力

  • 首次全量导入curl http://localhost:8081/etl/es7/es-test/test_user.yml -X POST

    参见源码:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pwI7XfZ6-1625822939437)(/Users/wangjunjie/Library/Application Support/typora-user-images/image-20210709145454907.png)]

SQL中的DML和DDL

  • DML(data manipulation language):数据操作语言。

SQL (结构化查询语言)是用于执行查询的语法。但是 SQL 语言也包含用于更新、插入和删除记录的语法。

查询和更新指令构成了 SQL 的 DML 部分:
* SELECT - 从数据库表中获取数据
* UPDATE - 更新数据库表中的数据
* DELETE - 从数据库表中删除数据
* INSERT INTO - 向数据库表中插入数据

  • DDL(data definition language):数据定义语言。

SQL 的数据定义语言 (DDL) 部分使我们有能力创建或删除表格。我们也可以定义索引(键),规定表之间的链接,以及施加表间的约束。

SQL 中最重要的 DDL 语句:
* CREATE DATABASE - 创建新数据库
* ALTER DATABASE - 修改数据库
* CREATE TABLE - 创建新表
* ALTER TABLE - 变更(改变)数据库表
* DROP TABLE - 删除表
* CREATE INDEX - 创建索引(搜索键)
* DROP INDEX - 删除索引

因为经常混淆这两个概念,所以想了一个办法记住。DML顾名思义,主要针对的对象是数据。所以像是SELECT、UPDATE、DELETE、INSERT INTO这些命令是对数据库里表中的数据进行操作的语言,而DDL主要是在定义或改变表的结构,数据类型,表之间的链接和约束等初始化工作上,所以主要是通过CREATE、ALTER、DROP这些命令进行操作的语言。

参考文章:

  1. https://www.cnblogs.com/awan-note/p/13617407.html
  2. https://github.com/alibaba/canal/wiki/AdminGuide

错误整理:

https://editor.csdn.net/md/?articleId=118611902

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