Canal高可用架构部署

Canal高可用架构部署

一、前言

canal 是阿里的一款开源项目,纯 Java 开发。基于数据库增量日志解析,提供增量数据订阅&消费,目前主要支持了 MySQL(也支持 mariaDB)。

Canal高可用架构部署
  1. canal 模拟 mysql slave 的交互协议,伪装自己为 mysql slave,向 mysql master发送 dump 协议;
  2. mysql master 收到 dump 请求,开始推送binary log给 slave(也就是canal)
  3. canal 解析 binary log对象(原始为byte流)。

总体架构

Canal高可用架构部署

二、部署准备

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

分别下载:canal.admin、canal.deployer、canal.adapter

PS:只有1.1.5以上版本才支持es7.x

其他依赖

  1. JDK1.8
  2. MySQL:用于canal-admin存储配置和节点等相关数据
  3. Zookeeper

三、HA机制

整个 HA 机制的控制主要是依赖了zookeeper的两个特性:watcher、EPHEMERAL节点。canal的 HA 机制实现分为两部分,canal server 和 canal client分别有对应的实现。

Canal高可用架构部署

canal server实现流程如下:

  1. canal server 要启动某个 canal instance 时都先向 zookeeper 进行一次尝试启动判断 (实现:创建 EPHEMERAL 节点,谁创建成功就允许谁启动);
  2. 创建 zookeeper 节点成功后,对应的 canal server 就启动对应的 canal instance,没有创建成功的 canal instance 就会处于 standby 状态;
  3. 一旦 zookeeper 发现 canal server A 创建的节点消失后,立即通知其他的 canal server 再次进行步骤1的操作,重新选出一个 canal server 启动instance;
  4. canal client 每次进行connect时,会首先向 zookeeper 询问当前是谁启动了canal instance,然后和其建立链接,一旦链接不可用,会重新尝试connect。

PS: 为了减少对mysql dump的请求,不同server上的instance要求同一时间只能有一个处于running,其他的处于standby状态。

canal client实现流程

  1. canal client 的方式和 canal server 方式类似,也是利用 zookeeper 的抢占EPHEMERAL 节点的方式进行控制
  2. 为了保证有序性,一份 instance 同一时间只能由一个 canal client 进行get/ack/rollback操作,否则客户端接收无法保证有序。

四、集群部署

4.1. MySQL准备

4.1.1. 开启binlog

MySQL的 my.cnf 中配置如下

[mysqld]
log-bin=mysql-bin # 开启 binlog
binlog-format=ROW # 选择 ROW 模式
server_id=1 # 配置 MySQL replaction 需要定义,不要和 canal 的 slaveId 重复

注意:如果订阅的是mysql的从库,需求增加配置让从库日志也写到binlog里面

log_slave_updates=1

可以通过在 mysql 终端中执行以下命令判断配置是否生效:

show variables like 'log_bin';
show variables like 'binlog_format';

4.1.2. 授权账号权限

授权 canal 链接 MySQL 账号具有作为 MySQL slave 的权限, 如果已有账户可直接 grant:

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

4.2. 部署canal-admin

4.2.1. 作用

  1. 通过图形化界面管理配置参数。
  2. 动态启停 ServerInstance
  3. 查看日志信息

4.2.2. 执行数据库脚本

执行 conf 目录下载的 canal_manager.sql 脚步,初始化所需的库表。

初始化SQL脚本里会默认创建canal_manager的数据库,建议使用root等有超级权限的账号进行初始化

4.2.3. 配置修改

执行 vim conf/application.yml

server:
  port: 8089
spring:
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8

spring.datasource:
  address: 127.0.0.1:3306
  database: canal_manager
  username: canal
  password: canal
  driver-class-name: com.mysql.jdbc.Driver
  url: jdbc:mysql://${spring.datasource.address}/${spring.datasource.database}?useUnicode=true&characterEncoding=UTF-8&useSSL=false
  hikari:
    maximum-pool-size: 30
    minimum-idle: 1

canal:
  adminUser: admin
  adminPasswd: admin

修改 addressdatabaseusernamepassword 四个参数

4.2.4. 启停命令

启动

sh bin/startup.sh

停止

sh bin/stop.sh

4.2.5. 使用

通过 http://127.0.0.1:8089/ 访问,默认密码:admin/123456

4.2.5.1. 创建集群

配置 集群名称ZK地址

Canal高可用架构部署

配置 主配置,该配置为集群内的所有Server实例共享的

Canal高可用架构部署

主要修改以下配置:

  • canal.zkServers 配置zookeeper集群地址
  • canal.instance.global.spring.xml 改为classpath:spring/default-instance.xml
4.2.5.2. 创建Server

Canal高可用架构部署

配置项:

  • 所属集群,可以选择为单机 或者 集群。一般单机Server的模式主要用于一次性的任务或者测试任务
  • Server名称,唯一即可,方便自己记忆
  • Server Ip,机器ip
  • admin端口,canal 1.1.4版本新增的能力,会在canal-server上提供远程管理操作,默认值11110
  • tcp端口,canal提供netty数据订阅服务的端口
  • metric端口, promethues的exporter监控数据端口 (未来会对接监控)

多台Server关联同一个集群即可形成主备HA架构

4.2.5.3. 创建Instance

每个 Instance 关联一个同步的数据源,如果有多个数据源需要同步则需要创建多个 实例

Canal高可用架构部署
  1. 先填写实例名
  2. 选择刚刚创建的集群
  3. 载入模板配置

主要修改以下配置:

  • canal.instance.master.address 配置要同步的数据库地址
  • canal.instance.dbUsername 数据库用户名(需同步权限)
  • canal.instance.dbPassword 数据库密码
  • canal.instance.filter.regex mysql 数据解析关注的表,Perl正则表达式.多个正则之间以逗号(,)分隔,转义符需要双斜杠()

canal.instance.filter.regex常见例子:

  1. 所有表:.* or . ..
  2. canal schema下所有表: canal..*
  3. canal下的以canal打头的表:canal.canal.*
  4. canal schema下的一张表:canal.test1
  5. 多个规则组合使用:canal..*,mysql.test1,mysql.test2 (逗号分隔)
    注意:此过滤条件只针对row模式的数据有效(ps. mixed/statement因为不解析sql,所以无法准确提取tableName进行过滤)

4.3. 部署canal-deployer

4.3.1. 作用

  1. 伪装成 MySQL 的从库,同步主库的binlog日志。
  2. 解析并结构化 binary log 对象。

4.3.2. 修改配置

执行 vim conf/canal_local.properties 修改配置项 canal.admin.manager 为canal-admin的地址

4.3.3. 启停命令

使用 local 配置启动

bin/startup.sh local

停止

bin/stop.sh

4.4. 部署canal-adapter

4.4.1. 作用

  1. 对接上游消息,包括kafka、rocketmq、canal-server
  2. 实现mysql数据的增量同步
  3. 实现mysql数据的全量同步
  4. 下游写入支持mysql、es、hbase等

4.4.2. 修改配置

注意:目前 adapter 是支持动态配置的,也就是说修改配置文件后无需重启,任务会自动刷新配置!

(1) 修改application.yml

执行 vim conf/application.yml 修改consumerProperties、srcDataSources、canalAdapters的配置

canal.conf:
  mode: tcp # kafka rocketMQ                # canal client的模式: tcp kafka rocketMQ
  flatMessage: true                         # 扁平message开关, 是否以json字符串形式投递数据, 仅在kafka/rocketMQ模式下有效
  syncBatchSize: 1000                       # 每次同步的批数量
  retries: 0                                # 重试次数, -1为无限重试
  timeout:                                  # 同步超时时间, 单位毫秒
  consumerProperties:
    canal.tcp.server.host:                  # 对应单机模式下的canal
    canal.tcp.zookeeper.hosts: 127.0.0.1:2181 # 对应集群模式下的zk地址, 如果配置了canal.tcp.server.host, 则以canal.tcp.server.host为准
    canal.tcp.batch.size: 500               # tcp每次拉取消息的数量
  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: es7                           # es7适配器
        mode: rest                          # transport or rest
        hosts: 127.0.0.1:9200               # es地址
        security.auth: test:123456          # 访问es的认证信息,如没有则不需要填
        cluster.name: my-es                 # 集群名称,transport模式必需配置
......

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

(2) conf/es7目录下新增映射配置文件

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

新增表映射的配置文件,如 sys_user.yml 内容如下:

dataSourceKey: defaultDS
destination: example
groupId: g1
esMapping:
  _index: sys_user
  _id: id
  upsert: true
  sql: "select id, username,
        , case when sex = 0 then '男' else '女' end sex
        , case when is_del = 0 then '否' else '是' end isdel
      from sys_user"
  etlCondition: "where update_time>={}"
  commitBatch: 3000
  • dataSourceKey 配置 application.ymlsrcDataSources 的值
  • destination 配置 canal.deployerInstance
  • groupId 配置 application.ymlcanalAdapters.groups 的值
  • _index 配置索引名
  • _id 配置主键对应的字段
  • upsert 是否更新
  • sql 映射sql
  • etlCondition etl 的条件参数,全量同步时可以使用
  • commitBatch 提交批大小

sql映射支持多表关联自由组合, 但是有一定的限制:

  1. 主表不能为子查询语句
  2. 只能使用left outer join即最左表一定要是主表
  3. 关联从表如果是子查询不能有多张表
  4. 主sql中不能有where查询条件(从表子查询中可以有where条件但是不推荐, 可能会造成数据同步的不一致, 比如修改了where条件中的字段内容)
  5. 关联条件只允许主外键的’=’操作不能出现其他常量判断比如: on a.role_id=b.id and b.statues=1
  6. 关联条件必须要有一个字段出现在主查询语句中比如: on a.role_id=b.id 其中的 a.role_id 或者 b.id 必须出现在主select语句中

Elastic Search的mapping 属性与sql的查询值将一一对应(不支持 select *), 比如: select a.id as _id, a.name, a.email as _email from user, 其中name将映射到es mapping的name field, _email将 映射到mapping的_email field, 这里以别名(如果有别名)作为最终的映射字段. 这里的_id可以填写到配置文件的 _id: _id映射

4.4.3. 启停命令

启动

bin/startup.sh

关闭

bin/stop.sh

4.5. 遗留问题

目前使用的 1.1.5-SNAPSHOT 版本由于还不是发布版,发现 canal-adapter 的集群部署有个bug,配置 zookeeper 地址后启动会出现以下异常:

java.lang.LinkageError: loader constraint violation: when resolving method "com.alibaba.otter.canal.common.zookeeper.ZkClientx.create(Ljava/lang/String;Ljava/lang/Object;Lorg/apache/zookeeper/CreateMode;)Ljava/lang/String;" the class loader (instance of com/alibaba/otter/canal/connector/core/spi/URLClassExtensionLoader) of the current class, com/alibaba/otter/canal/client/impl/running/ClientRunningMonitor, and the class loader (instance of sun/misc/Launcher$AppClassLoader) for the method's defining class, org/I0Itec/zkclient/ZkClient, have different Class objects for the type org/apache/zookeeper/CreateMode used in the signature
    at com.alibaba.otter.canal.client.impl.running.ClientRunningMonitor.initRunning(ClientRunningMonitor.java:122) [connector.tcp-1.1.5-SNAPSHOT-jar-with-dependencies.jar:na]
    at com.alibaba.otter.canal.client.impl.running.ClientRunningMonitor.start(ClientRunningMonitor.java:93) [connector.tcp-1.1.5-SNAPSHOT-jar-with-dependencies.jar:na]
    at com.alibaba.otter.canal.client.impl.SimpleCanalConnector.connect(SimpleCanalConnector.java:108) [connector.tcp-1.1.5-SNAPSHOT-jar-with-dependencies.jar:na]
    at com.alibaba.otter.canal.client.impl.ClusterCanalConnector.connect(ClusterCanalConnector.java:64) [connector.tcp-1.1.5-SNAPSHOT-jar-with-dependencies.jar:na]
    at com.alibaba.otter.canal.connector.tcp.consumer.CanalTCPConsumer.connect(CanalTCPConsumer.java:59) [connector.tcp-1.1.5-SNAPSHOT-jar-with-dependencies.jar:na]

有以下3个解决思路:

  1. adapter暂时使用单实例模式,等待官方解决问题。
  2. 自行修复bug
  3. 使用 MQ 模式(adapter则无需注册到zookeeper了)

BUG 已修复:https://github.com/zlt2000/canal

五、监控

canal 默认已通过 11112 端口暴露同步相关的 metrics 信息,只需通过集成 prometheusgrafana 即可实现实时监控同步情况,效果图如下:

Canal高可用架构部署

指标 简述 Basic Canal instance 基本信息。 Network bandwith 网络带宽。包含inbound(canal server读取binlog的网络带宽)和outbound(canal server返回给canal client的网络带宽)。 Delay Canal server与master延时;store 的put, get, ack操作对应的延时。 Blocking sink线程blocking占比;dump线程blocking占比(仅parallel mode)。 TPS(events) Canal instance消费所有binlog事件的TPS, 以MySQL binlog events为单位计算。 TPS(transaction) Canal instance 处理binlog的TPS,以MySQL transaction为单位计算。 TPS(tableRows) 分别对应store的put, get, ack操作针对数据表变更行的TPS。 Client requests Canal client请求server的请求数统计,结果按请求类型分类(比如get/ack/sub/rollback等)。 Client QPS client发送请求的QPS,按GET与CLIENTACK分类统计。 Empty packets Canal client请求server返回空结果的统计。 Response time Canal client请求server的响应时间统计。 Store remain events Canal instance ringbuffer中堆积的events数量。 Store remain mem Canal instance ringbuffer中堆积的events内存使用量。

六、总结

  1. 准备MySQL
  2. 开启binlog(row模式)
  3. 准备同步权限的用户
  4. 创建canal-admin的库表
  5. 准备zookeeper
  6. 部署canal-admin
  7. 创建集群
  8. 创建server:关联集群
  9. 创建Instance:关联集群,并配置源库信息
  10. 启动canal-deployer
  11. 关联canal-admin
  12. 启动canal-adapter
  13. 关联zookeeper
  14. 配置源库信息
  15. 关联Instance
  16. 配置目标库信息(es)
  17. 新增映射配置文件

扫码关注有惊喜!

Canal高可用架构部署

Original: https://www.cnblogs.com/zlt2000/p/14565133.html
Author: zlt2000
Title: Canal高可用架构部署

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/575314/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • POI操作EXCEL对象

    POI操作EXCEL对象HSSF:操作Excel 97(.xls)格式XSSF:操作Excel 2007 OOXML (.xlsx)格式,操作EXCEL内存占用高于HSSFSXSS…

    Java 2023年6月9日
    069
  • BF算法和KMP算法

    什么是串 数据结构中,字符串要单独用一种存储结构来存储,称为串存储结构。这里的串指的就是字符串。字符串通常是由零个或多个字符组成的有限序列。 一般地,由n个字符串构成的串记作: S…

    Java 2023年6月5日
    078
  • 程序包javax.persistence不存在解决办法

    只需添加以下包即可 javax.persistence persistence-api 1.0.2 Original: https://www.cnblogs.com/javalo…

    Java 2023年6月15日
    090
  • 若依项目quill富文本提交后缺少了部分html标签

    背景: ruoyi前后端分离项目,后端Springboot,前端vue,富文本控件quill。 问题: 提交含有quill富文本控件的表单,后端接收到的富文本数据,缺少了部分htm…

    Java 2023年6月14日
    084
  • [Java编程思想] 第八章 多态

    “我曾经被问到’求教,Babbage先生,如果你向机器中输入错误的数字,可以得到正确的答案吗?’我无法恰当地理解产生这种问题的概念上地混淆&#8…

    Java 2023年6月5日
    0130
  • 图解MongoDB集群部署原理(3)

    MongoDB的集群部署方案中有三类角色:实际数据存储结点、配置文件存储结点和路由接入结点。连接的客户端直接与路由结点相连,从配置结点上查询数据,根据查询结果到实际的存储结点上查询…

    Java 2023年6月7日
    078
  • 分布式项目开发-springmvc.xmll基础配置

    基础步骤: 1 包扫描 2 驱动开发 3 视图解析器 4 文件上传解析器 5 拦截器 6 静态资源 xmlns:xsi="http://www.w3.org/2001/X…

    Java 2023年6月8日
    064
  • Feign Interceptor 拦截器实现全局请求参数

    在第三方API对接中通常所有接口都需要在Header或Param放置固定参数(Token、开发者Key等),因为是SpringCloud开发,一般HTTP工具采用Feign。如果选…

    Java 2023年6月5日
    084
  • 重构

    参数过长 影响: 方法不易被理解、使用,方法签名容易不稳定,不易维护 解决方法:反复使用提炼方法+内联方法,消除多余参数 ​ 尽量把方法移进相关的类中 ​ 如实体类中的get方法在…

    Java 2023年6月8日
    098
  • Servlet中使用注解@WebServlet进行url匹配报404的问题

    首先这个问题是比较简单,前提是你使用了@WebServlet注解,然后检查了所有配置都没有问题 最终还是前端浏览器报404错误,那多半都是你看一下web.xml配置文件里 meta…

    Java 2023年6月6日
    0104
  • Java实体映射工具MapStruct 与BeanUtils性能比较

    本文通过一个简单的示例代码,比较MapStruct和BeanUtils的性能数据,实测一下性能到底有多大的差距。关于MapStruct工具的详细介绍可以参考《Java实体映射工具M…

    Java 2023年5月29日
    057
  • MyBatisCodeHelperPro激活方法(有效方法)

    注意事项我的idea是2021.2.1的,新版本的idea我也不清楚。我这个版本是可以的。 ​编辑 1、下载插件 ​编辑 这是插件下载的地址: MybatisCodeHelperN…

    Java 2023年6月13日
    0124
  • Seata源码分析——AT模式底层实现

    GlobalTransactionScanner 继承AbstractAutoProxyCreator 实现InitializingBean接口 写在最后 以AT为例,我们使用Se…

    Java 2023年6月9日
    0128
  • Eureka多节点数据不同步问题

    前言 以下为找到问题后搜到的文章,这里做下记录,如果解决了您的问题可以为原位作者点赞 以下为原文 转载自joshua317博客 Spring Boot-yaml格式,eureka客…

    Java 2023年6月8日
    088
  • 线程知识总结2

    参考文档:https://blog.csdn.net/weixin_45860338/article/details/113824249 B站:遇见狂神说 案例:线程停止 /** …

    Java 2023年6月7日
    080
  • HashMap在jdk7和jdk8中的实现原理

    HashMap在jdk7中实现原理: 1.在实例化以后,底层创建了一个长度为16的一维数组Entry[] table 在可能执行多次put后 map.put(key1,value1…

    Java 2023年5月30日
    068
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球