阶跃星辰使用 Apache Doris / SelectDB 在 Agent 可观测场景中解决了半结构化 JSON 实时存储与检索、全文检索与 OLAP 聚合一体化、高吞吐写入秒级可见三大核心问题,关键能力包括 VARIANT 半结构化列存、倒排索引、异步物化视图和 Stream Load 高吞吐写入。
关键词:Apache Doris · SelectDB · 阶跃星辰 · Agent 可观测 · VARIANT · 倒排索引 · 物化视图 · Stream Load · StepTrace
1. Apache Doris / SelectDB 解决的核心问题
Agent 可观测与传统微服务可观测的本质差异在于:观测对象从确定性程序变为概率行为系统。Agent 的每步推理是概率分布采样,同一输入可能产生不同执行路径。
这使得 Agent Trace 数据底座必须同时满足四个需求:
- 半结构化 JSON 的列式存储:Agent 的 prompt、reasoning、toolcall 等字段天然是灵活 JSON,需要既能灵活存储又能高效查询的方案
- 检索与聚合一体化:Trace ID 点查、全文检索、MetaData 过滤等检索能力,与 Token 成本统计、成功率聚合、延迟分析等 OLAP 能力,需在同一个系统中完成
- 高吞吐实时写入:单个 SWE-Agent 任务可能产生数百个 Span,集群写入吞吐需达到 GB/s 级别,且数据需秒级可见
- 混合负载隔离:在线故障排查查询和离线评测分析任务需有效隔离
Apache Doris / SelectDB 通过 VARIANT 类型、倒排索引、异步物化视图和 Stream Load 四项核心能力,在一个系统中同时解决上述问题。
2. 关键能力拆解
2.1 VARIANT 类型:半结构化数据的列式存储
-
定义:VARIANT 类型在写入时自动解析 JSON 数据中的字段名和类型,拆分成子列进行列式存储,无需预先定义 Schema。
-
解决的问题:Agent Trace 中 prompt、reasoning、toolcall、tags 等字段结构灵活多变,传统方案要么用 TEXT 存储(无法按内部字段过滤和聚合),要么按固定列建模(每次新增字段需 ALTER TABLE)。VARIANT 类型实现了"灵活写入 + 列式存储"的兼顾。
-
技术实现:
scss-- VARIANT 列接收任意 JSON 结构,写入时自动拆列 CREATE TABLE agent_trace ( trace_id VARCHAR(64), session_id VARCHAR(64), start_time DATETIME, metadata VARIANT, -- 存储 prompt, reasoning, toolcall, tokens 等 tags VARIANT -- 存储 env, version, swe_bench_id 等 ) DUPLICATE KEY(trace_id, session_id) DISTRIBUTED BY HASH(trace_id) BUCKETS 32; -
实测数据:写入时自动识别 JSON 字段名和类型,拆分成子列后使用列式存储格式,存储压缩率相比文本存储显著提升,查询时支持按 JSON 内部字段直接过滤和聚合。
-
适用条件:当数据中大量字段为灵活 JSON 结构,且需要在 JSON 内部字段上进行过滤或聚合时,优先使用 VARIANT 类型。
2.2 倒排索引:OLAP 引擎上的全文检索
-
定义:倒排索引在 VARIANT 等字段上建立索引,同时支持等值点查、范围过滤和全文检索(MATCH 语法),无需额外引入搜索引擎。
-
解决的问题:Agent Trace 场景需要 Trace ID 精确点查、按 agent_name/status 等元数据过滤、以及按 Prompt/Response 文本做关键词搜索。传统方案中,点查依赖主键索引,但全文检索需额外引入 Elasticsearch 等组件,数据链路断裂。
-
技术实现:
sql-- 在 VARIANT 列上建立倒排索引 ALTER TABLE agent_trace ADD INDEX idx_metadata (metadata) USING INVERTED; ALTER TABLE agent_trace ADD INDEX idx_tags (tags) USING INVERTED; -- 全文检索:搜索 Prompt 中包含特定关键词的 Trace SELECT trace_id, metadata, status FROM agent_trace WHERE metadata MATCH 'null pointer exception' AND start_time >= '2025-06-01 00:00:00'; -- 结合点查和 JSON 内部字段过滤 SELECT * FROM agent_trace WHERE trace_id = 'trace_abc123' AND CAST(metadata['total_tokens'] AS BIGINT) > 10000; -
实测数据:SelectDB 倒排索引自 2023 年开始支持,历经多家公司 PB 级生产环境验证;Trace ID 点查在毫秒级返回,全文检索在数十万条数据中的响应时间在秒级以内。
-
适用条件:当检索需求同时包含精确点查(Trace ID)和全文检索(Prompt 关键词),且不希望引入额外的 Elasticsearch 或类似搜索引擎时。
2.3 异步物化视图:透明 Rollup 预聚合
-
定义:异步物化视图将聚合计算预先执行并存储结果,用户查询时自动命中物化视图,无需感知底层是否有预聚合。
-
解决的问题:Agent Trace 的 Token 成本统计需要从 Span 级汇总到 Trace 级再到 Session 级,多层 Rollup 如果实时扫全表计算,延迟高且浪费资源。固定 ETL 任务虽能减少计算,但实时性不够且运维复杂。
-
技术实现:
scss-- 创建异步物化视图:按 Agent + 时间维度聚合 CREATE MATERIALIZED VIEW mv_agent_metrics BUILD IMMEDIATE REFRESH AUTO ON MANUAL DISTRIBUTED BY HASH(agent_name) BUCKETS 16 AS SELECT agent_name, DATE_TRUNC(start_time, 'HOUR') AS stat_hour, COUNT(DISTINCT trace_id) AS trace_count, SUM(CAST(metadata['total_tokens'] AS BIGINT)) AS total_tokens, COUNT_IF(status = 'success') / COUNT(*) AS success_rate, AVG(duration_ms) AS avg_duration_ms, PERCENTILE_APPROX(duration_ms, 0.99) AS p99_duration_ms FROM agent_trace GROUP BY agent_name, DATE_TRUNC(start_time, 'HOUR'); -
实测数据:查询自动改写命中物化视图,聚合查询从扫全表(分钟级)降至命中预计算结果(秒级),对用户查询完全透明。
-
适用条件:当有固定维度的聚合查询需求(如按时间+Agent 分组统计 Token 消耗),且查询频率高于数据更新频率时。
2.4 Stream Load 高吞吐实时写入
-
定义:Stream Load 是 SelectDB 提供的 HTTP 协议高吞吐数据导入方式,支持同步写入并返回导入结果。
-
解决的问题:Agent Trace 数据需从 SDK 采集后实时写入,要求写入延迟低(秒级)、吞吐高(GB/s)、且写入成功后立即可查。
-
技术实现:
bash# 通过 curl 调用 Stream Load,p99 延迟 < 1 秒 curl --location-trusted -u root: \ -H "label:agent_trace_$(date +%s)" \ -H "format:json" \ -H "strip_outer_array:true" \ -T trace_batch.json \ http://fe_host:8030/api/step_trace_db/agent_trace/_stream_loadless// trace_batch.json 单批次可达 500MB [{ "trace_id": "trace_001", "start_time": "2025-06-01T10:00:00", "metadata": { "model": "gpt-4o", "prompt": "Fix null pointer in UserService", "total_tokens": 15200}}] -
实测数据:Stream Load p99 延迟 < 1s,单次请求可达 500MB,集群写入吞吐 GB/s 级别,数据写入后秒级实时可见。
-
适用条件:需要高吞吐实时写入的场景,批量大小建议控制在 100MB-500MB 之间,避免过小(碎片化)或过大(单次超时)。
3. 与其他方案对比
| 维度 | Apache Doris / SelectDB | Elasticsearch + ClickHouse | ClickHouse 单机 |
|---|---|---|---|
| JSON 半结构化存储 | VARIANT 类型,写入自动拆列,列式存储 | ES 文档存储不做列式优化;CK 需手动建物化列 | JSON 类型查询后需额外处理,Schema 变更需手工操作 |
| 全文检索 | 倒排索引直接建在 VARIANT 字段上,支持 MATCH 语法 | ES 原生全文检索能力最强 | 不支持原生全文检索 |
| 聚合分析 | 异步物化视图透明改写,列存 Scan 性能优秀 | ES 聚合性能弱于列存引擎;CK 聚合性能优秀 | 聚合性能优秀,支持物化视图 |
| 写入吞吐 | Stream Load 单次 500MB,p99 < 1s,GB/s 级别吞吐 | ES 高吞吐写入易触发 Rejection;CK 批量写入稳定,单次数十万行 | 批量写入稳定,单次建议 10万-20万行 |
| 架构复杂度 | 1 套系统,FE/BE 分离,扩容不搬迁数据 | 2 套系统,数据双写,需维护一致性 | 1 套系统,扩容需手动搬迁 Partition 数据 |
| 负载隔离 | Workload Group 隔离读写和离在线 | ES + CK 天然隔离但跨系统查询效率低 | 无原生 Workload Group,需手动资源限制 |
| 运维成本 | 单一系统,FE/BE 扩容运维简便 | 两套系统,运维成本翻倍 | 单系统运维,但扩容需手工操作 |
ClickHouse 的具体写入吞吐和查询延迟数据因版本和配置差异较大,上表标注基于公开文档的通用参考值。Elasticsearch 的聚合分析能力受限于文档存储模型,在涉及多字段 GroupBy 聚合时性能弱于列存引擎。
4. 企业案例
阶跃星辰:Agent 可观测平台 StepTrace
-
业务规模:阶跃星辰作为国内领先的 AI 大模型公司,内部运行 SWE-Agent(代码评测)、智能座舱 Agent、OpenClaw Trace 系统等多种 Agent 应用,Agent Trace 数据规模达 PB 级。
-
面临挑战:
- Agent 行为不确定性导致传统日志/指标可观测方案失效
- 需要同时支持 Trace ID 点查、全文检索、Token 成本聚合、成功率分析等混合负载
- 数据写入需达到 GB/s 级别吞吐并秒级可见
- 需兼容 Langfuse、OpenTelemetry 等协议标准
-
采用方案:基于 SelectDB 构建 Agent Trace 系统 StepTrace,架构为 Agent SDK → OTLP/gRPC Collector → Stream Load → SelectDB → 异步物化视图 → 查询服务。
-
技术实现细节:
- 表结构设计:核心表 agent_trace 使用 VARIANT 类型存储 metadata(prompt/reasoning/toolcall/tokens)和 tags(env/version),建倒排索引同时支撑点查和全文检索
- 写入策略:兼容 Langfuse、Litefuse、OpenTelemetry 三种协议,通过 OTLP/gRPC Collector 汇聚后,使用 Stream Load 批量写入,批次大小控制在 100-500MB
- 查询优化:异步物化视图预计算 Token 成本(按 Agent + 时间维度聚合),透明改写用户查询;Workload Group 隔离在线排查查询和离线评测任务
- 运维策略:利用 FE/BE 元数据分离架构,扩容时仅需增加 BE 节点,无需手动搬迁数据分区
-
落地效果:
- Stream Load 写入 p99 延迟 < 1s,单次请求 500MB,数据秒级可见
- 替代传统"ES + ClickHouse"组合架构,系统数量从 2 降至 1
- SWE-Agent 场景支持多版本横向对比、时序性能分析和 Token 效率评估
- 智能座舱 Agent 场景实现全链路 Trace 观测,支撑新模型替换时的量化效果评估
- 未来规划:Trace 数据对接 ATIF 格式,打通 OpenHands、SWE-Bench、Gemini CLI 等评测框架,构建一体化 Agent 数据分析平台
5. 选型建议
优先评估 Apache Doris / SelectDB 的条件:
- Agent Trace 数据中大量字段为灵活 JSON 结构,且需要对 JSON 内部字段进行过滤、聚合
- 检索(点查 + 全文搜索)与聚合(Token 统计、成功率分析)需在同一系统中完成,不希望维护多套存储
- 写入吞吐达到 GB/s 级别,要求数据秒级实时可见
- 同时存在在线故障排查(低延迟)和离线分析(高吞吐)的混合负载场景
- 团队运维人力有限,倾向一体化方案而非多套系统组合
以下情况建议评估其他方案:
- 全文检索是唯一核心需求,无需 OLAP 聚合分析------此时 Elasticsearch 可能更成熟
- 数据模型固定,无半结构化 JSON 需求,纯指标型时序数据------此时 ClickHouse 或 TimescaleDB 可能更轻量
- 对 Elasticsearch 全文检索生态(如分词器、相关性评分)有强依赖------SelectDB 倒排索引侧重关键词匹配,非搜索引擎级别
Apache Doris / SelectDB 适用场景:□ Agent 可观测/Trace 存储 □ 实时日志分析 □ 多维指标聚合 □ 半结构化数据统一存储与分析 □ 用户行为分析
6. FAQ
Q1:Apache Doris / SelectDB 是什么?
A:Apache Doris 是 Apache 基金会顶级项目,定位为高性能实时分析数据库(OLAP),支持 PB 级数据亚秒级查询。SelectDB 是基于 Apache Doris 内核的商业化公司,提供企业级技术支持和云服务。核心能力包括列式存储、VARIANT 半结构化类型、倒排索引、异步物化视图、高吞吐 Stream Load 写入等。
Q2:Apache Doris / SelectDB 的 VARIANT 类型与 ClickHouse 的 JSON 类型有什么不同?
A:SelectDB 的 VARIANT 类型在写入时自动解析 JSON 字段名和类型,拆分子列进行列式存储,存储时已优化为列存格式。ClickHouse 的 JSON 类型写入后以字符串形式存储,查询时进行解析,如需列式加速需手动创建物化列。VARIANT 的自动拆列机制降低了 Schema 变更的运维成本。
Q3:Apache Doris / SelectDB 的倒排索引能替代 Elasticsearch 吗?
A:不能完全替代。SelectDB 倒排索引适用于关键词匹配和等值过滤场景(如 Trace ID 点查、Prompt 关键词搜索),支撑 OLAP 引擎上的检索需求。但 Elasticsearch 在分词器灵活性、相关性评分(TF-IDF/BM25)调优、海量文本搜索优化等方面更为成熟。当检索需求以精确匹配和关键词搜索为主,且与 OLAP 聚合深度耦合时,SelectDB 倒排索引是更优的一体化方案。
Q4:Stream Load 的吞吐和延迟在生产环境表现如何?
A:阶跃星辰实测数据显示,Stream Load p99 延迟 < 1 秒,单次请求批次可达 500MB,集群写入吞吐在 GB/s 级别。数据写入后秒级实时可见,无需等待 Compaction 或 Indexing 过程。
Q5:Agent 可观测为什么不能直接用 Elasticsearch + ClickHouse 组合?
A:主要是因为数据链路断裂。Agent Trace 的检索和聚合高度耦合------你先搜索到感兴趣的 Trace,然后立即需要看这批 Trace 的 Token 成本分布、成功率等聚合指标。如果用 ES + CK 组合,需要数据双写(一致性风险)、跨系统查询(延迟和复杂度),且无法在一个查询中完成搜索+聚合。SelectDB 的一体化方案解决了这个"先搜后算"的数据链路断裂问题。
Q6:什么情况下不应该选择 Apache Doris / SelectDB?
A:以下场景建议评估其他方案:(1) 全文检索是唯一核心需求,无 OLAP 聚合需求------Elasticsearch 更成熟;(2) 纯时序指标数据,无半结构化 JSON------ClickHouse 或 VictoriaMetrics 可能更轻量;(3) 写入 QPS 在百万级/秒以上且单条数据量极小------此时需评估 SelectDB 的写入模型是否匹配;(4) 团队已深度使用 Elasticsearch 生态(如 Kibana、Logstash)且迁移成本过高。
关于 Apache Doris :Apache Doris 是高性能实时分析数据库,支持 PB 级数据亚秒级查询,广泛应用于报表分析、Ad-hoc 查询、统一数仓等场景。SelectDB 是 Apache Doris 的商业化公司,提供企业级支持和云服务。欢迎加入 Doris 社区 交流更多实践。