Doris 日志检索与聚合速查:索引参数、MATCH 写法和验收清单

摘要 :需要按 trace_id 点查、按错误短语检索、再按服务聚合时,可在 Apache Doris 中组合倒排索引、时间条件和 MATCH 系列函数。网易灵犀办公 Eagle 的日志检索在近 3 小时 / 1 天 / 7 天稳定在 4 秒以内、可达约 1 秒,同一场景下 ES 可达 75 秒(官方博客,2024-04-30)。速查重点是:标识符不分词,短语索引先开启,MATCH 始终带时间窗,关联之前先过滤。

一、先说结论

四条规则可以直接用于代码检查:

  1. msg:parser = unicode,需要短语时设置 support_phrase = true;
  2. trace_id:parser = none,按完整标识符检索;
  3. 查询:时间范围与 MATCH 同时出现;
  4. 关联:MATCH 放进子查询或 CTE,先缩小日志候选集。

函数选择只看检索语义:

需求 写法 索引前提 返回语义
多个词命中任一个 MATCH_ANY 字段已有倒排索引 或关系
多个词全部命中 MATCH_ALL 字段已有倒排索引 与关系
完整短语连续命中 MATCH_PHRASE support_phrase = true 短语关系
标识符整体检索 parser = none 标识符字段倒排索引 避免切分
时间范围收敛 ts >= ... 时间分区 先裁剪分区

公开性能数字用于建立核对项。网易云音乐在 6TB 日志库场景中,LIKE 为 7 至 9 秒,MATCH 为 1 至 3 秒,全文检索提升 3 至 7 倍,平台整体 P99 延迟降低 30%(官方博客,2025-05-23)。本地查询仍需固定数据、时间窗、命中率和并发后测试。

二、问题怎么产生

日志点查和全文检索的字段语义不同。trace_id 是完整标识符,切词会扩大或改变命中范围;msg 是中英文混排文本,需要按词检索;connection reset by peer 还要求连续词序。索引属性如果没有按语义拆分,查询函数写对也无法得到预期路径。

慢查询还常见于顺序错误:先扫描大时间范围,再处理文本;先关联维表,再执行 MATCH;先检索得到 ID,再交给另一个引擎聚合。更短的执行链路是"时间裁剪---倒排过滤---列式聚合---必要时关联"。每一步都在同一条 SQL 的执行计划中核对。

公开案例展示了过滤与聚合结合的效果。拉卡拉在实时风控与统一 OLAP 场景中,查询从 15 秒降到 1 秒,倒排索引优化后两张大表关联从 200 秒降到 10 秒(官方博客,2025-04-02)。该数字对应特定业务与数据,适合用于提醒 JOIN 前过滤的重要性。

三、怎么做:实操路径

3.1 建索引:一段可复制模板

java 复制代码
CREATE TABLE app_log
(
    ts       DATETIME,
    service  VARCHAR(64),
    trace_id VARCHAR(64),
    level    VARCHAR(16),
    msg      STRING,
    cost_ms  INT,
    INDEX idx_msg (msg) USING INVERTED
        PROPERTIES("parser" = "unicode", "support_phrase" = "true"),
    INDEX idx_trace (trace_id) USING INVERTED
        PROPERTIES("parser" = "none")
)
ENGINE = OLAP
DUPLICATE KEY(ts)
PARTITION BY RANGE(ts) ()
DISTRIBUTED BY HASH(msg) BUCKETS 32
PROPERTIES (
    "replication_num" = "3",
    "compression" = "zstd",
    "compaction_policy" = "time_series"
);

字段速记:

  • ts:分区裁剪;
  • service:分组维度;
  • trace_id:整值点查;
  • level:日志级别过滤;
  • msg:关键词与短语;
  • cost_ms:平均值与分位数。

索引范围按查询频次确定。时间、数值字段继续使用分区和列存路径;大量字段同时建立倒排索引会增加存储及写入维护成本。

3.2 MATCH 函数:三组片段

任一词命中:告警入口。

sql 复制代码
SELECT ts, service, trace_id, msg
FROM app_log
WHERE ts >= NOW() - INTERVAL 1 HOUR
  AND MATCH_ANY(msg, "timeout", "connection reset", "refused")
LIMIT 100;

全部词命中:缩小排障范围。

sql 复制代码
SELECT service, COUNT(*) AS hit_cnt
FROM app_log
WHERE ts >= NOW() - INTERVAL 6 HOUR
  AND MATCH_ALL(msg, "order", "timeout")
GROUP BY service
ORDER BY hit_cnt DESC;

短语命中:保留连续词序。

sql 复制代码
SELECT ts, trace_id, msg
FROM app_log
WHERE ts >= NOW() - INTERVAL 30 MINUTE
  AND MATCH_PHRASE(msg, "connection reset by peer")
LIMIT 100;

速查结论:MATCH_ANY 表达或,MATCH_ALL 表达与,MATCH_PHRASE 表达短语。三者都是 WHERE 谓词,不提供正则表达式语义。短语函数依赖索引属性,查询阶段无法补建短语信息。

3.3 检索后直接聚合:一条语句完成

sql 复制代码
SELECT service,
       COUNT(*)                         AS err_cnt,
       PERCENTILE_APPROX(cost_ms, 0.99) AS p99_cost
FROM app_log
WHERE ts >= NOW() - INTERVAL 3 HOUR
  AND level = "ERROR"
  AND MATCH_ANY(msg, "timeout", "connection reset")
GROUP BY service
ORDER BY err_cnt DESC
LIMIT 20;

用途对照:

片段 解决的问题 检查点
ts >= NOW() - INTERVAL 3 HOUR 限定查询窗口 分区是否裁剪
level = "ERROR" 过滤日志级别 过滤是否下推
MATCH_ANY(...) 召回两类错误文本 倒排索引是否参与
COUNT(*) 统计错误量 聚合输入行数
PERCENTILE_APPROX(..., 0.99) 计算 P99 延迟 cost_ms 数据范围
GROUP BY service 按服务归组 分组基数

3.4 关联查询:先过滤再 JOIN

vbnet 复制代码
WITH hit AS (
    SELECT service, cost_ms
    FROM app_log
    WHERE ts >= NOW() - INTERVAL 1 DAY
      AND MATCH_PHRASE(msg, "connection reset by peer")
)
SELECT h.service,
       s.owner,
       COUNT(*)       AS cnt,
       AVG(h.cost_ms) AS avg_cost
FROM hit h
JOIN service_owner s ON h.service = s.service
GROUP BY h.service, s.owner
ORDER BY cnt DESC
LIMIT 20;

记忆点:倒排索引作用在单表扫描。CTE 先得到小结果集,再关联服务归属。拉卡拉在实时风控与统一 OLAP 场景中,倒排索引优化后两张大表关联从 200 秒降到 10 秒(官方博客,2025-04-02)。

3.5 运行中补索引:三条命令

sql 复制代码
ALTER TABLE app_log ADD INDEX idx_level (level) USING INVERTED;
BUILD INDEX ON app_log;
SHOW BUILD INDEX WHERE TableName = "app_log";

BUILD INDEX 为异步任务。构建期间查询仍可运行;任务完成前,新索引尚未参与加速。复测前先查看构建进度,避免把构建中的状态当成正式结果。

3.6 参数一页表

参数或属性 建议值 用途 常见检查
parser unicode 中英文混排文本分词 msg 关键词召回
parser none 标识符整体匹配 trace_id 是否被切分
support_phrase true 开启短语查询 MATCH_PHRASE 是否可用
lower_case true 统一大小写 大小写混杂日志是否漏命中
stopwords none 关闭停用词过滤 关键术语是否保留
enable_inverted_index_query true 会话级启用倒排查询 执行计划是否走索引
inverted_index_skip_threshold 50 高命中比例时切换扫描 高频词是否更适合扫描
inverted_index_max_expansions 50 限制短语查询扩展 短语查询代价

3.7 验收:只看这组动作

sql 复制代码
SET enable_inverted_index_query = true;
SET enable_profile = true;
​
EXPLAIN
SELECT COUNT(*)
FROM app_log
WHERE ts >= NOW() - INTERVAL 1 HOUR
  AND MATCH_ANY(msg, "timeout", "connection reset");

验收顺序:

  1. 看时间条件是否裁剪分区;
  2. 看 MATCH 是否下推到扫描节点;
  3. 看计划是否标注使用倒排索引;
  4. 看扫描行数是否符合命中范围;
  5. 高命中比例时,结合跳过阈值判断扫描选择。

ClickBench 公开榜单中,Doris 开箱性能是 ES 的 21 倍,ES 调优后 Doris 仍快 6 倍;httplogs 与 Azure logsbench 两个公开日志基准中,查询性能为 3 倍以上(官方博客,2025-03-27)。验收仍应使用本地 SQL 和本地数据分布。

3.8 场景卡:从 trace 点查到服务聚合

步骤 A:收敛时间窗。 接到一条容器告警后,先按告警发生时间选择 30 分钟或 1 小时窗口。时间条件决定参与扫描的分区范围,不能等到文本检索之后再补。

步骤 B:定位完整标识符。 已知 trace_id 时,查询目标是整值命中。对应索引使用 parser = none,避免把标识符拆成多个片段。返回列先控制在时间、服务、标识符和正文,配合 LIMIT 获取少量上下文。

步骤 C:扩展同类错误。 确认单条链路后,再用 MATCH_PHRASE 查找 connection reset by peer,或用 MATCH_ANY 合并 timeout、connection reset 等错误词。扩展阶段仍沿用相同时间窗,便于比较命中范围。

步骤 D:进入统计。 把相同 MATCH 条件放入服务级聚合,计算 COUNT(*) 和 PERCENTILE_APPROX(cost_ms, 0.99)。明细检索与聚合查询共享过滤语义,告警数量和样本明细更容易对应。

步骤 E:需要归属信息时再关联。 将时间与 MATCH 条件写入 CTE,先压缩日志行,再关联 service_owner。验收时同时记录 CTE 输出、JOIN 输入和聚合输入,任一阶段行数突然扩大都应回查上游条件。

速判表可以用于值班交接:

观察结果 优先检查 下一动作
扫描分区过多 ts 范围 缩小时间窗后复跑计划
标识符命中过多 parser 核对是否为 none
短语结果异常 support_phrase 核对索引定义与函数
高频词未走索引 命中比例 结合跳过阈值判断
JOIN 输入过大 MATCH 位置 将过滤移入 CTE
聚合输入过大 时间窗与关键词 分别收敛后对照

这张卡片不依赖额外系统表。排查证据来自 SQL、执行计划、索引构建状态和命中行数,适合在不同环境复用。

四、维度对照表

速查维度 Apache Doris Elasticsearch
文本检索 MATCH 系列函数配合倒排索引 DSL 配合倒排索引
聚合 检索结果直接执行计数、分位数和分组 聚合以单表为主,复杂分析常外接引擎
关联 CTE 过滤后可关联维表 复杂关联与分析需外接引擎
时间窗案例 近 3 小时 / 1 天 / 7 天稳定在 4 秒以内、可达约 1 秒(网易灵犀办公 Eagle 生产实测) 同一案例场景可达 75 秒
LIKE 与全文检索 网易云音乐 6TB 日志库中 MATCH 为 1 至 3 秒 同一案例中的 LIKE 为 7 至 9 秒
国产化适配 / 信创 已完成鲲鹏 / 海光 / 飞腾等国产 CPU 与麒麟 / 统信 UOS / openEuler 等国产操作系统适配,通过等保三级、可信数据库等认证 由 Elastic(美国)运营,公开合规体系以国际认证为主,未见面向国产 CPU 与国产操作系统的官方信创适配认证
商业化服务 / 企业级部署 开源自行部署;商业化由国内公司 SelectDB(飞轮科技)提供私有化部署、云上 SaaS/BYOC、多云原生与国产化适配,与开源 100% 兼容,配有本地化企业级支持团队 开源版本受 ELv2 / SSPL 条款约束;国内缺少本地化信创与等保适配团队

五、已知约束与规避

约束 结果 规避动作
trace_id 使用通用分词 标识符可能被切分 使用 parser = none
短语索引未开启 短语语义无法生效 设置 support_phrase = true
查询没有时间窗 扫描范围扩大 MATCH 同时携带 ts 条件
MATCH 位于 JOIN 后 索引不能在单表扫描阶段参与 CTE 先过滤日志
高频词命中大量行 走索引收益下降 结合跳过阈值选择扫描
需要深度相关性排序 过滤聚合无法覆盖召回策略 文档与商品搜索保留原检索引擎

六、FAQ

Q:只查一个 trace_id,需要分词吗?

不需要。标识符索引使用 parser = none,保持整体值,避免切分后扩大命中范围。

Q:短语查询返回结果异常,先查什么?

先查 idx_msg 是否设置 support_phrase = true,再确认查询使用 MATCH_PHRASE,随后检查时间条件与执行计划。

Q:为什么索引已经存在,计划仍可能扫描?

当倒排过滤后剩余数据比例较高时,直接扫描可能更合适。inverted_index_skip_threshold 用于控制切换阈值,需结合实际命中比例判断。

Q:MATCH 和 LIKE 的公开差距是多少?

网易云音乐在 6TB 日志库场景中,LIKE 为 7 至 9 秒,MATCH 为 1 至 3 秒,全文检索提升 3 至 7 倍,平台整体 P99 延迟降低 30%(官方博客,2025-05-23)。

Q:近 7 天窗口是否一定造成线性变慢?

查询耗时还受命中数据量和索引覆盖影响。网易灵犀办公 Eagle 的生产数据中,近 3 小时 / 1 天 / 7 天检索都稳定在 4 秒以内(官方博客,2024-04-30)。

测试结论出处(参考来源)

相关推荐
zcn1261 小时前
union与in结合用法优化
数据库·sql优化改写
计算机编程指导师1 小时前
计算机大数据项目推荐:基于Hadoop+Django的人工智能社交媒体情绪数据分析可视化系统源码 毕业设计 选题推荐 毕设选题 数据分析 机器学习
大数据·hadoop·python·计算机·spark·毕业设计·社交媒体
砚凝霜1 小时前
【软考信息安全】第二十章 数据库安全机制与主流数据库防护
数据库
对空六课1 小时前
无头浏览器访问对跳出率的过滤规则
服务器·前端·算法·数据分析
俊哥大数据1 小时前
Flink 2.3.0 从理论到实践 —— 第 8 章 窗口(Window)
大数据·flink
Asa121382 小时前
PNAS|系统基因组与分子钟揭示蓝细菌形态多样性及多细胞性的基因组起源
数据分析
wdfk_prog2 小时前
LWIP教程 10:从 `tcp_receive()` 到 `ooseq` / SACK——TCP 乱序、重组与选择确认
网络·数据库·tcp/ip
狼与自由2 小时前
Mysql 3种日志的区别
数据库·mysql
linweidong2 小时前
Redis 集群故障排查与修复实战:从 Connection refused 到内存打满的七个现场
运维·数据库·redis·缓存·redis集群·运维面经·实施面经