一个结账服务的 p95 延迟为 582ms,而 SLO 目标为 350ms。在 Kibana Discover 中,一条 KQL 查询就找到了它。要确定哪个团队拥有该服务,需要一条 ES|QL 查询,该查询使用 LOOKUP JOIN 将指标文档与一个小型服务目录索引进行关联。下面,调查按顺序进行。数据视图缩小了范围,筛选药丸使其保持可见——当其他人需要重建你的搜索过程时,这一点比听起来更重要。KQL 完成了大部分工作。Lucene 查询语法处理了需要正则表达式的那个场景,而一旦筛选不再能回答问题,ES|QL 就接手了。
要跟随操作,你需要:
LOOKUP JOIN 在 Elasticsearch 9.1 中正式可用,在 9.0 中为技术预览,因此最后一部分请使用 9.1 或更高版本。LOOKUP JOIN,均在免费基础许可证下工作。示例从一个常见的运维问题开始:
为什么生产环境中结账延迟增加了,以及哪个团队拥有该服务?
指标索引包含三个区域中四个服务的 15 分钟服务测量数据。在调查窗口期间,一个名为 checkout-api 的服务在 us-central1 区域出现更高的 p95 延迟。目标是从所有指标中定位到解释该问题的一小部分文档。
本演练按以下步骤进行:
LOOKUP JOIN 将服务目录数据丰富到指标中。该演练搜索名为 o11y-labs-discover-service-metrics 的指标索引。使用关键字字段表示服务维度,使用数值字段表示测量值来创建它:
PUT o11y-labs-discover-service-metrics
{
"mappings": {
"properties": {
"@timestamp": {
"type": "date"
},
"service": {
"properties": {
"name": {
"type": "keyword"
},
"environment": {
"type": "keyword"
},
"version": {
"type": "keyword"
}
}
},
"cloud": {
"properties": {
"region": {
"type": "keyword"
}
}
},
"host": {
"properties": {
"name": {
"type": "keyword"
}
}
},
"metrics": {
"properties": {
"latency": {
"properties": {
"p95_ms": {
"type": "float"
}
}
},
"cpu": {
"properties": {
"pct": {
"type": "float"
}
}
},
"error": {
"properties": {
"rate": {
"type": "float"
}
}
}
}
}
}
}
}每个文档是一个区域中一个服务的 15 分钟测量值:
POST o11y-labs-discover-service-metrics/_bulk
{"index": {}}
{"@timestamp": "2026-06-30T16:15:00.000Z", "service": {"name": "checkout-api", "environment": "production", "version": "2026.06.30-1"}, "cloud": {"region": "us-central1"}, "host": {"name": "checkout-api-us-central1-01"}, "metrics": {"latency": {"p95_ms": 582.6}, "cpu": {"pct": 0.81}, "error": {"rate": 0.041}}}
{"index": {}}
{"@timestamp": "2026-06-30T16:15:00.000Z", "service": {"name": "payments-api", "environment": "production", "version": "2026.06.29-7"}, "cloud": {"region": "us-central1"}, "host": {"name": "payments-api-us-central1-01"}, "metrics": {"latency": {"p95_ms": 231.4}, "cpu": {"pct": 0.31}, "error": {"rate": 0.008}}}要重现截图,请为每个服务、区域和 15 分钟间隔索引一个文档:
checkout-api、checkout-worker、payments-api、inventory-apius-central1、us-east4、europe-west1staging 文档(checkout-api 和 payments-api,均在 us-central1)具体数值并不重要,只要 us-central1 区域的 checkout-api 在 UTC 时间 15:45 至 18:45 之间报告 metrics.latency.p95_ms 超过 500,而在其他所有地方都远低于 500 ms 即可。
无需手动索引所有内容,你可以运行配套笔记本,它会生成完整的 336 个文档数据集,创建两个索引,并验证最后的 ES|QL 查询。
ES|QL 部分还会使用第二个包含四个文档的查找索引,用于服务目录数据。我们将在到达那里时创建它。
数据视图是 Discover 中的第一个过滤器。它决定搜索哪些 Elasticsearch 索引、哪个时间字段驱动直方图,以及左侧字段列表中哪些字段可用。

对于本演练,Discover 数据视图指向:
o11y-labs-discover-service-metrics时间字段是 @timestamp。这很重要,因为时间选择器会在你添加查询、筛选药丸或选中字段之前限制文档。
尽可能使用窄的数据视图。例如,当你已经知道问题与指标相关时,针对服务指标的数据视图比宽泛的 logs-*,metrics-* 数据视图更容易在 Discover 中浏览。
选择数据视图后,添加支持调查的字段:
service.nameservice.environmentcloud.regionmetrics.latency.p95_msmetrics.cpu.pctmetrics.error.rate当你想要一个可见、可编辑的约束列表时,UI 筛选器非常有用。当你正在从文档表中探索字段,并希望 Discover 为你编写字段语法时,它们也很有帮助。
在文档表中,使用字段操作(悬停在值上时出现的 +/- 图标)来包含或排除它。例如:
service.environment: productionNOT cloud.region: us-east4service.version: 2026.06.29-7 (已禁用)
这三个筛选器展示了主要的筛选控件:
固定筛选器对于跨越应用边界的调查很有用。例如,在从 Discover 移动到仪表板、Lens 或其他视图之前,你可以固定 service.environment: production。禁用筛选器对于测试某个假设而不删除引导你到达那里的上下文很有用。
关键习惯是保持筛选器可读。如果查询包含很长的搜索表达式和许多隐藏的假设,另一位工程师必须重建你的思路。筛选药丸使主要的范围决策变得可见。
KQL(Kibana 查询语言)是 Discover 搜索的一个良好默认选项。它支持字段名称、精确值、范围、通配符和布尔逻辑,形式可读。
对于结账延迟示例,这条 KQL 查询将视图缩小到一个服务、一个区域和高 p95 延迟:

service.name : "checkout-api" and cloud.region : "us-central1" and metrics.latency.p95_ms >= 500从左到右阅读:
service.name : "checkout-api" 保留一个服务。cloud.region : "us-central1" 保留一个云区域。metrics.latency.p95_ms >= 500 保留延迟样本在 500 ms 及以上。你可以在 KQL 中添加环境:
service.environment : "production" and service.name : "checkout-api" and cloud.region : "us-central1" and metrics.latency.p95_ms >= 500或者,你可以将 service.environment: production 保持为 UI 筛选器。两种方法都有效。对于共享调查,我们更倾向于将稳定范围(如环境和服务)作为筛选药丸,将活跃假设(如延迟阈值)放在搜索栏中。
KQL 也适用于组合多个字段:
service.environment : "production" and(service.name : "checkout-api" or service.name : "payments-api") andmetrics.error.rate > 0.02当用户面向的流程跨越多个服务时,这很有用。你可以在不切换数据视图或先创建仪表板的情况下比较一小群服务。
Lucene 查询语法是 Kibana 中支持正则表达式的选项。KQL 不支持,因此当搜索栏中需要正则表达式时,打开搜索栏右侧的查询菜单,将语言切换为 Lucene。

例如,这条 Lucene 查询搜索名称以 checkout- 开头且 p95 延迟高于 500 ms 的生产服务:
service.name:/checkout-.*/ AND service.environment:production AND metrics.latency.p95_ms:>500Lucene 语法更紧凑,但也更容易误读。当它能提供你无法用 KQL 清晰表达的内容(例如字段上的正则表达式模式)时,再使用它。对于日常的字段、值和范围筛选,KQL 通常更便于队友审查。
经典 Discover 模式适用于搜索、筛选、检查字段和查看原始文档。当问题需要在结果有用之前进行转换时,Discover 中的 ES|QL 更好。使用 Discover 工具栏中的 Query in ES|QL 按钮来切换模式。

在此示例中,原始指标告诉我们 checkout-api 延迟很高。但它们没有告诉我们谁拥有该服务,或者该服务预期达到什么延迟目标。这些数据存于一个小的服务目录查找索引中。
PUT o11y-labs-service-catalog-lookup
{
"settings": {
"index.mode": "lookup"
},
"mappings": {
"properties": {
"service": {
"properties": {
"name": {
"type": "keyword"
}
}
},
"owner": {
"properties": {
"team": {
"type": "keyword"
}
}
},
"slo": {
"properties": {
"latency_target_ms": {
"type": "long"
}
}
},
"runbook": {
"properties": {
"url": {
"type": "keyword"
}
}
}
}
}
}一个目录文档可以将所有权和 SLO 目标附加到服务上:
POST o11y-labs-service-catalog-lookup/_doc/checkout-api
{
"service": {
"name": "checkout-api"
},
"owner": {
"team": "checkout-platform"
},
"slo": {
"latency_target_ms": 350
},
"runbook": {
"url": "https://runbooks.example.com/checkout-api/latency"
}
}现在,Discover 可以运行一条 ES|QL 查询,使用 LOOKUP JOIN 将指标文档与目录元数据关联起来。请注意,此命令需要 Elasticsearch 9.1 或更高版本,查找索引必须使用 index.mode: lookup 创建,并且连接字段(此处为 service.name)必须在查找索引中映射为 keyword。
FROM o11y-labs-discover-service-metrics| WHERE @timestamp >= "2026-06-30T15:00:00.000Z" AND @timestamp <= "2026-06-30T18:45:00.000Z"| WHERE service.environment == "production"| LOOKUP JOIN o11y-labs-service-catalog-lookup ON service.name| WHERE owner.team == "checkout-platform" AND metrics.latency.p95_ms > slo.latency_target_ms| KEEP @timestamp, service.name, cloud.region, metrics.latency.p95_ms, slo.latency_target_ms, owner.team| SORT @timestamp DESC这是经典模式无法覆盖的部分。经典 Discover 可以筛选指标文档,但 ES|QL 可以在显示结果之前,用另一个索引的数据丰富这些行。

结果表回答了一个比原始搜索更具操作性的问题。它在一个视图中显示了受影响的服务、区域、延迟值、目标和所属团队。
此模式不仅适用于所有权。你可以为服务层级、部署环、升级渠道、业务能力或 runbook URL 维护小型查找索引。然后在调查时,将这些上下文加入到指标搜索中。
最有用的工作流程不是一种搜索语言适用于所有情况。而是从宽范围到具体证据的渐进过程。
用例 | Discover 功能 | 为何有用 |
|---|---|---|
限制可搜索的数据 | 数据视图和时间选择器 | 在查询运行前移除不相关的索引和旧文档 |
保持范围可见 | UI 筛选器 | 使包含、排除、禁用和固定条件易于审查 |
搜索精确字段和范围 | KQL | 使常见的指标搜索可读 |
使用正则表达式匹配字段值 | Lucene 模式 | 当搜索需要时添加正则表达式语法 |
丰富或重构结果 | ESQL 模式 | 添加关联、投影、排序和转换 |
对于真实的调查,从包含所需数据的最小数据视图开始。为稳定范围添加筛选药丸。使用 KQL 进行活跃搜索。仅当正则表达式语法值得额外复杂性时切换到 Lucene。当问题需要丰富、聚合或重构时,转向 ES|QL。
当字段名称携带足够的上下文时,指标搜索效果最好。上面的示例尽可能使用了 Elastic Common Schema 风格的字段:
service.name 表示被监控的服务。service.environment 表示生产、暂存或开发。cloud.region 表示部署区域。host.name 用于主机级别的下钻。metrics.* 下。你不需要使用这个确切模式来使用 Discover,但可预测的字段名称使搜索栏和筛选药丸更容易使用。它们也使已保存的搜索和截图在交接时更容易理解。
对于服务目录数据,保持查找索引小而稳定。像服务所有者、层级、SLO 目标和 runbook URL 这样的字段变化频率低于原始指标。这使得它们成为分析期间使用 LOOKUP JOIN 的好候选。
将 Discover 用作下钻路径,而不仅仅是文档表。在本演练中,我们:
LOOKUP JOIN 将指标文档与查找索引中的所有权和 SLO 数据丰富起来。要尝试在自己的集群上运行完整流程,请执行配套笔记本,它会创建两个索引以及每个示例中使用的故障数据。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。