基于FlinkSQLCDC的实时数据同步方案
基于FlinkSQLCDC的实时数据同步⽅案
Flink 1.11 引⼊了 Flink SQL CDC,CDC 能给我们数据和业务间能带来什么变化?本⽂由 Apache Flink PMC,阿⾥巴巴技术专家伍翀(云邪)分享,内容将从传统的数据同步⽅案,基于 Flink CDC 同步的解决⽅案以及更多的应⽤场景和 CDC 未来开发规划等⽅⾯进⾏介绍和演⽰。
汽车指示灯1、传统数据同步⽅案
2、基于 Flink SQL CDC 的数据同步⽅案(Demo)
3、Flink SQL CDC 的更多应⽤场景
4、Flink SQL CDC 的未来规划
传统的数据同步⽅案与 Flink SQL CDC 解决⽅案
业务系统经常会遇到需要更新数据到多个存储的需求。例如:⼀个订单系统刚刚开始只需要写⼊数据库即可完成业务使⽤。某天 BI 团队期望对数据库做全⽂索引,于是我们同时要写多⼀份数据到 ES 中,改造后⼀段时间,⼜有需求需要写⼊到 Redis 缓存中。
很明显这种模式是不可持续发展的,这种双写到各个数据存储系统中可能导致不可维护和扩展,数据⼀致性问题等,需要引⼊分布式事务,成本和复杂度也随之增加。我们可以通过 CDC(Change Data Capture)⼯具进⾏解除耦合,同步到下游需要同步的存储系统。通过这种⽅式提⾼系统的稳健性,也⽅便后续的维护。
Flink SQL CDC 数据同步与原理解析
CDC 全称是 Change Data Capture ,它是⼀个⽐较⼴义的概念,只要能捕获变更的数据,我们都可以称为 CDC 。业界主要有基于查询的 CDC 和基于⽇志的 CDC ,可以从下⾯表格对⽐他们功能和差异点。
经过以上对⽐,我们可以发现基于⽇志 CDC 有以下这⼏种优势:
能够捕获所有数据的变化,捕获完整的变更记录。在异地容灾,数据备份等场景中得到⼴泛应⽤,如果是基于查询的 CDC 有可能导致两次查询的中间⼀部分数据丢失
每次 DML 操作均有记录⽆需像查询 CDC 这样发起全表扫描进⾏过滤,拥有更⾼的效率和性能,具有低延迟,不增加数据库负载的优势
⽆需⼊侵业务,业务解耦,⽆需更改业务模型
捕获删除事件和捕获旧记录的状态,在查询 CDC 中,周期的查询⽆法感知中间数据是否删除
基于⽇志的 CDC ⽅案介绍
从 ETL 的⾓度进⾏分析,⼀般采集的都是业务库数据,这⾥使⽤ MySQL 作为需要采集的数据库,通过 Debezium 把 MySQL Binlog 进⾏采集后发送⾄ Kafka 消息队列,然后对接⼀些实时计算引擎或者 APP 进⾏消费后把数据传输⼊ OLAP 系统或者其他存储介质。
宿建德江的意思翻译Flink 希望打通更多数据源,发挥完整的计算能⼒。我们⽣产中主要来源于业务⽇志和数据库⽇志,Flink 在业务⽇志的⽀持上已经⾮常完善,但是在数据库⽇志⽀持⽅⾯在 Flink 1.11 前还属于⼀⽚空⽩,这就是为什么要集成 CDC 的原因之⼀。
Flink SQL 内部⽀持了完整的 changelog 机制,所以 Flink 对接 CDC 数据只需要把CDC 数据转换成 Flink 认识的数据,所以在 Flink 1.11 ⾥⾯重构了 TableSource 接⼝,以便更好⽀持和集成 CDC。
重构后的 TableSource 输出的都是 RowData 数据结构,代表了⼀⾏的数据。在RowData 上⾯会有⼀个元数据的信息,我们称为RowKind 。RowKind ⾥⾯包括了插⼊、更新前、更新后、删除,这样和数据库⾥⾯的 binlog 概念⼗分类似。通过 Debezium 采集的JSON 格式,包含了旧数据和新数据⾏以及原数据信息,op 的 u表⽰是 update 更新操作标识符,ts_ms 表⽰同步的时间戳。因此,对接Debezium JSON 的数据,其实就是将这种原始的 JSON 数据转换成 Flink 认识的 RowData。
选择 Flink 作为 ETL ⼯具
当选择 Flink 作为 ETL ⼯具时,在数据同步场景,如下图同步结构:
通过 Debezium 订阅业务库 MySQL 的 Binlog 传输⾄ Kafka ,Flink 通过创建 Kafka 表指定 format 格式为 debezium-json ,然后通过 Flink 进⾏计算后或者直接插⼊到其他外部数据存储系统,例如图中的 Elasticsearch 和 PostgreSQL。
但是这个架构有个缺点,我们可以看到采集端组件过多导致维护繁杂,这时候就会想是否可以⽤ Flink SQL 直接对接 MySQL 的 binlog 数据呢,有没可以替代的⽅案呢?
答案是有的!经过改进后结构如下图:
社区开发了 flink-cdc-connectors 组件,这是⼀个可以直接从 MySQL、PostgreSQL 等数据库直接读取全量数据和增量变更数据的source 组件。
flink-cdc-connectors 可以⽤来替换 Debezium+Kafka 的数据采集模块,从⽽实现 Flink SQL 采集+计算+传输(ETL)⼀体化,这样做的优点有以下:
开箱即⽤,简单易上⼿
减少维护的组件,简化实时链路,减轻部署成本
减⼩端到端延迟
Flink ⾃⾝⽀持 Exactly Once 的读取和计算
数据不落地,减少存储成本
⽀持全量和增量流式读取
binlog 采集位点可回溯
基于 Flink SQL CDC 的数据同步⽅案实践
下⾯给⼤家带来 3 个关于 Flink SQL + CDC 在实际场景中使⽤较多的案例。在完成实验时候,你需要 Docker、MySQL、Elasticsearch 等组件,具体请参考每个案例参考⽂档。
案例 1 : Flink SQL CDC + JDBC Connector
这个案例通过订阅我们订单表(事实表)数据,通过 Debezium 将 MySQL Binlog 发送⾄ Kafka,通过维表 Join 和 ETL 操作把结果输出⾄下游的 PG 数据库。
案例 2 : CDC Streaming ETL
模拟电商公司的订单表和物流表,需要对订单数据进⾏统计分析,对于不同的信息需要进⾏关联后续形成订单的⼤宽表后,交给下游的业务⽅使⽤ ES 做数据分析,这个案例演⽰了如何只依赖 Flink 不依赖其他组件,借助 Flink 强⼤的计算能⼒实时把 Binlog 的数据流关联⼀次并同步⾄ ES 。
例如如下的这段 Flink SQL 代码就能完成实时同步 MySQL 中 orders 表的全量+增量数据的⽬的。
CREATE TABLE orders (
order_id INT,
order_date TIMESTAMP(0),
customer_name STRING,
price DECIMAL(10, 5),
product_id INT,
order_status BOOLEAN
) WITH (
'connector' = 'mysql-cdc',
'hostname' = 'localhost',
'port' = '3306',
帝血弑天刷图加点
'username' = 'root',
贬义词
'password' = '123456',
'database-name' = 'mydb',
'table-name' = 'orders'
);
SELECT * FROM orders
为了让读者更好地上⼿和理解,我们还提供了 docker-compose 的测试环境。
案例 3 : Streaming Changes to Kafka
下⾯案例就是对 GMV 进⾏天级别的全站统计。包含插⼊/更新/删除,只有付款的订单才能计算进⼊ GMV ,观察 GMV 值的变化。
Flink SQL CDC 的更多应⽤场景
Flink SQL CDC 不仅可以灵活地应⽤于实时数据同步场景中,还可以打通更多的场景提供给⽤户选择。
Flink 在数据同步场景中的灵活定位
如果你已经有 Debezium/Canal + Kafka 的采集层 (E),可以使⽤ Flink 作为计算层 (T) 和传输层 (L)
也可以⽤ Flink 替代 Debezium/Canal ,由 Flink 直接同步变更数据到 Kafka,Flink 统⼀ ETL 流程
如果不需要 Kafka 数据缓存,可以由 Flink 直接同步变更数据到⽬的地,Flink 统⼀ ETL 流程
Flink SQL CDC : 打通更多场景
实时数据同步,数据备份,数据迁移,数仓构建
优势:丰富的上下游(E & L),强⼤的计算(T),易⽤的 API(SQL),流式计算低延迟
数据库之上的实时物化视图、流式数据分析
索引构建和实时维护
业务 cache 刷新
审计跟踪
沐川击
微服务的解耦,读写分离
基于 CDC 的维表关联
下⾯介绍⼀下为何⽤ CDC 的维表关联会⽐基于查询的维表查询快。
岩字组词
基于查询的维表关联
⽬前维表查询的⽅式主要是通过 Join 的⽅式,数据从消息队列进来后通过向数据库发起 IO 的请求,由数据库把结果返回后合并再输出到下游,但是这个过程⽆可避免的产⽣了 IO 和⽹络通信的消耗,导致吞吐量⽆法进⼀步提升,就算使⽤⼀些缓存机制,但是因为缓存更新不及时可能会导致精确性也没那么⾼。
基于 CDC 的维表关联

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。