
科大讯飞星迹日志中心经历了从 Elasticsearch 到 Loki,再到 Apache Doris 的可观测性存储分析底座升级,支持可观测三大支柱 Log Trace Metrics 的存储与分析,有效解决 Elasticsearch 成本高、Loki 查询慢的问题。Doris 能够在降低成本的同时提高查询效率,实现了查询性能提升 10 倍、存储空间缩减至 Elasticsearch 1/6。此外,Doris 提供的半结构化数据类型 VARIANT 能高效存储可扩展的 JSON 数据,具备很高的灵活性,且其性能媲美普通宽表。
更多相关文章:#Elasticsearch 到 Apache Doris 案例、#日志场景案例
讯飞星迹作为科大讯飞推出的一款全领域场景的可观测产品,旨在满足基础设施、应用及业务上的监测需求,提供一体化的解决方案。以实际场景为例,当服务上线后,需要对中间件和操作系统的 CPU 、内存等资源进行监控,这些指标能够实时反映系统的健康状态。当问题出现后,可以通过日志数据分析其来源,再利用日志链路分析迅速定位问题的位置。

写的多:
高吞吐、低延迟:日志数据增长迅猛,每天可产生 10 ~ 100 TB 数据、日志条数可达几十亿~几百亿条。同时,日志写入并发量也在持续提升,可达到 50 万 TPS,对日志平台的写入吞吐要求极高。
低成本存储:日志数据总量庞大且保存时间较长,需实现高压缩率的存储方案,支持冷热存储和数据归档,避免占用过多存储资源。
查的快:
秒级查询响应:即使面对海量数据,也需要提供稳定高性能的查询能力,以应对故障排查等对响应速度有较高要求的使用场景,分钟级的数据延迟往往无法满足业务要求。
易于使用:
运维简单:要求架构极简易用,支持快速部署、扩容及运维,并能够与其他子系统串联打通,支持多云场景。
使用简单:支持工程师熟悉的接口和语言比如 SQL,以及可视化的、便捷的管理界面。
可观测性存储底座架构演进

资源占用高:无论是写入还是查询,CPU 占用率普遍较高。这主要是由于高吞吐量写入时,分词操作和 Segment 合并会导致显著的 CPU 消耗。
存储成本高:受限于 Elasticsearch 的压缩率,海量日志数据存储成本相对较高。 稳定性差:在进行跨天查询或处理大数据量时,系统经常出现 OOM(内存溢出)问题,且故障恢复时间较长。此外,index 加载耗时较长,可能导致写入被拒绝。
02 Loki + Cassandra

CPU 使用率高、查询分析效率低:Loki 的架构与 Prometheus 原理相似。当以标签进行数据查询时,系统先根据 index 定位到 chunk,然后加载 chunk 中的数据,解压后逐条暴力搜索。这种处理方式显然会导致较高的 CPU 使用率,并且经常出现 OOM(内存溢出)问题,查询和分析的效率也并不理想。
创建标签的数量受限:当标签基数较少时,查询速度尚可。而当标签数量过多或搜索条件复杂时,无法对基数较大的值进行查询加速,而日志场景中的字段基数通常较高。例如,在查询每个链路的 trace ID 时,每条 trace ID 数据几乎都是唯一的,这种高基数的数据不适合使用标签来处理。
03 基于 Apache Doris 的可观测性存储底座

写的多:可支撑日均 600 亿条、10TB 的写入流量。与 Elasticsearch 相比,存储成本不及其 1/6,相同的数据 Elasticsearch 存储需要 1T,而依赖于 Doris 的列式存储和 ZSTD 压缩,仅需要 170 G。
查的快:查询效率提升至少 10 倍,特别是在聚合分析、短语模糊匹配及 TOPN 命中前缀索引等场景下,性能提升效果显著。Doris 即使在没有命中索引的情况下,也可以在分钟内返回结果。与 Elasticsearch 频繁出现的 OOM 相比,效率提升尤为突出。 易于使用:Doris manager 可便捷管理所有 Doris 集群。科大讯飞在交付私有化项目时,通常需要管理至少数十套集群,而 Doris Manager 使这一过程变得便捷轻松。此外,系统还提供 Grafana 和自研的 Web 查询界面,方便用户进行日志检索和分析。
新架构的应用及优化经验
01 Log Trace Metric 选择合适的数据模型

CREATE TABLE config (
app_code varchar(50) NOT NULL COMMENT '业务唯一编码',
app_name varchar(50) NOT NULL ,
table_name varchar(200) NOT NULL COMMENT '数据表名',
create_time datetime NOT NULL COMMENT '创建时间',
update_time datetime NOT NULL COMMENT '更新时间'
)
ENGINE = OLAP
UNIQUE KEY(app_code)
DISTRIBUTED BY HASH(app_code) BUCKETS AUTO
PROPERTIES (
"enable_unique_key_merge_on_write" = "true",
"light_schema_change" = "true");
CREATE TABLE log_record
(
`log_date` DATETIMEV2(3) COMMENT "日志打印时间",
`source` VARCHAR(100) COMMENT "日志来源",
`level` VARCHAR(10) COMMENT "日志级别",
`host_name` VARCHAR(100) COMMENT "主机名",
`msg` STRING COMMENT "日志内容",
INDEX idx_msg (`msg`) USING INVERTED
)
ENGINE = OLAP
DUPLICATE KEY(`log_date`)
PARTITION BY RANGE (`log_date`)
(
)
DISTRIBUTED BY RANDOM BUCKETS 50
PROPERTIES (
"compaction_policy" = "time_series",
"dynamic_partition.enable" = "true",
"dynamic_partition.time_unit" = "DAY",
"dynamic_partition.create_history_partition" = "true",
"dynamic_partition.start" = "-30",
"dynamic_partition.end" = "7",
"dynamic_partition.prefix" = "p",
"compression"="zstd"
);
CREATE TABLE alarm_agg
(
`id` LARGEINT,
`first_trigger_time` DATETIME MIN COMMENT "第一次触发时间",
`level` TINYINT MAX COMMENT "告警级别",
`msg` STRING REPALCE COMMENT "告警内容",
`num` INT SUM COMMENT "总数量"
)
AGGREGATE KEY(`id`)
DISTRIBUTED BY HASH(`id`) BUCKETS 10;
数据聚合发生的时段分为三个: 每一批次数据导入的 ETL 阶段。每一批次导入的数据内部进行聚合,聚合后写入 Doris 集群。
BE 进行数据 Compaction 阶段。BE 会对已导入的不同批次的数据进行进一步的聚合。 数据查询阶段。对于查询涉及到的数据,进行对应的聚合。 聚合模型的局限性: 对 count(*)
查询不友好, Doris 必须扫描所有的 AGGREGATE KEY 列,并且聚合后,才能得到语意正确的结果。当聚合列非常多时,count(*)
查询需要扫描大量的数据。
02 可扩展 JSON 数据使用半结构化数据类型 VARIANT
{
"source":"PC",
"time":1722562556534,
"userId":"d3079d82",
"properties": {
"duration":8979,
"mark":"标识",
"title":"标题",
"url":"/statistic/analysis"
}
}
上述示例展示了一个典型的行为分析日志,其中properties
是 JSON 格式的可扩展字段,存储了运行时长、标题和 URL 等子字段。然而,不同业务线在properties
字段中的具体数据可能有所差异。例如,某业务线可能仅依据其标识来记录数据,如果该业务线涉及启动参数或启动状态,字段数量可能会减少,仅包含用户信息,如用户 ID。根据不同的事件类型,整个properties
字段的内容也会有所不同。因此,在日志场景中,经常需要存储一些动态字段,如 Kubernetes 下的标签以及采集指标数据的标签等。
1)基于导入手动指定json_path
静态 Schema 方案:
properties这种可扩展的 JSON 字段,最初在使用 Doris 导入时,手动配置
json_path参数以映射到表的字段。为提供用户体验,我们还在页面上添加了可视化配置映射功能。该方案的优缺点都很明显。
优点:能够确保存储和查询的效率,所有字段都映射到 Doris 表中的普通列。相较于 JSON 文本数据,列式存储在存储和查询方面的优势非常明显。
缺点:不够灵活,无法动态扩展字段。每次修改都需手动调整表结构和映射关系,上下游系统需协同处理,这一过程繁琐且低效,容易出错。
2)基于 Doris Variant 动态 Schema 方案:
CREATE TABLE log_variant (
time BIGINT,
source STRING,
userId STRING,
properties VARIANT
)
SELECT * FROM log_variant
WHERE time BETWEEN t1 AND t2
AND source = 'PC'
AND properties['duration'] > 100000;
properties['duration']) 即可,不会产生额外的数据读取和解析的开销(比如
mark,
title,
url等字段)。这种方案的性能与静态列相当,而相较于 JSON 字符串,性能提升存在数量级的差异。
在使用 VARIANT 类型的过程中,也遇到一些局限性但已找到解决方法:
早期版本 VARIANT 不能应用在聚合模型中, 升级到 2.1.3 以上的版本可以解决。 当 VARIANT 与 Group Commit 一起使用时,会出现过早反压影响写入性能的问题,升级到 2.1.5 以上的版本可以解决。 在 VARIANT 列上创建索引时,会对所有子列同时创建索引。如果子列数量过多,可能导致索引数量过多,从而影响写入性能。此外,同一 VARIANT 列的分词属性是一致的。例如,如果某列包含十个字段,并使用中文分词,那么这十个字段都将应用相同的中文分词规则。 日期、Decimal 等非标准 JSON 类型,会被默认推断成字符串类型,应尽可能从 VARIANT 中提取出来,用静态类型性能更好。
03 建表分区分桶优化

CREATE TABLE log_record (
log_date DATETIMEV2(3),
level VARCHAR(10),
host VARCHAR(100),
message string,
INDEX idx_host (host) USING INVERTED),
INDEX idx_message (message) USING INVERTED PROPERTIES("parser" = "chinese", "support_phrase" = "true")
)
ENGINE = OLAP
DUPLICATE KEY(log_date)
PARTITION BY RANGE (log_date)()
DISTRIBUTED BY RANDOM BUCKETS 50
PROPERTIES (
"compaction_policy" = "time_series",
"compression"="zstd“,
"dynamic_partition.enable" = "true",
"dynamic_partition.time_unit" = "DAY",
"dynamic_partition.create_history_partition" = "true",
"dynamic_partition.start" = "-30",
"dynamic_partition.end" = “3",
"dynamic_partition.prefix" = "p"
);
SELECT * FROM log_record
WHERE log_date >= '2024-08-10 00:00:00.000' AND log_date <= '2024-08-11 00:00:00.000'
ORDER BY log_date DESC LIMIT 0, 20

04 写入优化
FE 参数优化:尽量让每个节点的 Tablet 均匀
enable_round_robin_create_tablet = truetablet_rebalancer_type = partition BE 参数优化:增加写入 Buffer Size 的大小,write_buffer_size = 1073741824 Stream Load 参数优化:设置单 Tablet 写入,load_to_single_tablet=true
我们会在写入前攒批,压力分摊到写入模块:

size_based及
time_series,其中
time_series适用于时序场景。
size的 Compaction 策略。
收益总结
写的多:可支撑日均 10TB,600 亿条日志的写入流量。与 Elasticsearch 相比,存储成本不到其 1/6。
查的快:查询效率提升至少 10 倍,特别是在聚合分析、短语模糊匹配及 TOPN 命中前缀索引等场景下,性能提升效果显著。 易于使用:Doris Manager 使得管理多个集群变得简单,同时提供 Grafana 和自研的 Web 查询界面,方便用户进行日志检索和分析。
未来展望
基于讯飞星火大模型的 AIOps:持续探索智能运维的最佳实践,包括日志异常监测、故障预测和故障诊断等。 用户行为分析:目前采用手动创建物化视图,未来探索如何利用 Doris 的物化视图能力实现自动物化。 存算分离:计划基于 3.0 版本的存算分离,实现中心化的读写分离以及租户的物理隔离。
更多标杆企业信赖

作为基于 Apache Doris 的商业化公司,飞轮科技秉承着 “开源技术创新”和“实时数仓服务”双轮驱动的战略,在投入资源大力参与 Apache Doris 社区研发和推广的同时,基于 Apache Doris 内核打造了聚焦于企业大数据实时分析需求的企业级产品 SelectDB ,面向新一代需求打造世界领先的实时分析能力。自 2022 年成立以来,获得 IDG 资本、红杉中国、襄禾资本等顶级 VC 的近 10 亿元融资,创下了近年来开源基础软件领域的新纪录。
往期推荐




