IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> 【转】canal源码分析 -> 正文阅读

[大数据]【转】canal源码分析

canal源码分析,canal server源码分析,canal deployer源码分析。转载保留记录。当做笔记。侵权告知。

以下为转载内容

早期,阿里巴巴 B2B 公司因为存在杭州和美国双机房部署,存在跨机房同步的业务需求。不过早期的数据库同步业务,主要是基于 trigger 的方式获取增量变更,不过从 2010 年开始,阿里系公司开始逐步的尝试基于数据库的日志解析,获取增量变更进行同步,由此衍生出了增量订阅 & 消费的业务,从此开启了一段新纪元。ps. 目前内部使用的同步,已经支持 mysql5.x 和 oracle 部分版本的日志解析

基于日志增量订阅 & 消费支持的业务:

  1. 数据库镜像
  2. 数据库实时备份
  3. 多级索引 (卖家和买家各自分库索引)
  4. search build
  5. 业务 cache 刷新
  6. 价格变化等重要业务消息

项目介绍

名称:canal [k?’n?l]

译意: 水道 / 管道 / 沟渠

语言: 纯 java 开发

定位: 基于数据库增量日志解析,提供增量数据订阅 & 消费,目前主要支持了 mysql

工作原理

mysql 主备复制实现


从上层来看,复制分成三步:

  1. master 将改变记录到二进制日志 (binary log) 中(这些记录叫做二进制日志事件,binary log events,可以通过 show binlog events 进行查看);
  2. slave 将 master 的 binary log events 拷贝到它的中继日志 (relay log);
  3. slave 重做中继日志中的事件,将改变反映它自己的数据。

canal 的工作原理:

原理相对比较简单:

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

架构

说明:

  • server 代表一个 canal 运行实例,对应于一个 jvm
  • instance 对应于一个数据队列 (1 个 server 对应 1…n 个 instance)

instance 模块:

  • eventParser (数据源接入,模拟 slave 协议和 master 进行交互,协议解析)
  • eventSink (Parser 和 Store 链接器,进行数据过滤,加工,分发的工作)
  • eventStore (数据存储)
  • metaManager (增量订阅 & 消费信息管理器)

知识科普

mysql 的 Binlay Log 介绍

简单点说:

  • mysql 的 binlog 是多文件存储,定位一个 LogEvent 需要通过 binlog filename + binlog position,进行定位
  • mysql 的 binlog 数据格式,按照生成的方式,主要分为:statement-based、row-based、mixed。
    Java 代码
    1. mysql> show variables like ‘binlog_format’;
    2. ±--------------±------+
    3. | Variable_name | Value |
    4. ±--------------±------+
    5. | binlog_format | ROW |
    6. ±--------------±------+
    7. 1 row in set (0.00 sec)

目前 canal 只能支持 row 模式的增量订阅 (statement 只有 sql,没有数据,所以无法获取原始的变更日志)

EventParser 设计

大致过程:

整个 parser 过程大致可分为几步:

  1. Connection 获取上一次解析成功的位置 (如果第一次启动,则获取初始指定的位置或者是当前数据库的 binlog 位点)
  2. Connection 建立链接,发送 BINLOG_DUMP 指令
    // 0. write command number
    // 1. write 4 bytes bin-log position to start at
    // 2. write 2 bytes bin-log flags
    // 3. write 4 bytes server id of the slave
    // 4. write bin-log file name
  3. Mysql 开始推送 Binaly Log
  4. 接收到的 Binaly Log 的通过 Binlog parser 进行协议解析,补充一些特定信息
    // 补充字段名字,字段类型,主键信息,unsigned 类型处理
  5. 传递给 EventSink 模块进行数据存储,是一个阻塞操作,直到存储成功
  6. 存储成功后,定时记录 Binaly Log 位置

mysql 的 Binlay Log 网络协议:

说明:

EventSink 设计

说明:

  • 数据过滤:支持通配符的过滤模式,表名,字段内容等
  • 数据路由 / 分发:解决 1:n (1 个 parser 对应多个 store 的模式)
  • 数据归并:解决 n:1 (多个 parser 对应 1 个 store)
  • 数据加工:在进入 store 之前进行额外的处理,比如 join

数据 1:n 业务

为了合理的利用数据库资源, 一般常见的业务都是按照 schema 进行隔离,然后在 mysql 上层或者 dao 这一层面上,进行一个数据源路由,屏蔽数据库物理位置对开发的影响,阿里系主要是通过 cobar/tddl 来解决数据源路由问题。

所以,一般一个数据库实例上,会部署多个 schema,每个 schema 会有由 1 个或者多个业务方关注

数据 n:1 业务

同样,当一个业务的数据规模达到一定的量级后,必然会涉及到水平拆分和垂直拆分的问题,针对这些拆分的数据需要处理时,就需要链接多个 store 进行处理,消费的位点就会变成多份,而且数据消费的进度无法得到尽可能有序的保证。

所以,在一定业务场景下,需要将拆分后的增量数据进行归并处理,比如按照时间戳 / 全局 id 进行排序归并.

EventStore 设计

    1. 目前仅实现了 Memory 内存模式,后续计划增加本地 file 存储,mixed 混合模式
    1. 借鉴了 Disruptor 的 RingBuffer 的实现思路

RingBuffer 设计:

定义了 3 个 cursor

  • Put : Sink 模块进行数据存储的最后一次写入位置
  • Get : 数据订阅获取的最后一次提取位置
  • Ack : 数据消费成功的最后一次消费位置

借鉴 Disruptor 的 RingBuffer 的实现,将 RingBuffer 拉直来看:

实现说明:

  • Put/Get/Ack cursor 用于递增,采用 long 型存储
  • buffer 的 get 操作,通过取余或者与操作。(与操作: cusor & (size - 1) , size 需要为 2 的指数,效率比较高)

Instance 设计

instance 代表了一个实际运行的数据队列,包括了 EventPaser,EventSink,EventStore 等组件。

抽象了 CanalInstanceGenerator,主要是考虑配置的管理方式:

  • manager 方式: 和你自己的内部 web console/manager 系统进行对接。(目前主要是公司内部使用)
  • spring 方式:基于 spring xml + properties 进行定义,构建 spring 配置.

Server 设计

server 代表了一个 canal 的运行实例,为了方便组件化使用,特意抽象了 Embeded(嵌入式) / Netty(网络访问) 的两种实现

  • Embeded : 对 latency 和可用性都有比较高的要求,自己又能 hold 住分布式的相关技术 (比如 failover)
  • Netty : 基于 netty 封装了一层网络协议,由 canal server 保证其可用性,采用的 pull 模型,当然 latency 会稍微打点折扣,不过这个也视情况而定。(阿里系的 notify 和 metaq,典型的 push/pull 模型,目前也逐步的在向 pull 模型靠拢,push 在数据量大的时候会有一些问题)

增量订阅 / 消费设计

具体的协议格式,可参见:CanalProtocol.proto

get/ack/rollback 协议介绍:

  • Message getWithoutAck(int batchSize),允许指定 batchSize,一次可以获取多条,每次返回的对象为 Message,包含的内容为:
    a. batch id 唯一标识
    b. entries 具体的数据对象,对应的数据对象格式:EntryProtocol.proto
  • void rollback(long batchId),顾命思议,回滚上次的 get 请求,重新获取数据。基于 get 获取的 batchId 进行提交,避免误操作
  • void ack(long batchId),顾命思议,确认已经消费成功,通知 server 删除数据。基于 get 获取的 batchId 进行提交,避免误操作

canal 的 get/ack/rollback 协议和常规的 jms 协议有所不同,允许 get/ack 异步处理,比如可以连续调用 get 多次,后续异步按顺序提交 ack/rollback,项目中称之为流式 api.

流式 api 设计的好处:

  • get/ack 异步化,减少因 ack 带来的网络延迟和操作成本 (99% 的状态都是处于正常状态,异常的 rollback 属于个别情况,没必要为个别的 case 牺牲整个性能)
  • get 获取数据后,业务消费存在瓶颈或者需要多进程 / 多线程消费时,可以不停的轮询 get 数据,不停的往后发送任务,提高并行化. (作者在实际业务中的一个 case:业务数据消费需要跨中美网络,所以一次操作基本在 200ms 以上,为了减少延迟,所以需要实施并行化)

流式 api 设计:

  • 每次 get 操作都会在 meta 中产生一个 mark,mark 标记会递增,保证运行过程中 mark 的唯一性
  • 每次的 get 操作,都会在上一次的 mark 操作记录的 cursor 继续往后取,如果 mark 不存在,则在 last ack cursor 继续往后取
  • 进行 ack 时,需要按照 mark 的顺序进行数序 ack,不能跳跃 ack. ack 会删除当前的 mark 标记,并将对应的 mark 位置更新为 last ack cusor
  • 一旦出现异常情况,客户端可发起 rollback 情况,重新置位:删除所有的 mark, 清理 get 请求位置,下次请求会从 last ack cursor 继续往后取

数据对象格式:EntryProtocol.proto

Java 代码

  1. Entry

  2.  Header  
    
  3.      logfileName [binlog 文件名]  
    
  4.      logfileOffset [binlog position]  
    
  5.      executeTime [发生的变更]  
    
  6.      schemaName   
    
  7.      tableName  
    
  8.      eventType [insert/update/delete 类型]  
    
  9.  entryType   [事务头 BEGIN / 事务尾 END / 数据 ROWDATA]  
    
  10.  storeValue  [byte 数据, 可展开,对应的类型为 RowChange]  
    
  11. RowChange

  12.  isDdl       [是否是 ddl 变更操作,比如 create table/drop table]  
    
  13.  sql     [具体的 ddl sql]  
    
  14.  rowDatas    [具体 insert/update/delete 的变更数据,可为多条,1 个 binlog event 事件可对应多条变更,比如批处理]  
    
  15.      beforeColumns [Column 类型的数组]  
    
  16.      afterColumns [Column 类型的数组]  
    
  17. Column

  18.  index         
    
  19.  sqlType     [jdbc type]  
    
  20.  name        [column name]  
    
  21.  isKey       [是否为主键]  
    
  22.  updated     [是否发生过变更]  
    
  23.  isNull      [值是否为 null]  
    
  24.  value       [具体的内容,注意为文本]  
    

说明:

  • 可以提供数据库变更前和变更后的字段内容,针对 binlog 中没有的 name,isKey 等信息进行补全
  • 可以提供 ddl 的变更语句

HA 机制设计

canal 的 ha 分为两部分,canal server 和 canal client 分别有对应的 ha 实现

  • canal server: 为了减少对 mysql dump 的请求,不同 server 上的 instance 要求同一时间只能有一个处于 running,其他的处于 standby 状态.
  • canal client: 为了保证有序性,一份 instance 同一时间只能由一个 canal client 进行 get/ack/rollback 操作,否则客户端接收无法保证有序。

整个 HA 机制的控制主要是依赖了 zookeeper 的几个特性,watcher 和 EPHEMERAL 节点 (和 session 生命周期绑定),可以看下我之前 zookeeper 的相关文章。

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.

Canal Client 的方式和 canal server 方式类似,也是利用 zokeeper 的抢占 EPHEMERAL 节点的方式进行控制.

最后

项目的代码: https://github.com/alibabatech/canal

这里给出了如何快速启动 Canal Server 和 Canal Client 的例子,如有问题可随时联系

Quick Start

Client Example

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-04-22 18:43:14  更:2022-04-22 18:47:22 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 3:35:01-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码