ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

DolphinX-Web 实战:数据库 Agent 驱动时序数据入库与分析

DolphinX-Web 实战:数据库 Agent 驱动时序数据入库与分析

1. 为什么要在数据库里塞一个 Agent

第一次听到“数据库自带 Agent”这个说法,我脑子里冒出来的画面是:一个 DBA 坐在机房里,旁边蹲着个机器人帮他写 SQL。后来真正把 DolphinX-Web 这套东西跑起来,才发现方向反了——不是数据库里养了个机器人,而是数据库本身把“数据入库”和“分析查询”这两件原本要写一堆胶水代码的事,收敛成了一套可以对话式驱动的框架。Agent 在这里更像是一个调度中枢,它不替你算数据,但它知道该把数据往哪张表塞、该用哪套分析模板去跑。

DolphinDB 这个库,做量化、做物联网时序、做工业数据分析的人应该不陌生。它的定位是高性能分布式时序数据库,写入吞吐和向量化计算是它的看家本领。但问题也在这儿:DolphinDB 的脚本语言(DolphinDB Script)对新手不算友好,光是建库建表、分区设计、流数据订阅这几步,就够劝退一批只想“把 CSV 导进去看看”的人。DolphinX-Web 要解决的就是这个断层——它把 DolphinDB 的能力包了一层 Web 化的操作界面,再挂上一个 Agent 做智能调度,让你不用背脚本语法也能完成入库和分析。

我实测下来的感受是:如果你手头有一批结构化的时序数据(比如传感器读数、行情快照、日志指标),想快速搭一个能查、能算、能出图的分析框架,这套组合的启动成本确实能压到 10 分钟级别。前提是你得把环境准备好,并且理解它内部几个关键环节是怎么串起来的。这篇文章我就按自己踩过的顺序,把整个搭建过程拆开讲,包括那些官方文档里不会写的坑。

适合谁看?三类人:一是做数据分析但不想深啃 DolphinDB 脚本的;二是想给团队搭一个轻量级数据中台原型的;三是单纯对“Agent 怎么和数据库结合”这个架构模式好奇的。下面进入正题。

2. 整体架构拆解:Agent 到底在哪个位置干活

2.1 三层结构:Web 层、Agent 层、DolphinDB 层

DolphinX-Web 的架构不复杂,但如果不先理清楚,后面配参数的时候会一头雾水。我把它拆成三层来看:

  • Web 交互层:负责接收你上传的文件、输入的查询语句、点击的分析按钮。这一层是纯前端加轻量后端,不碰数据计算。
  • Agent 调度层:这是核心。它接收 Web 层传来的“意图”,比如“把这个 CSV 入库到行情表”或者“算一下过去 7 天的均值”,然后翻译成 DolphinDB 能执行的脚本或 API 调用。
  • DolphinDB 存储与计算层:真正干活的地方。数据存在这里,向量化计算也在这里跑。

Agent 层的关键价值在于“翻译”和“编排”。翻译是指把自然语言或半结构化指令转成 DolphinDB 操作;编排是指决定先建表还是先写数据、分区怎么切、并发怎么控。很多人以为 Agent 就是接个大模型 API,其实在这套框架里,Agent 更多是规则引擎加模板匹配,大模型只在意图识别那一小段起作用。这个认知很重要,因为它决定了你调试的时候该往哪看。

2.2 为什么选 DolphinDB 而不是通用关系库

有人会问:我直接用 MySQL 或 PostgreSQL 不行吗?行,但要看场景。DolphinDB 的优势在时序数据的写入和向量化计算上。举个例子,同样是一亿行传感器数据做滑动窗口均值,DolphinDB 用向量化算子可能几秒出结果,通用关系库用窗口函数可能要几十秒甚至更久。DolphinX-Web 选它做底座,就是冲着这个性能差去的。

但代价是学习曲线。DolphinDB 的分区机制、内存表与分布式表的区别、流数据表的订阅模型,这些概念和传统关系库不一样。DolphinX-Web 的 Agent 层帮你屏蔽了一部分,但不是全部。我的建议是:至少花半小时把 DolphinDB 的“分区”和“分布式表”这两个概念搞明白,否则后面入库的时候数据分布不均,查询会慢得让你怀疑人生。

2.3 Agent 的两种工作模式:模板驱动与意图驱动

实际用下来,Agent 有两种触发方式。一种是模板驱动:你在 Web 界面上选“CSV 入库”,填好表名、分区列、时间列,Agent 就按预设模板生成建表语句和写入逻辑。这种方式稳定、可预测,适合批量操作。另一种是意图驱动:你在对话框里输入“帮我把这批数据按天聚合”,Agent 尝试理解你的意图,匹配到对应的分析模板。这种方式灵活,但边界模糊,容易匹配错。

我的经验是:入库操作一律走模板驱动,别偷懒用自然语言,因为入库涉及表结构定义,一旦 Agent 理解偏了,建出来的表分区不对,后面全得重来。分析查询可以走意图驱动,因为查错了大不了重查,不会污染数据。

3. 环境准备与依赖安装:别跳过这一步

3.1 DolphinDB 服务端的安装与最小配置

DolphinDB 服务端是整套框架的地基。官方提供社区版,单机部署足够跑通 DolphinX-Web。安装过程不复杂,但有几个参数必须提前改。

下载对应平台的安装包后,解压到一个没有中文和空格的路径下。然后找到config目录里的配置文件,重点改这几个:

  • maxMemSize:给 DolphinDB 分配的最大内存。我建议至少给 4GB,如果数据量大就往上加。这个值设太小,入库的时候会直接报内存不足。
  • maxConnections:最大连接数。默认值偏小,Web 层加 Agent 层会占掉几个连接,建议调到 128 以上。
  • dataDir:数据存储目录。别用默认路径,换到一个独立磁盘分区,避免和系统盘抢 IO。

改完配置后启动服务端。启动日志里会打印监听端口,默认是 8848。记住这个端口,后面 Web 层要连它。

注意:DolphinDB 社区版对内存和节点数有限制,如果只是做原型验证够用,但别指望用它扛生产级的高并发写入。

3.2 DolphinX-Web 的部署方式选择

DolphinX-Web 的部署有两种路子:Docker 一键拉起,或者源码手动部署。我两种都试过,说下区别。

Docker 方式适合快速验证。拉镜像、挂载配置、起容器,三条命令搞定。但问题是镜像里的默认配置不一定匹配你的 DolphinDB 地址和端口,得进容器改配置文件,或者用环境变量覆盖。而且 Docker 网络模式下,容器访问宿主机的 DolphinDB 服务需要特殊处理,新手容易卡在这里。

源码部署适合需要定制的情况。克隆代码仓库,装 Python 依赖(主要是 Web 框架和 DolphinDB 的 Python API),改配置文件,然后启动。这种方式你能看到每一层在干什么,出问题也好排查。我的建议是:第一次搭用 Docker 快速跑通,理解流程后再换源码部署做定制。

3.3 Python 环境与 DolphinDB API 的版本匹配

如果你走源码部署,Python 环境这块有个坑:DolphinDB 的 Python API 对版本有要求。我用 Python 3.9 和 3.10 都跑通过,但 3.11 以上某些版本会出现连接超时的问题。保险起见,用 3.9 或 3.10。

安装 API 就是一条 pip 命令,但要注意别和已有的 DolphinDB 相关包冲突。装完后写个三行脚本测试连接:

import dolphindb as ddb s = ddb.session() s.connect("localhost", 8848, "admin", "123456") print(s.run("1+1"))

如果输出 2,说明连接正常。如果报错,先检查 DolphinDB 服务端是否在跑,再检查端口和账号密码。默认账号密码是 admin/123456,生产环境务必改掉。

4. 数据入库全流程:从 CSV 到可查询的表

4.1 数据源准备与格式规范

入库的第一步不是打开 Web 界面,而是把你的数据整理好。DolphinX-Web 支持 CSV 和 JSON 两种格式,我主要用 CSV。CSV 有几个硬性要求:

  • 第一行必须是列名,且列名不能有中文、空格和特殊字符。用下划线代替空格,比如sensor_id而不是sensor id。
  • 时间列必须是标准格式,推荐yyyy-MM-dd HH:mm:ss或者毫秒时间戳。格式不统一的话,Agent 解析时间列会失败。
  • 数值列不要混入空字符串或N/A,要么填 0,要么留空但提前声明该列允许空值。

我踩过的一个坑:CSV 文件用 Excel 编辑后保存,默认编码变成了 GBK,而 DolphinX-Web 默认按 UTF-8 读,结果中文列名全乱码。解决办法是保存时选 UTF-8 编码,或者用文本编辑器转一遍。

4.2 建表策略:分区列怎么选

这是整个入库流程里最关键的决策。DolphinDB 的分区机制直接决定查询性能。DolphinX-Web 的 Agent 会根据你指定的分区列自动生成建表语句,但分区列选得好不好,它不管。

分区列的选择原则:

  • 如果数据有时间列,优先用时间列做分区。按天或按月分区,取决于数据量。一天数据量超过 1000 万行就按天分,否则按月分。
  • 如果数据有明显的类别列(比如设备 ID、股票代码),可以用“时间 + 类别”的组合分区。DolphinDB 支持组合分区,比如先按天分,再按设备 ID 的哈希分。
  • 别用高基数列做分区。比如用毫秒时间戳做分区列,会生成海量小分区,元数据管理开销爆炸。

在 DolphinX-Web 界面上,建表时会有分区类型和分区列的下拉选项。我一般选“范围分区”配时间列,或者“哈希分区”配设备 ID。选完后 Agent 会生成类似这样的脚本:

db = database("dfs://sensor_db", VALUE, 2024.01.01..2024.12.31)

这是按值分区的例子。实际生成的可能更复杂,但逻辑一样。

4.3 入库操作的分步演示

环境准备好、数据整理好、分区策略定好之后,入库本身很快。在 DolphinX-Web 界面上:

  1. 点“数据入库”,选择 CSV 文件。
  2. 系统预览前几行,让你确认列名和类型。这一步要仔细看,Agent 自动推断的类型不一定对。比如它可能把001这样的编号推断成整数,丢了前导零。手动改成字符串类型。
  3. 指定目标表名和分区列。如果表不存在,Agent 会问你是否自动建表。
  4. 点“开始入库”,进度条走完就结束了。

入库过程中,Agent 在后台做的事是:读 CSV、按分区列切分数据块、并发写入 DolphinDB 的分布式表。如果数据量大,它会分批写,避免一次性占满内存。

实操心得:第一次入库先用 1000 行左右的小文件测试,确认表结构和分区没问题,再上全量数据。我见过有人直接传 500 万行,结果分区列选错,删表重来花了半小时。

4.4 入库后的数据校验

入库完成不代表万事大吉。必须做三件事:

  • 查总行数,和源文件对比。少了几行说明有数据被丢弃,通常是类型转换失败。
  • 查时间范围,确认最早和最晚时间正确。如果时间列解析错了,范围会离谱。
  • 随机抽几行,和源数据逐字段对比。

DolphinX-Web 提供了一个简单的查询界面,可以直接跑select count(*) from 表名。如果数字对不上,去 DolphinDB 的日志里找写入错误记录。

5. 分析框架的搭建与查询实操

5.1 内置分析模板的使用

DolphinX-Web 自带一批分析模板,覆盖了常见的时序分析场景:滑动窗口统计、同比环比、异常检测、聚合汇总。这些模板本质上是预写好的 DolphinDB 脚本,Agent 根据你选的模板和参数填充变量后执行。

以滑动窗口均值为例,你在界面上选“滑动窗口”,指定窗口大小(比如 10 分钟)和聚合列(比如 temperature),Agent 生成类似这样的脚本:

select moving(avg(temperature), 10) from 表名

但实际生成的脚本会包含分区裁剪和时间范围过滤,比这个复杂。模板的好处是参数化,你不用改脚本逻辑,只填数字就行。

5.2 自定义查询的编写技巧

内置模板覆盖不了的场景,就得自己写查询。DolphinX-Web 提供了一个查询编辑器,支持 DolphinDB 脚本。这里分享几个实用技巧:

  • 查询时尽量带上时间范围条件。DolphinDB 的分区裁剪依赖时间条件,不带的话会全分区扫描,慢得离谱。
  • 用select而不是exec,除非你确定只要一列数据。
  • 聚合函数尽量用 DolphinDB 内置的向量化版本,比如avg、sum、std,别自己写循环。

如果查询逻辑复杂,可以先在 DolphinDB 的客户端里调试好,再粘贴到 Web 编辑器里。Web 编辑器的报错信息不如客户端详细。

5.3 Agent 辅助分析的边界与局限

Agent 在分析环节能帮你做意图识别和模板匹配,但别指望它理解复杂的业务逻辑。比如你说“算一下异常值”,它可能匹配到 3-sigma 模板,但你的业务里异常的定义可能是“超过阈值且持续 5 分钟”,这种它就处理不了。

我的用法是:Agent 负责快速生成查询骨架,我手动补业务逻辑。这样既省了写基础语法的时间,又保证了逻辑正确。

6. 常见问题与排查技巧实录

6.1 入库失败的高频原因速查

现象可能原因排查方法
进度条卡住不动DolphinDB 连接断开检查服务端日志,确认端口和账号
报类型转换错误CSV 列类型推断错误手动指定列类型后重试
入库后行数偏少空值或格式错误被丢弃查 DolphinDB 写入日志
查询超时分区列选错或未带时间条件检查建表语句的分区设置

6.2 查询性能骤降的排查思路

查询突然变慢,按这个顺序查:

  1. 数据量是不是涨了?分区数是不是太多了?DolphinDB 的分区数超过一定量级,元数据操作会变慢。
  2. 查询有没有带分区裁剪条件?没有的话加时间范围。
  3. DolphinDB 的内存使用率是不是满了?满了会触发磁盘交换,性能断崖式下跌。
  4. 是不是有并发写入在跑?写入和查询抢 IO,错峰执行。

6.3 Agent 调度异常的恢复方法

Agent 偶尔会卡在“正在处理”状态,通常是意图识别超时或模板匹配失败。恢复方法:

  • 刷新 Web 页面,重新提交任务。
  • 如果反复卡住,去 Agent 层的日志里找错误堆栈。常见的是模板参数缺失或类型不匹配。
  • 实在不行,重启 Agent 服务。DolphinX-Web 的 Agent 层是无状态的,重启不丢数据。

避坑技巧:Agent 的配置文件里有个超时参数,默认值偏短。如果数据量大,调长一点,避免任务被误杀。

7. 我踩过的坑与实操心得

第一个坑是分区列选错。我一开始用毫秒时间戳做分区列,结果生成了几十万个小分区,查询直接卡死。后来改成按天分区,同样的查询从几十秒降到一秒内。分区列的选择比什么都重要,这是我最深的体会。

第二个坑是 CSV 编码。用 Excel 另存为 CSV 后编码变成 GBK,入库后中文列名乱码,Agent 匹配不到列,整个流程失败。后来养成习惯,所有 CSV 都用 UTF-8 保存,或者用 Python 的 pandas 转一遍编码。

第三个坑是 Agent 的意图识别。我试过用自然语言描述入库需求,结果 Agent 把“按设备分组”理解成了“按设备 ID 哈希分区”,建出来的表结构和我预期的不一样。从那以后,入库操作我一律用模板驱动,不碰自然语言。

最后一个心得:DolphinX-Web 这套框架适合快速原型,但别把它当生产级方案。它的 Agent 层是规则加模板,不是真正的智能体,复杂业务逻辑还得自己写。但作为“10 分钟搭起一个能查能算的框架”这个目标,它确实做到了。后续如果要扩展,我建议从两个方向入手:一是把常用的分析逻辑固化成自定义模板,二是把 Agent 的意图识别换成更细粒度的规则引擎,减少误匹配。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进