说说基于 DolphinDB 3.00.x 实时聚合计算:多维度聚合实战(从流式引擎到 Cube/Rollup 方法论)

最近在做优化的时候涉及到了这块内容,觉得值得写下来,方便以后翻阅。

摘要:本文面向要处理物联网、金融行情等高频时序数据的开发者,系统讲解如何在 DolphinDB 3.00.x 中落地实时聚合与多维度聚合。文章从 DolphinDB 引擎能力、实时聚合计算本质、多维度聚合概念三个前置概念切入,逐层展开基础聚合、Cube 与 Rollup 层级聚合、时间序列聚合引擎的实战写法,并给出增量、并行、预聚合三类性能优化方案。每个环节均配可运行脚本与预期输出,最后以一个完整的实时聚合系统案例收尾,并提示适用边界与风险。读完应能独立搭建一套支撑秒级刷新的多维度实时聚合管道。

文章目录

九、实战案例:分钟级实时聚合系统 十、适用边界与风险提醒总结与思考题

引言

在物联网、金融行情、工业监控等场景中,数据以每秒数万甚至数十万条的速率持续产生。业务侧却往往只要「每分钟每设备的平均温度」「每个区域当天的累计产量」这类被压缩过的汇总值。如果每次查询都对全量明细做 GROUP BY,延迟会随数据量线性膨胀,根本扛不住看板的高频刷新。

一个典型的踩坑是:某工厂把每分钟 10 万条的传感器数据全量存进关系库,再用定时任务每 5 秒做一次 GROUP BY 出看板。结果表越来越大,查询越来越慢,看板刷新从秒级退化到分钟级,运维被迫不断加从库。问题的根因不是 SQL 写得差,而是把「实时聚合」当成了「高频批处理」。本文要建立的认知是:聚合应当发生在数据写入的那一刻,而不是被查询的那一刻。

本文基于 DolphinDB 3.00.x(文中的窗口函数、createTimeSeriesEngine 等写法均在该系列验证;低于 2.00 的旧版本在分组语法上存在差异,见第十节替代方案)展开。我们会从三个基础概念讲起,再落到可运行的脚本、性能优化与完整案例,目标是让你带走一套「流数据进来、聚合结果秒出」的落地方法,而不是只记住几个函数名。

一、什么是 DolphinDB(概念拆解)

DolphinDB 是一款面向海量时序与关系数据的高性能数据库,内核同时集成了分布式存储、向量化计算与流计算能力。它最尤其的地方在于:关系型查询(SQL 风格)、过程式脚本(类 Python 的 def/for/if)和流计算引擎被统一在同一个运行时里,开发者无需在「数据库」与「计算框架」之间来回搬运数据。

为什么选它做实时聚合?核心机制有三点。第一,列式存储加向量化执行,让 sum/avg 这类聚合在单机上也能吃满 CPU;第二,原生流表(streamTable)支持订阅发布,新数据到达即可被引擎消费;第三,内置多种聚合引擎(时间序列、横截面、响应式状态等),把「窗口 + 分组 + 聚合」这套高频需求封装成了声明式接口。理解了这三点,后面所有写法都是在「用对引擎、喂对数据」。

当然,DolphinDB 也不是所有聚合场景的唯一答案。若你的数据量很小(日增百万行以内)、查询 QPS 很低,用 MySQL 加索引做定时聚合完全够用,引入 DolphinDB 反而增加学习与运维成本。只有当你面临「高吞吐写入 + 低延迟多维查询 + 要流式能力」三者叠加时,它的流批一体与向量化优势才真正值回票价。选型的核心判据是吞吐与延迟,而非「新不新潮」。

和 InfluxDB、TDengine 等专精时序存储的数据库相比,DolphinDB 的差异化在于「计算」而非「存储」:前者通常把聚合下推到查询层或连续查询(CQ),后者则在统一的运行时内提供有状态引擎。当你需要的不只是存点查线,而是麻烦的多维度 Cube、上卷下钻、与过程式逻辑混编时,DolphinDB 的脚本能力会更顺手。但反过来,纯写入型指标采集场景,轻量的专用时序库部署成本更低。按需取舍即可,不要为了用而用。

二、什么是实时聚合计算(概念拆解)

实时聚合计算,指的是数据在「产生后极短时间内」被持续地汇总成统计值,而不是等一天收尾后跑批。它的本质是把聚合的计算成本从「查询时」平摊到「写入时」:每来一条明细,引擎就更新对应窗口的累计状态,窗口触发时直接输出结果,查询端拿到的是已经算好的值。

与离线批处理相比,实时聚合的关键差异在「状态」二字。批处理每次都从零扫描全量;实时聚合一定要维护跨批次的累计状态(如当前窗口的求和、计数、极值)。这也是为什么 DolphinDB 提供了 createTimeSeriesEngine 这类有状态引擎——它替你保管窗口状态,你只需声明「按什么列分组、用什么窗口、算哪些指标」。搞清楚状态由谁保管,是避免重复造轮子的前提。

这里要区分「实时」与「近实时」。严格实时要求数据到达即反映到结果,对延迟极度敏感;而近实时(如秒级、分钟级)允许一个窗口的滞后,工程上更常见也更稳妥。DolphinDB 的时间序列引擎本质是「近实时」:它按固定窗口(如 60 秒)触发计算,结果天然带一个窗口的延迟。理解这一点能避免一个常见误区——不要指望流引擎给出「当前这一秒的精确累计值」,它给的是「上一个完整窗口的聚合值」。下面是整体数据流向。

单维度

多维度

层级

原始明细流

选择聚合类型

单表 / 分组聚合

多列分组 / Cube

Rollup 上卷下钻

聚合结果表

看板 / 下游查询

三、什么是多维度聚合(概念拆解)

多维度聚合指的是在同一个明细数据集上,按多个业务维度(设备、时间、区域、产品等)同时产出不同粒度的汇总。它要解决的典型问题是:运营既想看「每台设备」,也想看「每个区域」,还想看「设备×小时」的交叉视图,而明细只有一份。

经典的多维度建模思路有 Cube 和 Rollup 两种。Cube 枚举所有维度组合的聚合并集(如 设备、小时、设备×小时);Rollup 则按层级从细到粗逐级上卷(设备 → 车间 → 工厂)。二者都不需要为每种视图各写一份查询,而是用一次扫描 + 组合的方式产出多粒度结果。下面几节会用 DolphinDB 脚本把这两种思路真正跑起来,并说明它们各自适合什么场景。

多维度聚合的第一步是选对维度。常见维度与典型用法如下,选型时应以「业务真正会被查询」为准,而非把所有维度都堆进去。

维度说明典型用法时间维度按时间分桶分钟/小时/天趋势设备维度按设备分群单设备画像、故障定位产品维度按产品线产线对比、良率分析区域维度按地理位置区域汇总、运力调度

那么 Cube 和 Rollup 该怎么选?一个实用的判断标准是:如果你的下游需要「任意维度的交叉透视」(像是既按设备又按区域随意组合切片),Cube 更合适,因为它预先枚举了主要组合;如果你只关心「从细到粗的层级汇总」(设备汇总到车间、再到工厂),Rollup 更省资源,因为它只算层级路径上的粒度,不会为不存在的组合浪费算力。在维度不多(2-3 个)时,两者成本接近;维度一旦超过 4 个,务必先做维度裁剪再决定。

四、基础聚合:单表、分组与条件聚合

在动手写实时管道前,先用普通表把三种最基础的聚合写法打牢。下面的脚本把单表聚合、分组聚合、条件聚合放在同一个文件里,输入是一张含 device_idtimestamptemperature 的明细表,输出是聚合结果表。注意 DolphinDB 用 iif 达成条件求和,这点与标准 SQL 的 CASE WHEN 等价。

下面先给出最常用的六个聚合函数及其在多维度场景下的典型用法,便于后续按需组合。

聚合函数作用多维度场景示例sum求和各设备累计温度、区域总产量avg均值设备小时均温、产线平均良率max / min极值阈值告警、最值定位count计数采样点数、在线设备数std标准差波动监控、异常初筛

```
// 基础聚合:单表聚合 / 分组聚合 / 条件聚合
// 输入:一张包含 device_id、timestamp、temperature 的表 t
// 输出:聚合结果表

def basicAggregation(t) {
return select sum(temperature) as total,
avg(temperature) as mean,
max(temperature) as max_val,
min(temperature) as min_val,
count() as cnt,
std(temperature) as std_val
from t
}

def groupAggregation(t, groupCol) {
return select eval(groupCol) as grp,
sum(temperature) as total,
avg(temperature) as mean,
count(
) as cnt
from t
group by eval(groupCol)
}

def conditionalAggregation(t) {
return select sum(iif(temperature > 25, temperature, 0)) as high_sum,
sum(iif(temperature 25, 1, 0)) as high_cnt,
count(iif(temperature 说明:本文脚本均在 DolphinDB 3.00.x 验证;图中架构为示意,发布前建议替换为真实系统截图。


本次分享就到这里。技术这东西越研究越有意思,后续有新的收获我也会继续更新。

评论 (0)

暂无评论