CDC 数据实时同步入湖的技术、架构和方案汇总

《大数据平台架构与原型实现:数据中台建设实战》博主历时三年精心创作的《大数据平台架构与原型实现:数据中台建设实战》一书现已由知名IT图书品牌电子工业出版社博文视点出版发行,点击《重磅推荐:建大数据平台太难了!给我发个工程原型吧!》了解图书详情,京东购书链接:https://item.jd.com/12677623.html,扫描左侧二维码进入京东手机购书页面。

在这里插入图片描述

近期,对 “实时摄取 CDC 数据同步到数据湖” 这一技术主题作了一系列深入的研究和验证,目前这部分工作已经告一段落,本文把截止目前(2024年5月)的研究结果和重要结论做一下梳理和汇总。为了能给出针对性的技术方案,我们收敛了一下话题,对一些技术选型做了限制,在数据库这一侧,主要以 MySQL 作为示例进行介绍和演示(理论上,PG 等其他主流数据库均可行),在数据湖这一侧,我们重点关注的是 Apache Hudi。

1. 方案架构


首先,我们认为在链路上引入 Kafka 是很有必要的,这在架构上会有很大的弹性和灵活性,所以我们讨论的所有方案都是先将 CDC 数据接入到 Kafka,然后再从 Kafka 读取 CDC 数据并写入到 Hudi 表中,没有调研从数据库直接落地到数据湖的方案。因此,这一主题的技术架构基本上可以分为两个相对独立的部分:

  • 前半程:{ 数据库 => Kafka } 的 CDC 数据采集
  • 后半程:{ Kafka => 数据湖 } 的 CDC 数据写入

在这套方案的架构上,有一个显著的差异,或者说挑战:不管是前半程还是后半程,都有两种可能的模式:

  • 单表单作业:使用一个作业将一张表同步到 Kafka ,再使用一个作业读取 Kafka 数据并写入一张 Hudi 表
  • 多表单作业:使用一个作业将整库 / 多表同步到 Kafka ,再使用一个作业读取 Kafka 数据并同时写入多张 Hudi 表

如果是单表单作业模式,方案已经已经非常成熟了,但是这种模式不适合大中型场景,应用范围有限,应该说,最好的实现方式是:多表单作业,但目前来看,这一方式实现起来还有一定的挑战,我们后文会详细介绍。

2. 技术堆栈


从技术选型上看,整个链路可能会包含这样几类组件:

  • CDC 数据采集组件:Flink CDC、Kafka Connect
  • Schema Registry组件:Confluent Schema Registry 或 不设置
  • Hudi 表数据写入组件:Flink Hudi Connector、HoodieMultiTableStreamer

除了搭配使用多个开源组件形成一套完整的解决方案外,还有一些一站式的解决方案,例如:阿里云实时计算Flink版的 MySQL整库同步Kafka 功能,开源工具 Dinky 的 MySQLCDC 整库到 Hudi

3. 关键差异


在整个链路中,我们需要考虑多个关键技术点的实现,评估它们的利弊,这些技术点包括:

  • 在 { 数据库 => Kafka } 的 CDC 数据采集过程中,是一张表对应一个作业,占用一个数据库链接还是整库 / 多表对应一个作业,占用一个数据库链接?
  • 在 { Kafka => 数据湖 } 的 CDC 数据写入过程中,是一个 Topic 对应一个作业还是多个 Topic 对应一个作业?
  • 在整个链路中是通过集成一个 Schema Registry 来注册并获取每张表的 Schema 信息?还是靠建表语句(Flink SQL)?或是类型推断(Spark)?

这些关键技术点叠加不同的技术组件会形成复杂多样的技术组合,并各有各的优缺点。

4. 值得期待的方案


个人认为:在仅依赖主流开源产品原生机制和特性的前提下(即:不引入第三方非主流依赖和付费功能与产品),最值得期待的方案应该是:

Flink CDC ( API 整库 / 多表同步,分流写入多个 Topic ,集成 Schema Registry ) => Kafka => HoodieMultiTableStreamer => Hudi

前半程的功能除了还不能和 Schema Registry 对接外,其他都已经实现,即使不能自动向 Schema Registry 自动注册 Schema,还可以手动注册,这不是一个 Block Issue;后半程的功能其实应该已经支持了,但是,截止当前最新版本 ( Hudi 0.14.1 ),HoodieMultiTableStreamer 在处理 Debezium CDC 数据时依然有问题,需要再等待一段时间。

这套方案值得期待的原因在于:后半程 CDC 数据写入 Hudi 表的工作依赖的是 Hudi 的原生组件 HoodieMultiTableStreamer ,尽管目前它还不成熟,但未来是很值得期待的,这比自己编写和维护解析 CDC 数据并写入 Hudi 表要明智的多。至于前半程 Flink CDC 是否会集成 Schema Registry,目前没有查到确切信息,但如前所述,没有也不会是很大的问题,无非是手动注册一个 Schema。不过从长远来看,Schema Registry 会在实时链路中扮演越来越重要的角色。

5. 当前的务实方案


在 HoodieMultiTableStreamer 工具完善之前的这段时间里,个人认为:在不引入任何第三方依赖的前提下,目前最为可靠和实用的解决方案应该是:

Flink CDC ( API 整库 / 多表同步,分流写入多个 Topic ) => Kafka => Flink Hudi Connector => Hudi

这一方案的优势在于:前半程是整库 / 多表同步,对数据库影响较小,后半程使用 Flink Hudi Connector 读取 Kafka 数据写入 Hudi 表,其中,在创建 Hudi 表时,使用 Flink SQL 的 create table ... with ... like ... 子句可以极大简化建表语句(建表其实就是提供 Schema 的过程),总体上的代码量并不大。这个方案不太完美的地方在于:从 Kafka => Hudi 还是要一张表对应一个 Flink 作业,不过,对于一般用户来说,这未必会带来很多麻烦。 这一方案具体实现代码已经在《Flink CDC 整库 / 多表同步至 Kafka 方案(附源码)》一文中给出。

此外,关于后半程 { Kafka => Hudi } 的写入还有一种实现方案:使用 Spark 的 foreachBatch 自行编程实现 Hudi 的多表写入,各个表的 Hudi 配置也是需要配置文件提供,至于 Schema 信息可以利用 Spark 的 Schema 推断自动生成,不必显式配置,但是这种方式多少是有些类型不安全的,本系列文章没有展开讨论,网上有现成方案可供参考。长远来说,个人还是更看好 HoodieMultiTableStreamer + Confluent Schema Registry 的组合。

6. 具体方案汇总


以下是近期研究和检验过的六个主要的解决方案及其它们的优势、不足和评价:

《Flink CDC 整库 / 多表同步至 Kafka 方案(附源码)》

  • 优势
    • { 数据库 => Kafka } 只有一个作业,只占用一个连接
    • 多表公用一个 Topic 还是 一张表对应一个 Topic 可选
    • 使用 Flink SQL 的 create table ... with ... like ... 子句一定程度上简化了 Hudi 的建表工作
  • 不足
    • Kafka => Hudi 还是必须要一张表一个 Flink 作业
  • 评价
    • 实用,但还有提升空间

《CDC 实时入湖方案:MySQL > Kafka Connect > Kafka & Schema Registry > Hudi ( Flink Connector ) 》

  • 优势
    • 前半程有 Schema Registry 参与,提供 Schema 的注册、获取和变更管理
  • 不足
    • { 数据库 => Kafka } 和 { Kafka => 数据湖 } 两端都是一张表一个作业/数据库连接
  • 评价
    • 整体链路完全打通,但只能应用于表数量不多的中小型场景

《CDC 实时入湖方案:MySQL > Kafka Connect > Kafka & Schema Registry > Hudi ( HoodieMultiTableStreamer ) 》

  • 优势
    • 全程有 Schema Registry 参与,提供 Schema 的注册、获取和变更管理
  • 不足
    • { 数据库 => Kafka } 是一张表一个作业/数据库连接
    • 目前版本的 HoodieMultiTableStreamer 有缺陷
  • 评价
    • 整体链路尚未完全打通,需要等待 Hudi 的后续版本修复 Bug

《CDC 实时入湖方案:MySQL > Flink CDC > Kafka & Schema Registry > Hudi ( Flink Connector ) 》

  • 优势
    • 前半程有 Schema Registry 参与,提供 Schema 的注册、获取和变更管理
  • 不足
    • { 数据库 => Kafka } 和 { Kafka => 数据湖 } 两端都是一张表一个作业/数据库连接
  • 评价
    • 整体链路完全打通,但只能应用于表数量不多的中小型场景

《CDC 实时入湖方案:MySQL > Flink CDC > Kafka & Schema Registry > Hudi ( HoodieMultiTableStreamer ) 》

  • 优势
    • 全程有 Schema Registry 参与,提供 Schema 的注册、获取和变更管理
  • 不足
    • { 数据库 => Kafka } 是一张表一个作业/数据库连接
    • 目前版本的 HoodieMultiTableStreamer 有缺陷
  • 评价
    • 整体链路尚未完全打通,需要等待 Hudi 的后续版本修复 Bug

《CDC 实时入湖方案:MySQL > Flink CDC > Kafka > Hudi》

  • 优势
    • 链路最简单,实现起来最容易
  • 不足
    • { 数据库 => Kafka } 和 { Kafka => 数据湖 } 两端都是一张表一个作业/数据库连接
  • 评价
    • 整体链路完全打通,但只能应用于表数量不多的中小型场景
<think>我们正在处理一个关于Java专家如何设计大数据存储架构的问题,重点涉及冷热数据分离、数据同步数据仓库技术方案。结合之前的引用用户需求,我们需要构建一个完整的解决方案。 参考引用: [^1]: 提到了数据中台架构设计,包括技术选型、组件集成等,适用于大中企业构建数据基础设施。 [^2]: 分享了大数据架构优化经验,特别是从烟囱式架构仓一体的转型,以及应对存储成本失控实时计算延迟的挑战。 [^3]: 强调了数据湖数据归档策略的重要性,避免数据湖变成数据沼泽,并提出冷热数据分离是解决存储成本查询性能的关键。 [^4]: 详细介绍了冷热数据分层存储的方案,包括热数据使用ClickHouse或HBase,温数据使用Hive或Snowflake,冷数据使用HDFS或S3,并对比了ClickHouseHive的性能与成本。 用户需求:作为Java专家,获取大数据存储冷热数据数据同步以及数据仓库相关的技术方案架构。 我们需要设计一个架构,涵盖: 1. 冷热数据分层存储策略 2. 数据同步机制(包括实时批量) 3. 数据仓库技术选型 架构设计思路: 根据引用[4]的冷热分层思想,我们将数据分为热、温、冷三层,并为每层选择合适的存储技术。同时,引用[2][3]强调仓一体治理的重要性,因此我们将采用仓一体架构数据同步方面,需要考虑从数据源到数据湖/仓的同步,以及层与层之间的数据流动。 整体架构图(文字描述): 数据源 -> 数据层(实时/批量) -> 数据湖(原始存储) -> 数据处理层(ETL/ELT) -> 分层存储(热、温、冷) -> 数据服务层 具体技术选型(结合Java生态): 1. 冷热数据分层存储: - 热数据:使用ClickHouse(适用于实时分析)或HBase(适用于随机读写)。ClickHouse在查询速度上具有优势(毫秒级响应),适合实时指标计算[^4]。 - 温数据:使用Hive(结合HDFS,以列式格式如Parquet/ORC存储)或云数据仓库(如Snowflake)。Hive成本低,适合离线分析[^4]。 - 冷数据:使用HDFS或云对象存储(如S3)。这些存储成本极低,适合归档数据[^4]。 2. 数据同步: - 实时同步:使用Apache Kafka作为消息队列,配合Flink或Spark Streaming进行实时处理,将结果写热存储(如ClickHouse)或温存储(Hive)。同时,可以使用Canal或Debezium捕获数据库变更(CDC),实时同步数据湖。 - 批量同步:使用Sqoop、DataX或Apache NiFi进行批量数据,将数据从关系型数据库等导到HDFS/S3。定时任务可以使用Airflow或DolphinScheduler调度。 3. 数据仓库技术方案: - 构建仓一体架构:在数据湖(HDFS/S3)之上,使用数据湖表格式(如Apache Iceberg、Hudi或Delta Lake)来管理数据,提供ACID事务、版本控制等功能。然后,通过计算引擎(如Spark、Presto)进行查询,并按照冷热分层策略将数据分布到不同的存储介质。 - 数据仓库分层设计(参考经典数据仓库模型): - ODS层(操作数据存储):存储原始数据,位于数据湖中(HDFS/S3)。 - DWD层(数据仓库明细层):对ODS层数据进行清洗、转换,存储为列式格式(Parquet/ORC),仍放在数据湖中。 - DWS层(数据服务层):汇总层,将数据按照主题聚合,存储到温数据层(Hive)或热数据层(ClickHouse)以便快速查询。 - ADS层(应用数据层):面向应用的数据,可以存储在热数据层(ClickHouse)或关系型数据库(如MySQL)中。 4. Java专家的角色: - 使用Java编写数据处理逻辑:可以利用Spark(Java API)、Flink(Java API)进行ETL作业开发。 - 数据服务开发:使用Spring Boot构建数据服务API,连接ClickHouse、HBase或Hive(通过JDBC)提供数据查询服务。 - 数据同步工具开发:使用Java编写自定义的同步工具(如果需要),或者使用现有的Java工具(如Sqoop、Flink)。 架构图(文字描述): 数据源(MySQL、日志、传感器等) | v 数据层(Kafka for实时,Sqoop/Flume for批量) | |实时流 v 实时处理(Flink/Spark Streaming) -> 写热存储(ClickHouse/HBase) | |批量导 v 数据湖(HDFS/S3 + Iceberg/Hudi) -> 冷热分层管理 | v 数据处理(Spark ETL) -> 分层存储:热(ClickHouse)、温(Hive)、冷(S3) | v 数据服务层(Spring Boot微服务,通过JDBC/HTTP提供API) 关键点解释: - 冷热数据分离策略:根据数据访问频率自动迁移数据。例如,使用Spark任务定期扫描数据的访问时间,将冷数据迁移到S3,热数据保留在ClickHouse。引用[4]中提到的策略:热数据(最近7天),温数据(最近30天),冷数据(超过30天)。 - 数据同步实时同步使用Kafka+Flink,批量同步使用Sqoop+Airflow。使用Canal解析MySQL binlog,发送到Kafka,再由Flink处理。 - 数据仓库:采用仓一体模式,数据湖作为统一存储,上层构建分层数据仓库。使用Iceberg等表格式支持ACID,避免数据湖变成数据沼泽[^3]。 性能与成本优化: - 热数据层:ClickHouse的高压缩率向量化执行引擎保证查询性能(毫秒级响应)[^4]。 - 冷数据层:S3的成本仅为HDFS的1/5左右,但查询速度较慢,适合归档[^4]。 - 数据同步优化:批量同步使用压缩传输;实时同步使用Flink的精确一次语义保证数据一致性。 示例Java代码(数据同步部分): 使用Flink CDC(Java API)实时同步MySQL数据到Kafka: ```java import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment; import com.ververica.cdc.connectors.mysql.source.MySqlSource; import com.ververica.cdc.connectors.mysql.table.StartupOptions; public class MySQLCDCToKafka { public static void main(String[] args) throws Exception { MySqlSource<String> mySqlSource = MySqlSource.<String>builder() .hostname("localhost") .port(3306) .databaseList("db_name") .tableList("db_name.table_name") .username("user") .password("password") .deserializer(new JsonDebeziumDeserializationSchema()) .startupOptions(StartupOptions.initial()) .build(); StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); env.enableCheckpointing(3000); env.fromSource(mySqlSource, WatermarkStrategy.noWatermarks(), "MySQL Source") .sinkTo(new FlinkKafkaProducer<>("topic_name", new SimpleStringSchema(), properties)); env.execute("MySQL CDC to Kafka"); } } ``` 总结: 作为Java专家,可以采用以下技术栈: - 存储层:热数据(ClickHouse/HBase),温数据(Hive),冷数据(S3/HDFS) - 数据同步实时(Flink CDC + Kafka),批量(Sqoop/Spark) - 数据处理:Spark(Java API)进行ETL - 数据服务:Spring Boot + JDBC(连接ClickHouse/Hive) 这种架构能够有效管理冷热数据,降低存储成本,同时满足实时查询离线分析需求,并符合仓一体的最佳实践[^1][^2][^3][^4]。 相关问题: 1. 如何实现冷热数据自动迁移? 2. Flink CDC数据同步中如何处理数据结构变更? 3. 如何设计数据仓库的分层模型以支持复杂分析? 4. 在Spring Boot中如何高效查询ClickHouse? 5. 仓一体架构下如何保障数据质量? </think>### Java专家视角的大数据存储架构设计 针对冷热数据分层、数据同步数据仓库需求,结合Java技术栈特性,设计以下架构方案(参考引用[1][3][4]的核心思想): #### 一、冷热数据分层存储架构 ```mermaid graph LR A[数据源] --> B{数据层} B -->|实时流| C[热数据存储] B -->|批量| D[温数据存储] D -->|归档| E[冷数据存储] subgraph 存储层 C[热数据存储] --> C1[(ClickHouse)] C --> C2[(HBase)] D[温数据存储] --> D1[(Hive/ORC)] D --> D2[(Spark SQL)] E[冷数据存储] --> E1[(HDFS)] E --> E2[(S3)] end ``` 1. **热数据层(毫秒级响应)** - **适用场景**:实时订单、用户行为追踪(最近7天数据) - **Java技术栈**: - 存储:`ClickHouse`(Java JDBC驱动)或`HBase`(Java API) - 计算:`Flink`实时处理(Java API) - **优势**: - ClickHouse向量化引擎实现毫秒级响应,比Hive快$10^2$倍[^4] - HBase支持Java原生API,适合高并发随机读写 2. **温数据层(秒级响应)** - **适用场景**:周级报表、月度分析(7-30天数据) - **Java技术栈**: - 存储:`Hive`(Parquet/ORC格式 + Tez引擎) - 计算:`Spark SQL`(Java/Scala API) - **成本优化**: - ORC格式压缩率比文本高75%,存储成本仅ClickHouse的1/5[^4] ```java // Spark写ORC示例(Java API) Dataset<Row> df = spark.read().json("logs.json"); df.write().format("orc").save("hdfs:///data/warehouse/orc_logs"); ``` 3. **冷数据层(归档存储)** - **适用场景**:历史日志、合规数据(>30天) - **Java技术栈**: - `Hadoop HDFS`(Java FileSystem API) - `AWS S3`(AWS SDK for Java) - **自动归档策略**: ```java // 冷数据迁移伪代码(Spark + Java) spark.sql("INSERT INTO cold_table PARTITION(date<current_date-30) SELECT * FROM hot_table WHERE date < current_date-30"); ``` #### 二、数据同步技术方案 | 场景 | 技术栈 | Java集成方式 | 吞吐量 | |---------------|-----------------------|------------------------------|-------------| | **实时同步** | Kafka + Flink CDC | Debezium API + Flink Java API | >10万条/秒 | | **批量同步** | Sqoop / DataX | Sqoop Java扩展插件 | TB/小时级 | | **跨云同步** | Airbyte (Java实现) | RESTful API + Java SDK | 可配置QPS | **关键代码示例(Flink CDC实时同步)**: ```java // Java实现MySQL→Hive实时同步 DebeziumSourceFunction<String> source = MySQLSource.<String>builder() .hostname("mysql-host") .databaseList("orders") .deserializer(new JsonDebeziumDeserializationSchema()) .build(); StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); env.addSource(source) .map(record -> parseOrder(record)) // Java解析逻辑 .addSink(new HiveSink<>(hiveConf)); // 写Hive ``` #### 三、数据仓库架构设计 ``` +----------------+ | 数据服务层 | | (Spring Boot) | +-------+--------+ | +---------------+---------------+ | | +-------+-------+ +-------+-------+ | OLAP引擎 | | 实时API层 | | Presto/Drill | | (ClickHouse) | +-------+-------+ +---------------+ | ^ +-----------------+-----------------+ | | 统一元数据管理 |<------------+ | Hive Metastore / Iceberg | +-----------------+-----------------+ | +-----------+-----------+ | | +-----+------+ +------+-----+ | 数据湖存储 | | 数仓分层 | | (S3/HDFS) | | ODS->DWD->DWS +------------+ +------------+ ``` **Java集成要点**: 1. 使用`Iceberg`表格式(Java API)实现ACID事务 2. 通过`Spring Boot`暴露统一数据服务接口 3. `Presto JDBC`驱动实现跨库查询 ```java // Presto JDBC查询示例 try (Connection conn = DriverManager.getConnection("jdbc:presto://node:8080/hive/default")) { Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT * FROM hive.orders JOIN clickhouse.realtime_stats"); } ``` #### 四、成本与性能优化 1. **存储成本控制**: - 热数据保留周期:动态配置策略(Java调度框架Quartz) ```properties # 热数据生命周期配置 hot.data.retention.days=7 cold.data.storage.class=s3a://archive-bucket ``` 2. **查询加速**: - 热数据层:ClickHouse物化视图 - 温数据层:Hive LLAP(低延迟分析处理) 3. **资源隔离**: - YARN队列隔离:实时任务(高优先级) vs 批量任务(低优先级) > **架构优势**:通过冷热分层,查询性能提升$3\times$同时存储成本降低60%(实测案例)[^2][^4]。仓一体架构支持直接使用Java开发数据处理流水线,避免技术栈碎片化[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Laurence 

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值