编者荐语:
随着用户对实时数据计算的需求越来越多, 现在市场上的CDC工具也越来越成熟, 本文将分享一种大众耳熟能详的开源技术CDC,当面临挑战进行工具选型时,希望能够帮你破壁。本文来自石原子科技合伙人祁国辉老师,欢迎大家阅读。
作者 | 祁国辉
编辑 | 宇亭
头图 | Yeekin
责编 | 韩 楠
实时数仓的浪潮来袭, 对于用户最大的挑战, 就是业务数据的变化需要实时反馈到后台系统, 甚至需要针对这些变化, 快速做出反应, 那么就需要一种技术来支持传统业务系统向实时转型的工具。
本文简单介绍一种大众耳熟能详的开源技术,也希望能够帮助你在讨论实时数仓的时候可以侃侃而谈, 言之有物。
CDC(Change Data Capture)变化数据捕获是指通过技术手段, 把系统中最新的数据变化(包括增删改)记录下来, 然后传输给后端系统进行消费的一种技术, 目前CDC被广泛用于各种场景:
- 变化数据捕获
- 数据仓库ETL
- 业务读写分离
- 应用系统多对一合并
- 一对多数据分发
- 数据跨平台容灾复制
- 数据平台滚动升级
目前, 常用的CDC技术有如下几种, 我们分别展开聊一聊。
#1.1 表级别时间戳或数据版本
在成熟的ERP应用中, 都会在表中设计诸如Last_update、 Date_modified等字段, 通过对这类时间戳字段的读取和筛选, 用户就可以知道数据的修改时间, 而对于数据删除, 也可以通过定义deleted 字段, 来标记数据是否已被标记为删除。但是缺点就在于数据量会持续增长,因为所有删除只是逻辑删除,应用处理逻辑也需要随之做出修改。
遗憾的是, 对于不少业务系统, 由于设计时没有考虑到CDC的需求,系统中没有设定时间戳, 数据删除也会直接删掉, 所以基于时间戳或者数据版本的CDC技术,受业务系统设计约束, 应用并不普遍。
#1.2 变化数据对比
基于数据快照或者全表在本地或者异地进行全量对比的方式, 也是针对无法进行时间戳数据比对的系统来捕获数据变化量的一种手段。
这种技术计算量大, 无论在本地还是异地进行全量对比, 都会消耗大量的CPU和存储IO, 所以该种对比大多数是基于存储硬件级别的加持,来实现大量数据的全量对比, 而且只能发现指定时间窗口内的数据最终状态,不能记录数据变化过程。
比如一个账户在时间窗口中账户余额变动多次, 最终在期末达到和期初一样的数额, 那么这种全量对比的方式就没有办法捕获账户中间的变化,所以基于变化数据对比的方式收益率不高, 试用场景并不广泛。
#1.3 表级触发器
现代数据库都具备在表上建立触发器的功能,基于三种操作,Insert、Update 和Delete分别建立对应的触发器。
基于触发器,可以将原始表的所有变化量都保存在另外一张专门记录原始表数据变化的变更历史表中 这个变更历史表中就保存了所有的数据变更历史,那么在数据ETL的时候,就可以精准地获取某个指定时间之后的所有数据变化 或者某个时间窗口中的数据变化情况。
但是缺点在于,触发器会带来系统额外的性能和数据容量的开销,在需要大量数据快速入库的场景中,会导致性能急剧下降,乃至出现数据堆积,影响系统的正常运行。
#1.4 基于日志的变化数据抽取
目前市面上最流行的变化数据捕获方案,主要基于对源数据库的日志的解析,实现对指定数据库表的变化数据的捕获,日志解析可以部署在数据库所在主机,也可以部署在数据库服务器之外,从而最大限度降低对源数据库的性能的影响和侵入。而且可以实现对业务系统的松耦合,灵活配置。并且可以轻松实现跨平台,跨数据库的变化数据捕获和传递。
基于日志捕获变化数据的配置要求
#2.1 MySQL
MySQL 中的基于日志的CDC, 主要是通过对Binlog的解析来实现的, 主要要求如下:
- MySQL数据库为5.7或以上版本。
- 不支持采集二进制类型的字段,例如:TINYBLOB、BLOB、MEDIUMBLOB、LONGBLOB。
Binlog 有三种格式:
- Statement
(Statement-Based Replication,SBR):每一条会修改数据的 SQL 都会记录在 binlog 中。日志量最小,但是由于只记录SQL,那么有可能会出现数据一致性问题;
- Row
(Row-Based Replication,RBR):不记录 SQL 语句上下文信息,仅保存哪条记录被修改。Row格式会清楚地记录数据的变化, 可以确保数据一致性,所以日志量会比较大;
- Mixed
(Mixed-Based Replication,MBR):Statement 和 Row 的混合体。综合上述两种日志类型,自动判断采用什么模式, 可以实现性能和功能的最大化。
如果需要对MySQL 进行CDC的话, 推荐使用后面两种模式。
#2.2 Oracle
因为Oracle Redo log会循环使用, 如果在主库业务繁忙的时候, 有可能会出现数据丢失的现象, 所以, 推荐开启归档模式, 确保所有数据库日志不丢失。
另外,Oracle 补充日志(supplemental log)又叫附加日志,可以指示数据库在日志中添加额外信息到日志流中,以支持基于日志的工具,比如逻辑standby、streams、GoldenGate、LogMiner。所以为了保证捕获完整, 必须打开附加日志。
Oracle 19C不支持 continuous_mine
Oracle LogMiner 是 Oracle 为其 Oracle 数据库的购买者提供的实用程序,提供查询对 Oracle 数据库所做的记录更改的方法,主要是通过引用 Oracle 重做日志中的数据的 SQL 命令。它主要由 DBA 用于查询事务日志。Oracle LogMiner 具有从 Oracle 重做日志提供实时更改的功能。大多数第三方 CDC 工具使用此功能为其客户复制 Oracle 数据。在 19C中,Oracle 也弃用了此功能, 其官方推荐使用Oracle Golden Gate。
目前有不少第三方工具已经找到work around 来解决这一问题。
#2.3 PostgreSQL
逻辑解码是 PostgreSQL 的基于日志的 CDC(逻辑复制)的正式名称。逻辑解码使用 PostgreSQL 预写日志的内容来存储数据库中发生的所有活动。
PG 从PG10 开始提供逻辑复制, 可以通过读取配置复制槽的方式, 通过解析WAL日志来把数据变化传输出来,到指定逻辑槽, 下游可以使用 pg_recvlogical消费逻辑槽中的数据。
#2.4 MongoDB
Change Stream是 v3.6 中引入的一个 MongoDB API。Change Streams 允许应用程序监听实时数据更改,而不会有拖尾oplog(数据库上所有修改操作的滚动记录)的复杂性和风险。应用程序可以使用更改流来订阅单个集合、数据库或整个部署上的所有数据更改,并立即对其做出反应。
更改流仅适用于副本集。这个限制是因为变更流的实现是基于 oplog 的,它只在副本集上可用。
#3.1 Debezium
Debezium是一个开源的捕获数据更改(CDC)平台,并且利用Kafka和Kafka Connect实现了自己的持久性、可靠性和容错性。
每一个部署在Kafka Connect分布式的、可扩展的、容错性的服务中的connector监控一个上游数据库服务器,捕获所有的数据库更改,然后记录到一个或者多个Kafka topic(通常一个数据库表对应一个kafka topic)。
Kafka确保所有这些数据更改事件都能够多副本并且总体上有序(Kafka只能保证一个topic的单个分区内有序),这样更多的客户端可以独立消费同样的数据更改事件,而同时对上游数据库系统造成的影响降到很小(如果N个应用都直接去监控数据库更改,对数据库的压力为N,而用debezium汇报数据库更改事件到kafka,所有的应用都去消费kafka中的消息,可以把对数据库的压力降到1)。
另外,客户端可以随时停止消费,然后重启,从上次停止消费的地方接着消费。每个客户端可以自行决定他们是否需要exactly-once或者at-least-once消息交付语义保证,并且所有的数据库或者表的更改事件是按照上游数据库发生的顺序被交付的。
图源 Debezium Architecture :: Debezium Documentation
#3.2 TapData
Tapdata 开源项目的定位是一个实时数据服务平台,目前已上线的 1.0 版本核心覆盖实时数据同步、实时数据开发、Fluent ETL 等场景,具备全量和增量复制、异构数据库间的同步与转换,表级同步以及任务监控等能力。其工作机制主要包含以下四个环节的功能特性:
- 基于 CDC 的无侵入数据源实时采集;
- 异构数据模型自动推断与转换;
- 数据处理,流式计算,缓存存储一体架构;
- 一键将模型发布为数据服务的闭环能力。
文档 - https://tapdata.github.io/
#3.3 Canal**
Canal 是阿里巴巴旗下的一款开源项目,纯 Java 开发。基于数据库增量日志解析,提供增量数据实时订阅和消费,目前主要支持了 MySQL,也支持 mariaDB。
很多大型的互联网项目生产环境中都有部署,包括阿里、美团等,是一个非常成熟的数据库同步方案,基础的使用只需要进行简单的配置即可。
图源 GitHub - alibaba/canal: 阿里巴巴 MySQL binlog 增量订阅&消费组件
MySQL主备复制原理
图源 GitHub - alibaba/canal:阿里巴巴 MySQL binlog 增量订阅&消费组件
- MySQL master 将数据变更写入二进制日志( binary log,其中记录叫做二进制日志事件binary log events,可以通过 show binlog events 进行查看);
- MySQL slave 将 master 的 binary log events 拷贝到它的中继日志(relay log);
- MySQL slave 重放 relay log 中事件,将数据变更反映它自己的数据。
Canal 工作原理
- Canal 模拟 MySQL slave 的交互协议,伪装自己为 MySQL slave ,向 MySQL master 发送dump 协议;
- MySQL master 收到 dump 请求,开始推送 binary log 给 slave (即 canal );
- Canal 解析 binary log 对象(原始为 byte 流)。
GitHub 地址:https://github.com/alibaba/canal
当前的Canal 支持源端 MySQL 版本包括 5.1.x , 5.5.x , 5.6.x , 5.7.x , 8.0.x。
#3.4 Maxwell
Maxwell 是一个能实时读取 MySQL 二进制日志 binlog,并生成 JSON 格式的消息,作为生产者发送给 Kafka,Kinesis、RabbitMQ、Redis、Google Cloud Pub/Sub、文件或其它平台的应用程序。
应用场景:ETL、维护缓存、收集表级别的 dml 指标、增量到搜索引擎、数据分区迁移、切库 binlog 回滚方案等。
GitHub 地址:https://github.com/zendesk/maxwell
官网 (http://maxwells-daemon.io)
- 支持 SELECT * FROM table 的方式进行全量数据初始化;
- 支持在主库发生 failover 后,自动恢复 binlog 位置 (GTID);
- 可以对数据进行分区,解决数据倾斜问题,发送到 kafka 的数据支持 database、table、column 等级别的数据分区;
- 工作方式是伪装为 Slave,接收 binlog events,然后根据 schemas 信息拼装,可以接受 ddl、xid、row 等各种 event。
#3.5 Flink CDC
Flink CDC Connectors 是 Flink 的一组 Source 连接器,是 Flink CDC 的核心组件,这些连接器负责从 MySQL、PostgreSQL、Oracle、MongoDB 等数据库读取存量历史数据和增量变更数据。Flink CDC Connectors 是一个独立的开源项目。
图源 Overview — CDC Connectors for Apache Flink® documentation (ververica.github.io)
Debezium 官方架构图中,是通过 Kafka Streams 直接实现的 CDC 功能。而Flink CDC优势在于 :
- Flink 的算子和 SQL 模块更为成熟和易用;
- Flink 作业可以通过调整算子并行度的方式,轻松扩展处理能力;
- Flink 支持高级的状态后端(State Backends),允许存取海量的状态数据;
- Flink 提供更多的 Source 和 Sink 等生态支持;
- Flink 有更大的用户基数和活跃的支持社群,问题更容易解决;
- Flink 的开源协议允许云厂商进行全托管的深度定制。
Supported Connectors
#3.6 Integrate.io
Integrate.io被广泛认为是市场上最好的ETL工具之一。它是一个基于云的ETL数据集成平台,可以轻松地将多个数据源联合起来。该平台有一个简单、直观的界面,能够在大量的来源和目的地之间建立数据管道。
该平台还具有高度的可扩展性,任何数据量或使用情况都可以,它使你能够将数据无缝地汇总到仓库、数据库、运营系统和数据存储中。有100多个流行的数据存储和SaaS应用程序包与Integrate.io,包括MongoDB、MySQL、亚马逊Redshift、谷歌云平台和Facebook。
随着用户对实时数据计算的需求越来越多, 现在市场上的CDC工具也越来越成熟, 通过CDC工具把业务系统中的数据变化直接传递到下游的系统中进行消费, 可以是数据分析, 可以是实时大屏, 也可以是用户实时推荐。当然也有用户可以利用CDC工具进行新旧系统切换, 不同平台之间的数据容灾。甚至可以实现云上云下的准实时同步。
当然, 除了开源的CDC工具, 也有不少成熟的商业化产品, 比如OGG、 DSG、英方的i2stream, 对于希望得到企业软件支持的用户, 也可以选用这类产品。
参考文献:
[1] Debezium Architecture :: Debezium Documentation:https://debezium.io/documentation/reference/2.1/architecture....
[2] GitHub - alibaba/canal: 阿里巴巴 MySQL binlog 增量订阅&消费组件:https://github.com/alibaba/canal
[3] Overview-CDC Connectors for Apache Flink®documentation(ververica.github.io):https://ververica.github.io/flink-cdc-connectors/master/conte...
加入StoneDB社区
Github: https://github.com/stoneatom/stonedb
Gitee: https://gitee.com/StoneDB/stonedb
社区官网: https://stonedb.io/
哔哩哔哩: https://space.bilibili.com/1154290084
Twitter: https://twitter.com/StoneDataBase
Linkedin: https://www.linkedin.com/in/stonedb/