Canal+Kafka实现Mysql数据同步

Canal介绍

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

canal可以用来监控数据库数据的变化,从而获得新增数据,或者修改的数据。

canal是应阿里巴巴存在杭州和美国的双机房部署,存在跨机房同步的业务需求而提出的。

阿里系公司开始逐步的尝试基于数据库的日志解析,获取增量变更进行同步,由此衍生出了增量订阅&消费的业务。

canal主要用途是基于 MySQL 数据库增量日志解析,并能提供增量数据订阅和消费,应用场景十分丰富。

目前canal主要支持mysql数据库。

github地址:https://github.com/alibaba/canal

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

文档地址:https://github.com/alibaba/canal/wiki/Docker-QuickStart

Canal应用场景

1)、电商场景下商品、用户实时更新同步到至Elasticsearch、solr等搜索引擎;
2)、价格、库存发生变更实时同步到redis;
3)、数据库异地备份、数据同步;
4)、代替使用轮询数据库方式来监控数据库变更,有效改善轮询耗费数据库资源。

image.png

MySQL主从复制原理

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

Canal工作原理

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

image.pngCanal安装

参考文档:https://github.com/alibaba/canal/wiki/QuickStart

Canal配置

mq相关参数说明 (>=1.1.5版本)

在1.1.5版本开始,引入了MQ Connector设计,参数配置做了部分调整

参数名

参数说明

默认值

canal.aliyun.accessKey

阿里云ak

canal.aliyun.secretKey

阿里云sk

canal.aliyun.uid

阿里云uid

canal.mq.flatMessage

是否为json格式 如果设置为false,对应MQ收到的消息为protobuf格式 需要通过CanalMessageDeserializer进行解码

false

canal.mq.canalBatchSize

获取canal数据的批次大小

50

canal.mq.canalGetTimeout

获取canal数据的超时时间

100

canal.mq.accessChannel = local

是否为阿里云模式,可选值local/cloud

local

canal.mq.database.hash

是否开启database混淆hash,确保不同库的数据可以均匀分散,如果关闭可以确保只按照业务字段做MQ分区计算

true

canal.mq.send.thread.size

MQ消息发送并行度

30

canal.mq.build.thread.size

MQ消息构建并行度

8

kafka.bootstrap.servers

kafka服务端地址

127.0.0.1:9092

kafka.acks

kafka为ProducerConfig.ACKS_CONFIG

all

kafka.compression.type

压缩类型

none

kafka.batch.size

kafka为ProducerConfig.BATCH_SIZE_CONFIG

16384

kafka.linger.ms

kafka为ProducerConfig.LINGER_MS_CONFIG , 如果是flatMessage格式建议将该值调大, 如: 200

1

kafka.max.request.size

kafka为ProducerConfig.MAX_REQUEST_SIZE_CONFIG

1048576

kafka.buffer.memory

kafka为ProducerConfig.BUFFER_MEMORY_CONFIG

33554432

kafka.max.in.flight.requests.per.connection

kafka为ProducerConfig.MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION

1

kafka.retries

发送失败重试次数

0

kafka.kerberos.enable

kerberos认证

false

kafka.kerberos.krb5.file

kerberos认证

../conf/kerberos/krb5.conf

kafka.kerberos.jaas.file

kerberos认证

../conf/kerberos/jaas.conf

rocketmq.producer.group

rocketMQ为ProducerGroup名

test

rocketmq.enable.message.trace

是否开启message trace

false

rocketmq.customized.trace.topic

message trace的topic

rocketmq.namespace

rocketmq的namespace

rocketmq.namesrv.addr

rocketmq的namesrv地址

127.0.0.1:9876

rocketmq.retry.times.when.send.failed

重试次数

0

rocketmq.vip.channel.enabled

rocketmq是否开启vip channel

false

rocketmq.tag

rocketmq的tag配置

空值

rabbitmq.host

rabbitMQ配置

rabbitmq.virtual.host

rabbitMQ配置

rabbitmq.exchange

rabbitMQ配置

rabbitmq.username

rabbitMQ配置

rabbitmq.password

rabbitMQ配置

rabbitmq.deliveryMode

rabbitMQ配置

pulsarmq.serverUrl

pulsarmq配置

pulsarmq.roleToken

pulsarmq配置

pulsarmq.topicTenantPrefix

pulsarmq配置

canal.mq.topic

mq里的topic名

canal.mq.dynamicTopic

mq里的动态topic规则, 1.1.3版本支持

canal.mq.partition

单队列模式的分区下标,

1

canal.mq.enableDynamicQueuePartition

动态获取MQ服务端的分区数,如果设置为true之后会自动根据topic获取分区数替换canal.mq.partitionsNum的定义,目前主要适用于RocketMQ

false

canal.mq.partitionsNum

散列模式的分区数

canal.mq.dynamicTopicPartitionNum

mq里的动态队列分区数,比如针对不同topic配置不同partitionsNum

canal.mq.partitionHash

散列规则定义 库名.表名 : 唯一主键,比如mytest.person: id 1.1.3版本支持新语法,见下文

canal.mq.dynamicTopic 表达式说明

canal 1.1.3版本之后, 支持配置格式:schema 或 schema.table,多个配置之间使用逗号或分号分隔

  • 例子1:test\\.test 指定匹配的单表,发送到以test_test为名字的topic上
  • 例子2:.*\\..* 匹配所有表,则每个表都会发送到各自表名的topic上
  • 例子3:test 指定匹配对应的库,一个库的所有表都会发送到库名的topic上
  • 例子4:test\\..* 指定匹配的表达式,针对匹配的表会发送到各自表名的topic上
  • 例子5:test,test1\\.test1,指定多个表达式,会将test库的表都发送到test的topic上,test1\\.test1的表发送到对应的test1_test1 topic上,其余的表发送到默认的canal.mq.topic值

为满足更大的灵活性,允许对匹配条件的规则指定发送的topic名字,配置格式:topicName:schema 或 topicName:schema.table

  • 例子1: test:test\\.test 指定匹配的单表,发送到以test为名字的topic上
  • 例子2: test:.*\\..* 匹配所有表,因为有指定topic,则每个表都会发送到test的topic下
  • 例子3: test:test 指定匹配对应的库,一个库的所有表都会发送到test的topic下
  • 例子4:testA:test\\..* 指定匹配的表达式,针对匹配的表会发送到testA的topic下
  • 例子5:test0:test,test1:test1\\.test1,指定多个表达式,会将test库的表都发送到test0的topic下,test1\\.test1的表发送到对应的test1的topic下,其余的表发送到默认的canal.mq.topic值

大家可以结合自己的业务需求,设置匹配规则,建议MQ开启自动创建topic的能力

canal.mq.partitionHash 表达式说明

canal 1.1.3版本之后, 支持配置格式:schema.table:pk1^pk2,多个配置之间使用逗号分隔

  • 例子1:test\\.test:pk1^pk2 指定匹配的单表,对应的hash字段为pk1 + pk2
  • 例子2:.*\\..*:id 正则匹配,指定所有正则匹配的表对应的hash字段为id
  • 例子3:.*\\..*:$pk$ 正则匹配,指定所有正则匹配的表对应的hash字段为表主键(自动查找)
  • 例子4: 匹配规则啥都不写,则默认发到0这个partition上
  • 例子5:.*\\..* ,不指定pk信息的正则匹配,将所有正则匹配的表,对应的hash字段为表名
    • 按表hash: 一张表的所有数据可以发到同一个分区,不同表之间会做散列 (会有热点表分区过大问题)

  • 例子6: test\\.test:id,.\\..* , 针对test的表按照id散列,其余的表按照table散列

注意:大家可以结合自己的业务需求,设置匹配规则,多条匹配规则之间是按照顺序进行匹配(命中一条规则就返回)

其他详细参数可参考Canal AdminGuide

mq顺序性问题

binlog本身是有序的,写入到mq之后如何保障顺序是很多人会比较关注,在issue里也有非常多人咨询了类似的问题,这里做一个统一的解答

  1. 1.

    canal目前选择支持的kafka/rocketmq,本质上都是基于本地文件的方式来支持了分区级的顺序消息的能力,也就是binlog写入mq是可以有一些顺序性保障,这个取决于用户的一些参数选择

  2. 2.

    canal支持MQ数据的几种路由方式:单topic单分区,单topic多分区、多topic单分区、多topic多分区

  • canal.mq.dynamicTopic,主要控制是否是单topic还是多topic,针对命中条件的表可以发到表名对应的topic、库名对应的topic、默认topic name
  • canal.mq.partitionsNum、canal.mq.partitionHash,主要控制是否多分区以及分区的partition的路由计算,针对命中条件的可以做到按表级做分区、pk级做分区等
  1. 1.

    canal的消费顺序性,主要取决于描述2中的路由选择,举例说明:

  • 单topic单分区,可以严格保证和binlog一样的顺序性,缺点就是性能比较慢,单分区的性能写入大概在2~3k的TPS
  • 多topic单分区,可以保证表级别的顺序性,一张表或者一个库的所有数据都写入到一个topic的单分区中,可以保证有序性,针对热点表也存在写入分区的性能问题
  • 单topic、多topic的多分区,如果用户选择的是指定table的方式,那和第二部分一样,保障的是表级别的顺序性(存在热点表写入分区的性能问题),如果用户选择的是指定pk hash的方式,那只能保障的是一个pk的多次binlog顺序性 ** pk hash的方式需要业务权衡,这里性能会最好,但如果业务上有pk变更或者对多pk数据有顺序性依赖,就会产生业务处理错乱的情况. 如果有pk变更,pk变更前和变更后的值会落在不同的分区里,业务消费就会有先后顺序的问题,需要注意

性能表现

Kafka + 混合DML场景测试

场景

1个topic + 单分区

1个topic+3分区

2个topic+1分区

2个topic+3分区

不开启flatMessage

29.6k rps (9.71k tps)

17.54k rps (6.53k tps)

21.6k rps (7.9k tps)

16.8k rps (5.71k tps)

开启flatMessage

11.79k rps (4.36k tps)

15.97 rps (5.94k tps)

11.91k rps (4.45k tps)

16.96k rps (6.26k tps)

Kafka + 单表的batch insert场景测试

场景

1个topic + 单分区

1个topic+3分区

不开启flatMessage

59.6k rps

45.1k rps

开启flatMessage

51.3k rps

49.6k rps


RocketMQ + 混合DML场景测试

场景

1个topic + 单分区

1个topic+3分区

2个topic+1分区

2个topic+3分区

不开启flatMessage

29.6k rps (10.71k tps)

23.3k rps (8.59k tps)

26.7k rps (9.46k tps)

21.7k rps (7.66k tps)

开启flatMessage

16.75k rps (6.17k tps)

14.96k rps (5.55k tps)

17.83k rps (6.63k tps)

16.93k rps (6.26k tps)

RocketMQ + 单表的batch insert场景测试

场景

1个topic + 单分区

1个topic+3分区

不开启flatMessage

81.2k rps

51.3k rps

开启flatMessage

62.6k rps

57.9k rps

附录:

canal官方文档:https://github.com/alibaba/canal/wiki/Canal-Kafka-RocketMQ-QuickStart

Canal+MQ性能表现:https://github.com/alibaba/canal/wiki/Canal-MQ-Performance

参考文档:https://www.cnblogs.com/zwh0910/p/17043265.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/69182.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【笔记】树状数组

【笔记】树状数组 目录 简介引入1. 直接暴力2. 维护前缀和数组总结 定义前置知识: lowbit ⁡ \operatorname{lowbit} lowbit 操作区间的表示方法操作单点修改前缀和查询任意区间查询 例题1: 单点修改,区间查询例题2: 区间修改,单点查询例题3:…

Maven 生成(打包)带有依赖的可以直接执行的一个 jar 包

在pom中增加如下内容 <build><plugins><plugin><artifactId>maven-assembly-plugin</artifactId><configuration><archive><manifest><mainClass>com.example.xxx.YourClass</mainClass></manifest></…

Android系统组件——AMS,App启动中的AMS流程

AMS&#xff08;Activity Manager Service&#xff09;是Android系统中非常重要的一个组件&#xff0c;负责管理应用程序的生命周期、进程调度以及任务栈的管理等任务。本文将从AMS的原理、数据结构、SystemServer加载AMS以及App启动中的AMS流程等方面进行详细介绍&#xff0c;…

Linux固件子系统的实现机制简介

一、Linux固件子系统概述 固件是硬件设备自身执行的一段程序。固件一般存放在设备flash内。而出于成本和便利性的考虑&#xff0c;通常是先将硬件设备的运行程序打包为一个特定格式的固件文件&#xff0c;存储到终端系统内&#xff0c;通过终端系统给硬件设备进行升级。Linux内…

C#使用EmguCV播放视频

目录 一、前言 1、简介 2、测试工程代码下载链接 3、EmguCV 库文件下载链接 二、工程环境配置 1、EmguCV控件添加引用 &#xff08;1&#xff09;窗口控件添加 &#xff08;2&#xff09;相关Dll文件添加添加引用 &#xff08;3&#xff09;工程运行基础文件夹添加 &a…

【Spring】(四)Bean 的作用域和生命周期

文章目录 前言一、Bean 的作用域1.1 被修改的 Bean 案例1.2 作用域的定义1.3 Bean 的六种作用域1.4 Bean 作用域的设置 二、Spring 的执行流程 和 Bean 的生命周期2.1 Spring 的执行流程2.2 Bean 的生命周期2.3 Bean 生命周期的演示 前言 Bean 是 Spring 框架中的一个核心概念…

从支付或退款之回调处理的设计,看一看抽象类的使用场景

一、背景 抽象类&#xff0c;包含抽象方法和实例方法&#xff0c;抽象方法待继承类去实例化&#xff0c;正是利用该特性&#xff0c;以满足不同支付渠道的差异化需求。 我们在做多渠道支付的时候&#xff0c;接收支付或退款的回调报文&#xff0c;然后去处理。这就意味着&…

JVM运行时五大数据区域详解

前言&#xff1a; java虚拟机再执行Java程序的时候把它所拥有的内存区域划分了若干个数据区域。这些区域有着不同的功能&#xff0c;各司其职。这些区域不但功能不同&#xff0c;创建、销毁时间也不同。有些区域为线程私有&#xff0c;如&#xff1a;每个线程都有自己的程序计数…

kubernetes基于helm部署gitlab

kubernetes基于helm部署gitlab 这篇博文介绍如何在 Kubernetes 中使用helm部署 GitLab。 先决条件 已运行的 Kubernetes 集群负载均衡器&#xff0c;为ingress-nginx控制器提供EXTERNAL-IP&#xff0c;本示例使用metallb默认存储类&#xff0c;为gitlab pods提供持久化存储&…

“算法详解”系列第3卷贪心算法和动态规划出版

“算法详解”系列图书共有4卷&#xff0c;目前1到3卷已经出版。最新出版的是第3卷—贪心算法和动态规划。 算法详解 卷3 贪心算法和动态规划 “算法详解”系列图书共有4卷&#xff0c;本书是第3卷—贪心算法和动态规划。其中贪心算法主要包括调度、最小生成树、集群、哈夫曼编…

centos7实现负载均衡

目录 一、基于 CentOS 7 构建 LVS-DR 集群。 1.1 配置lvs负载均衡服务 1.1.1 下载ipvsadm 1.1.2 增加vip 1.1.3 配置ipvsadm 1.2 配置rs1 1.2.1 编写测试页面 1.2.2 手工在RS端绑定VIP、添加路由 1.2.3 抑制arp响应 1.3 配置rs2 1.4 测试 二、配置nginx负载…

Jmeter命令行运行实例讲解

1. 简介 使用非 GUI 模式&#xff0c;即命令行模式运行 JMeter 测试脚本能够大大缩减所需要的系统资 本文介绍windows下以命令行模式运行的方法。 1.1. 命令介绍 jmeter -n -t <testplan filename> -l <listener filename> 示例&#xff1a; jmeter -n -t test…

【数学建模】-- Matlab中图的最短路径

前言&#xff1a; 图的基本概念&#xff1a; 若想简单绘制图可以利用此网站&#xff1a; 左上角Undirected/Directed是无向图/有向图 左边 0-index &#xff0c;1-index为0下标&#xff0c;1下标。 Node Count为节点个数 Graph Data&#xff1a;最初尾节点的名称&#xff…

【什么是应变波齿轮又名谐波驱动?机器人应用的完美齿轮组!?】

什么是应变波齿轮又名谐波驱动&#xff1f;机器人应用的完美齿轮组&#xff01;&#xff1f; 1. 什么是应变波齿轮&#xff1f;2. 工作原理3. 应变波齿轮 – 谐波驱动 3D 模型4. 3D 打印应变波齿轮 – 谐波驱动5. 总结 在本教程中&#xff0c;我们将学习什么是应变波齿轮&#…

第五次作业 运维高级 构建 LVS-DR 集群和配置nginx负载均衡

1、基于 CentOS 7 构建 LVS-DR 群集。 LVS-DR模式工作原理 首先&#xff0c;来自客户端计算机CIP的请求被发送到Director的VIP。然后Director使用相同的VIP目的IP地址将请求发送到集群节点或真实服务器。然后&#xff0c;集群某个节点将回复该数据包&#xff0c;并将该数据包…

ResUNet原理与实现

简述 ResNet是一种非常成功的深度卷积神经网络结构&#xff0c;其具有较强的特征表达能力和较浅的网络深度&#xff0c;使得其在图像分类等任务中表现出了出色的性能。因此&#xff0c;将ResNet作为encoder替换U-Net原始结构&#xff0c;可以使U-Net在图像分割任务中获得更好的…

python爬虫实战(1)--爬取新闻数据

想要每天看到新闻数据又不想占用太多时间去整理&#xff0c;萌生自己抓取新闻网站的想法。 1. 准备工作 使用python语言可以快速实现&#xff0c;调用BeautifulSoup包里面的方法 安装BeautifulSoup pip install BeautifulSoup完成以后引入项目 2. 开发 定义请求头&#xf…

【Windows】Windows开机密码重置

文章目录 前言一、问题描述二、操作步骤2.1 安装DaBaiCai_d14_v6.0_2207_Online.exe2.2 插入U盘2.3 打开大白菜&#xff0c;点击“一键制作USB启动盘”2.4 等待进度条走完2.5 重启电脑&#xff0c;开机按“F12”或者“F8”&#xff08;具体百度一下&#xff0c;对应品牌电脑开机…

Java 成功实现通过网址URL截图保存

Java 实现通过网址URL截图 1.DjNativeSwing方式 &#xff08;不好用&#xff09;2.phantomjs方式 &#xff08;截图还是有瑕疵&#xff09;3.selenium方式 &#xff08;满意&#xff0c;成功实现&#xff09;maven 引入下载相关浏览器chrome下载相关浏览器chromedriver驱动后端…

代码随想录算法训练营第53天|动态规划part11|123. 买卖股票的最佳时机 III、188.买卖股票的最佳时机IV

代码随想录算法训练营第53天&#xff5c;动态规划part11&#xff5c;123. 买卖股票的最佳时机 III、 188.买卖股票的最佳时机IV 123. 买卖股票的最佳时机 III 123. 买卖股票的最佳时机 III 思路&#xff1a; 相比买股票的最佳时机II&#xff0c;限制了买股票的次数&#xf…
最新文章