过去几年,企业建设实时数据体系时,首先解决的是"怎么让数据更快地流起来"。
业务数据库通过 CDC 捕获变化,Kafka 承担数据流转,Flink 持续处理,再将结果写入实时数仓或数据湖。相比小时级、T+1 的传统数仓,这套架构把很多业务的数据时效压缩到了分钟甚至秒级。
这套方式今天依然有效。但随着 CDC 和流计算逐渐成为数据平台的基础能力,一个新的问题开始出现:
CDC 已经可以做到秒级,为什么业务看到的数据仍然可能是几分钟前的?
原因并不复杂。CDC 解决的是"变化多久被捕获",但业务真正关心的是"变化多久可以被使用"。从数据库发生变化,到最终能够被报表、指标平台或业务系统查询,中间还要经过流式计算、Checkpoint、数据提交、湖表更新等一系列环节。
实时湖仓因此正在发生一个变化:关注点开始从"有没有实时链路",转向能不能持续交付足够新的数据。
CDC 快,并不等于数据就够新
真正的实时,是整条链路的结果
假设一家零售企业正在计算实时销售额。订单支付完成后,数据库中的状态很快就能通过 CDC 进入 Kafka,但这条变化还要经过 Flink 计算,再写入湖表,形成下游可以读取的新数据。
只要其中一个环节发生积压,最终数据就会变旧。
例如,Flink 出现反压,数据会停留在计算链路中;Checkpoint 时间变长,数据提交就会推迟;持续写入产生越来越多的小文件,也可能逐渐影响后续的数据处理和查询。
所以,企业看到的"数据延迟",并不是一个 CDC 指标,而是整条链路共同作用的结果。
这也是实时数据体系规模扩大之后经常遇到的问题:任务没有失败,数据也一直在处理,但一条原本几十秒的链路,慢慢变成了几分钟。
此时,只继续优化 CDC 已经解决不了问题。
实时湖仓真正难的,是三个目标同时成立
数据越快提交,代价通常也越高
为了让数据更快可见,一个直接的办法是缩短 Flink 的 Checkpoint 周期,让数据更加频繁地提交。
但这种优化不是免费的。在 Flink 流式写入 Paimon 的场景中,数据通常随成功完成的 Checkpoint 提交为新 Snapshot。缩短 Checkpoint 间隔可以减少提交等待时间,但如果任务存在反压或 Checkpoint 耗时过长,实际数据可见延迟未必下降。
Paimon 的写入性能与 Checkpoint 有直接关系,更短的 Checkpoint 意味着更频繁的写入和提交;反过来,在追求更大写入吞吐时,Paimon 官方给出的优化方式之一就是适当增加 Checkpoint Interval。
持续更新还会带来文件组织的问题。
Paimon 的主键表采用 LSM Tree。随着数据不断写入,内部会产生更多需要参与读取的数据文件,因此需要通过 Compaction 定期合并。不同表模式下,Compaction 对读写性能和数据可见性的影响不同,需要结合查询方式和写入负载配置。做得太频繁,又会占用 CPU 和磁盘 I/O,影响实时写入。Paimon 将其明确视为读写性能之间的取舍。
这也是实时湖仓比"接一条 CDC"复杂得多的地方。
企业真正需要平衡的是三件事:
数据要足够新,查询要足够快,存储和计算成本还要可控。
任何一个指标单独做到极致都不困难,难的是让三者在持续运行的数据规模下长期保持平衡。
因此,"最低可以做到几秒"并不是评价实时湖仓最重要的问题。更值得关注的是:在每天持续产生大量增量更新的情况下,这个时效能不能稳定保持,查询会不会随着数据积累越来越慢,背后的计算和存储成本又是否合理。
从"选择流还是批",到"告诉系统数据要多新"
业务真正关心的不是 Streaming Job
不同业务对数据时效的要求,本来就不同。
风控可能需要秒级数据,经营分析允许几十秒,库存管理可能接受几分钟,而财务汇总一小时刷新一次就已经足够。但在传统的数据开发方式中,这些业务要求最终往往变成了一系列工程配置:这个任务跑 Streaming,那个任务跑 Batch;这个 Checkpoint 设 10 秒,另一个任务每小时调度一次。
随着任务越来越多,企业管理的实际上是一堆作业,而不是"数据应该保持多新"。
Flink Materialized Table 正在改变这种方式。在 Flink 中,可以直接通过 FRESHNESS 描述一张物化表允许落后上游数据多长时间。例如:FRESHNESS = INTERVAL '10' SECOND
Flink 再根据这个新鲜度目标选择刷新方式。较短的新鲜度可以通过持续运行的流任务刷新,较长的周期则可以采用批任务定期刷新;在 Continuous 模式下,Freshness 还会进一步影响 Checkpoint 周期。
这个变化值得关注的地方,并不只是多了一个 SQL 参数。
它代表着数据平台的使用方式正在从"我要跑一个实时任务。"逐渐变成:"我希望这份数据最多落后 10 秒。"底层究竟应该使用流计算还是批计算,开始成为平台内部需要处理的问题。
当然,Freshness 并不是绝对 SLA。Flink 也明确说明,系统会尽量达到设定的新鲜度目标,但实际结果仍然受到任务性能、资源和 Checkpoint 等因素影响。
但这种抽象已经指出了实时湖仓下一阶段的方向:"实时"不再只是一种技术架构,而开始成为一种可以描述的数据服务要求。
为什么 Paimon 会成为实时湖仓的重要一环?
实时数据最终还是要成为一张"表"
CDC 解决变化捕获,Kafka 负责数据流转,Flink 负责实时计算,但企业最终使用的通常不是一条消息流,而是一张能够被查询、分析和长期保存的表。
这也是实时湖仓真正需要解决的问题。
传统数据湖更擅长保存大规模历史数据,但面对数据库中不断发生的 Insert、Update、Delete,如果依然依赖周期性重写数据,很难兼顾时效和成本。
Paimon 的价值就在这里。
它让湖表本身具备持续更新能力:利用主键表承接高频变化,通过 Snapshot 管理不同时间点的数据状态,再通过 Compaction 控制持续写入之后的查询成本。于是,实时数据不必只停留在 Kafka 或独立实时数仓中,而可以持续进入湖仓,并和历史数据形成统一的数据状态。
所以,Paimon 并不只是让数据湖"更快",而是让数据湖开始真正处理持续变化的数据。
这也是实时湖仓从"实时旁路"走向统一数据体系的关键一步。
EasyMR 如何让实时链路成为一套可运行的整体?
真正进入生产环境时,只部署一套 Paimon 并不能自动得到实时湖仓。EasyMR 的思路,不是单独提供一个更快的 CDC 工具,而是把实时湖仓所需的接入、计算、存储、查询和运维能力放进同一套企业级底座中。
上游依然需要稳定捕获数据库变化,中间需要流计算处理复杂的数据逻辑,下游需要查询和分析能力,同时还要面对任务运行、资源分配、监控告警和集群运维。
**在数据进入侧,**EasyMR 支持多种主流数据源接入,并通过 Flink CDC 与 Kafka 的集成,把业务库变化持续写入数据湖。CDC 负责捕获变化,Kafka 负责缓冲、解耦和回放,减少上下游系统之间的直接依赖。
**到了存储层,**Paimon 则负责把这些持续发生的变化真正沉淀成可更新、可查询的湖表。EasyMR 将 Paimon 纳入统一湖仓体系,与 Flink、Kafka 以及下游分析能力形成完整链路。
目前,在 EasyMR 的统一湖表建设场景中,基于 Apache Paimon 可以实现秒级的数据时延。
这件事的价值并不只是把一个指标从"分钟"降到了"秒"。
对于实时订单、库存变化、用户行为等持续更新的数据来说,它意味着这些变化可以从业务系统出发,经过 CDC 和 Flink 处理之后直接进入湖表。实时数据不再需要长期停留在一套独立的实时链路中,湖仓本身开始承担实时数据存储和更新的职责。
比"跑到秒级"更重要的是长期稳定运行
而当实时链路真正进入生产,问题还会继续向运维侧延伸。
Flink 是否出现反压、任务资源是否充足、Checkpoint 是否异常、集群服务是否稳定,都会最终影响数据新鲜度。
EasyMR 中的 EasyManager 可以统一管理集群、任务和资源,并提供节点、服务及组件的实时监控和告警能力。对实时湖仓来说,稳定性本身就是新鲜度的一部分------如果集群升级、节点故障或流量高峰都会导致链路长时间中断,那么平时再低的数据延迟也无法构成业务承诺。
这也是企业级实时湖仓与一次技术 Demo 的区别。
实时不是某一次测试达到 5 秒,而是一条链路在持续运行之后,仍然能够稳定把数据控制在业务可以接受的时效范围内。
新鲜度如何成为可管理的业务指标
回过头来看,实时湖仓的发展其实经历了一个很自然的过程。
最早的问题是数据能不能从批处理走向实时处理,因此企业建设 CDC、Kafka 和 Flink;随后,实时数据开始进入数据湖,于是需要 Paimon 这样的湖表处理持续更新;当这些基础能力逐渐成熟以后,下一个问题自然变成:企业应该如何管理不同数据的实时程度?
订单数据也许需要 10 秒,库存数据需要 1 分钟,经营分析可以接受 5 分钟,财务数据则可能只需要小时级。它们没有必要都追求最低延迟。
真正成熟的数据基础设施,应该能够根据业务需要的数据新鲜度,在写入速度、查询性能和资源成本之间选择合适的处理方式。
从这个角度看,实时湖仓的下一阶段并不是继续追求更快的 CDC,而是让"数据有多新"逐渐成为一项可以被定义、管理和持续交付的数据属性**,这也是 EasyMR 建设 Paimon 实时湖仓能力所指向的方向。**