这里是为您整理的云器技术问答 Vol.2:增量计算 。本期内容聚焦于云器科技的核心技术——通用增量计算 (Generic Incremental Compute, GIC) ,旨在帮助开发者快速理解其原理、关键概念的区别以及相比传统流计算的优势。
🔧 Q1:云器“通用增量计算”的定义是什么?
通用增量计算 (Generic Incremental Compute, GIC) 是一种旨在统一当前主流的批处理、流处理和交互式分析的新型计算模式。其核心原理是:当上游数据发生变化时,系统只计算变化的数据部分($\Delta$), 并将这部分计算结果与之前的查询结果进行合并,从而以最小的运算成本、最快的速度生成最新的查询结果。
它遵循 "SPOT" 标准:
- S (Standard SQL): 使用标准、完整语义的 SQL(包含复杂的 Join 和 UDF),无需像流计算那样引入 Watermark 或 Window 等非标准概念。
- P (Performance): 在一体化架构上,同时获得批处理的高吞吐和流处理的低延迟。
- O (Open Format): 数据采用标准开放格式(如 Iceberg),可被其他引擎读取,支持标准的数仓分层(ODS/DWD/ADS)。
- T (Trade-off): 支持在 T+0(实时)和 T+1(离线)之间进行灵活的平衡调节。
🔧 Q2:云器增量计算能够为用户带来什么?
-
极简的架构 (Kappa Architecture):
- 消除 Lambda 架构,无需维护“流”和“批”两套代码和两套系统,实现增量统一。
-
显著的降本增效:
- 通过只计算 Delta(变化数据),避免了全量计算的资源浪费。
- 资源利用率相比 Flink 大幅优化,无需为维持实时性而保留大量常驻资源。
-
灵活的“不可能三角”平衡:
- 用户可以在数据新鲜度 (Freshness) 、成本 (Cost) 和 性能 (Performance) 之间自由调节。只需调整
REFRESH INTERVAL,即可在秒级延迟和低成本之间切换。
- 用户可以在数据新鲜度 (Freshness) 、成本 (Cost) 和 性能 (Performance) 之间自由调节。只需调整
-
开发效率提升:
- 使用声明式 SQL,开发者只需关注“业务逻辑是什么”,而无需关心“如何处理增量数据”,系统会自动生成增量执行计划。
🔧 Q3:云器增量计算跟 Flink 流式计算的异同点?
虽然两者都处理实时数据,但云器增量计算 (GIC) 旨在通过统一架构解决 Lambda 架构 的复杂性,而 Flink 本质上是基于窗口的流式处理系统。
| 维度 | Apache Flink (流计算代表) | 云器 GIC (增量计算) |
|---|---|---|
| 驱动方式 | 被动计算 (Event Driven): 数据一来就触发计算,对乱序数据敏感。 | 主动计算 (Schedule Driven): 按需调度(如每分钟/每小时),适合批量增量处理。 |
| SQL 标准化 | 非标准 SQL: 需要理解 Watermark, Window, Trigger 等流式特有概念,开发门槛高。 | 标准 SQL: 完全兼容批处理 SQL 语法,无需修改逻辑即可实现增量化。 |
| 数据处理 | Row-based (行式): 逐行处理,吞吐量受限。 | Vector-based (向量化): 基于向量化引擎,处理批量增量数据,性能更高。 |
| 状态管理 | State Backend: 需要维护庞大的中间状态 (State),Checkpoints 开销大。 | Storage-based: 基于湖仓存储 (Lakehouse),无常驻 State,利用 MVCC 处理版本和一致性。 |
| 回撤处理 | 复杂: 需专门机制处理 Retraction,且受窗口限制。 | 原生支持: 将“回撤”视为增量数据的一种形态(增量减),统一处理。 |
总结: 云器 GIC 通过“批处理的吞吐 + 流处理的增量算法”,在同等条件下(传统批/流场景),比 Flink 提效 3X-10X 。
🔧 Q4:为什么说云器增量计算比 Flink 更节省资源?有具体数据吗?
根据白皮书中的性能评估,在同等业务场景下,云器 Lakehouse 的资源消耗通常比 Flink 低 3X-10X (9)。主要原因包括:
- 执行引擎差异: Flink 是基于 Java 的行式处理(Row-based),执行效率相对较低;云器底层是 Native 实现的向量化引擎 (Vectorized Engine) ,在处理批量增量数据时效率极高 。
- 状态管理开销: Flink 为了保证一致性(Exactly-Once),需要维护庞大的 State 并进行 Checkpoint,这消耗了大量 CPU 和 I/O。云器基于湖仓存储,无常驻状态 ,通过 MVCC 和增量读写解决一致性,没有 Checkpoint 的沉重负担 。
- Join 算法优化: Flink 的流式 Join 类似 Nested Loop Join(需频繁点查状态存储,随机 I/O 多);云器的增量 Join 采用 Hash Join ,一次性读取一批增量数据与右表进行批量关联,利用了 Cache 和顺序 I/O,效率更高 。
🔧 Q5:如何快速把离线全量作业转成增量计算作业?
迁移过程非常简单,核心思想是**“保留原始 SQL 逻辑,仅修改表定义”**。
步骤如下:
- 无需重写业务逻辑: 你不需要手动编写复杂的增量识别逻辑(如识别哪些是 Insert,哪些是 Update),也不需要像 Flink 那样添加 Window 定义。
- 修改 DDL 语句:
- 将原本的
1.CREATE TABLE ... 2.INSERT OVERWRITE ... SELECT ... - 改为
CREATE DYNAMIC TABLE ... REFRESH INTERVAL ... AS SELECT ...
- 将原本的
代码对比示例:
❌ 传统离线方式 (全量刷新):
SQL
CREATE TABLE sales_summary (
product_name string,
amount_total bigint
)
INSERT OVERWRITE sales_summary --每10分钟执行一次
SELECT
product_name,
SUM(amount)
FROM sales
GROUP BY product_name
✅ 云器增量方式 (自动增量刷新):
SQL
-- 仅需增加 'DYNAMIC' 关键字和刷新周期配置
CREATE DYNAMIC TABLE sales_summary
REFRESH INTERVAL 10 MINUTE -- 定义期望的新鲜度(如10分钟)
AS SELECT
product_name,
SUM(amount)
FROM sales
GROUP BY product_name;
-- 系统自动识别增量数据,每10分钟仅计算新数据并合并结果
🔧 Q6:云器的View, Materialized View, Dynamic Table, Table Stream 容易混淆,它们有什么区别?
在云器的体系中,这四个概念从“逻辑视图”到“物理增量实体”层层递进,区别如下:
| 概念 | 核心定义与区别 | 典型用途 |
|---|---|---|
| View (普通视图) | 逻辑定义,无存储。 每次查询时都会重新执行定义的 SQL。 | 简化复杂查询的别名,不涉及数据存储或预计算。 |
| Materialized View (物化视图) | 物理存储。 通常用于单表的查询重写优化,其能力基本和Dynamic Table 等价(部分功能未放开,比如不支持按分区刷新)。 | 数据库内部的透明查询加速(Query Rewrite)。 |
| Dynamic Table (动态表) | **增量计算的核心实体。 | |
| 1.支持复杂逻辑:** 可基于复杂 SQL(含 Joins, Unions)定义。 | ||
| 2. 自动化 Pipeline: 专为构建多级数据管道设计,系统自动管理刷新逻辑和依赖关系。 | ||
| 3. 增量刷新: 仅处理增量变化数据,而非全量重算。 | 替代传统的 ETL 任务,构建实时/近实时数仓(ODS -> DWD -> ADS)。 | |
| Table Stream (数据流) | 数据的变化日志 (Change Log)。 它不是表的状态,而是记录表在两个时间点之间发生的 DML 操作(Insert/Update/Delete)。 | 类似于数据库的 CDC (Change Data Capture),用于下游精确消费上游的“变化量”。 |
一句话总结: 如果你要构建自动刷新的实时数仓链路,请使用 Dynamic Table ;如果你需要获取原始的变更记录(CDC),请使用 Table Stream 。
👉 了解更多 DYANMIC TABLE 与 TABLE STREAM
🔧 Q7:云器增量任务的调度策略有哪些?是只能按时间调度吗?
不是。云器实现了调度系统与 SQL 逻辑的解耦,支持两种灵活的调度模式,以适应不同的业务需求:
-
按时间周期性调度 (Periodic):
- 机制: 设定固定间隔(如 1分钟、10分钟、1小时)触发刷新。
- 场景: 绝大多数近实时场景。优势在于可以“积攒”一批增量数据进行批处理,利用向量化引擎的高吞吐优势,显著降低资源成本 。
-
根据依赖触发调度 (Dependency Driven):
- 机制: 基于任务间的 DAG(有向无环图)依赖关系。例如,只有DWD层的任务清洗之后,才会触发 DWS层的任务汇总。
- 场景: 数仓分层处理,用户可以不改变已有的调度逻辑,快捷的把离线作业改造成增量计算作业。
🔧 Q8:云器增量计算如何处理“数据回撤 (Retraction)”和“延迟数据 (Late Event)”?
在流计算中,处理上游数据的修改/撤回(Retraction)和乱序到达(Late Event)通常需要复杂的水位线(Watermark)和窗口机制。云器通过通用增量模型简化了这一过程:
-
数据回撤 (Retraction):
- 传统流计算: 需要在状态存储(StateStore)中保存窗口内的全量数据,当回撤发生时,通过 KV 查找定位并执行相反操作 。
- 云器增量计算: 将“回撤”视为增量数据的一种标准形态(例如 CDC 中的 Delete 或 Update 操作)。引擎将所有对数据的修改统一抽象为增量数据集(Delta),通过标准 SQL 逻辑自动处理这些 Delta,无需用户感知。
-
延迟数据 (Late Event):
- 传统流计算: 往往需要丢弃或者等待,依赖 Watermark 机制。
- 云器增量计算: 天然支持延迟数据。因为增量计算基于动态表(Dynamic Table)和存储层(Lakehouse),延迟到达的数据会被识别为新的增量批次,系统会自动触发刷新将其合并到结果中,保证最终一致性,且无需为了“等待数据”而阻塞计算资源 。
🔧 Q9:使用云器增量计算时有什么限制?比如使用 current_timestamp 会怎样?
增量计算的核心假设是**“利用历史计算结果 + 新增变化量 = 新结果”。如果 SQL 中包含 不确定性函数(Non-deterministic Functions),会破坏这一假设。但在云器目前的实现中,对这一限制进行了智能放宽** :
- 支持增量的场景(透传模式): 只要不确定性函数不影响数据行数及核心算子逻辑(即不出现在 Filter、Join Key、Group Key 或 Window Partition Key 上),系统依然支持增量计算。例如,仅在
SELECT子句中使用current_time来记录某一行数据的插入时间,系统会保留当时计算出的值并透传写入结果表,不会触发全量重算。 - 回退全量的场景(影响逻辑): 如果不确定性函数直接参与了数据过滤、关联或分组(例如
WHERE time > now()),为了保证结果正确性,系统会自动回退为全量模式。 - UDF 声明: 对于用户自定义函数(UDF),开发者需要显式声明该函数是否为“确定性函数”,以便增量引擎自动识别并决定是否开启增量优化。
🎯 总结
本文主要解答了云器通用增量计算的四大核心问题 :
- 是什么? 通过"只算变化"实现批流统一的新型计算模式,遵循 SPOT 标准(标准SQL、高性能、开放格式、灵活权衡)
- 为什么用? 消除 Lambda 架构复杂性,资源消耗比 Flink 低 3-10倍,开发效率大幅提升
- 怎么用? 离线作业迁移只需将
INSERT OVERWRITE改为CREATE DYNAMIC TABLE,保留原有 SQL 逻辑即可 - 深入细节: 核心概念辨析(Dynamic Table vs Table Stream)、调度策略、数据回撤/延迟处理、以及使用限制
如果您在使用过程中遇到其他问题,欢迎:
本文是「云器技术问答」系列的第二期,我们会持续分享客户关心的技术话题和最佳实践,敬请关注后续内容。
🎁 新用户专享福利
✅ 1 TB 存储 · 1 CRU时/天计算 · 1 年全托管体验
➤ 即刻访问云器官网领取:https://www.yunqi.tech/product/one-year-package


