菜单
文档breadcrumb arrow Grafana Lokibreadcrumb arrow 入门breadcrumb arrow 标签breadcrumb arrow 标签最佳实践
开源

标签最佳实践

Grafana Loki 正在积极开发中,我们不断努力改进性能。但以下是一些当前关于标签的最佳实践,它们将为您带来最佳的 Loki 使用体验。

静态标签很好

将标签用于区域、集群、服务器、应用、命名空间和环境等。对于给定的系统/应用,它们是固定的,并且具有有限的值。使用静态标签可以更容易地按逻辑查询您的日志(例如,显示给定应用和特定环境的所有日志,或显示特定主机上所有应用的所有日志)。

谨慎使用动态标签

过多的标签值组合会导致过多的日志流。这在 Loki 中会导致较大的索引和存储中较小的块,这反过来实际上会降低性能。

为了避免这些问题,除非您知道需要它,否则不要添加标签!使用过滤表达式(|= "text", |~ "regex", ...)来暴力匹配这些日志。这有效——而且速度很快。

如果您经常在查询时从日志行中解析出标签,并且该标签的基数很高,并且提取该标签的性能开销很大;请考虑在客户端提取该标签,并将其作为结构化元数据附加到日志行中。

早期,我们使用 Promtail 管线为 level 动态设置了一个标签。这在我们看来很直观,因为我们经常只想显示 level="error" 的日志;然而,我们现在正在重新评估这种做法,因为事实证明,对于我们的许多应用,查询 {app="loki"} |= "level=error"{app="loki",level="error"} 一样快。

这可能看起来令人惊讶,但如果应用的日志量中等到较低,该标签会导致一个应用的日志被分割成多达五个流,这意味着存储了 5 倍的块。加载块会带来额外的开销。现在想象一下,如果查询是 {app="loki",level!="debug"}。这需要加载的块将比 {app="loki"} != "level=debug" 多得

上面我们提到除非您需要标签,否则不要添加,那么什么时候您会需要标签呢?下面有一个关于chunk_target_size的部分。如果您将其设置为 1MB(这是合理的),Loki 将尝试在压缩大小达到 1MB 时切块,这大约相当于 5MB 左右的未压缩日志(根据压缩情况,可能多达 10MB)。如果您的日志量足够大,可以在小于 max_chunk_age 的时间内写入 5MB,或者在该时间内写入许多块,您可能需要考虑使用动态标签将其分割成单独的流。

您需要避免的是将日志文件分割成流,从而导致块在未满时因为流空闲或达到最大年龄而被刷新。截至Loki 1.4.0,有一个指标可以帮助您了解块被刷新的原因 sum by (reason) (rate(loki_ingester_chunks_flushed_total{cluster="dev"}[1m]))

块在刷新时不必完全填满并非至关重要,但这将改进操作的许多方面。因此,我们目前的指导是尽可能避免使用动态标签,而是优先使用过滤表达式。例如,不要添加 level 动态标签,而是使用 |= "level=debug"

以下是使用动态标签的一些最佳实践:

  • 确保标签基数较低,理想情况下限制在数十个值以内。
  • 使用具有长寿命值的标签,例如 HTTP 路径的初始部分:/load, /save, /update
    • 不要将像 trace ID 或 order ID 这样的临时值提取为标签;这些值应该是静态的,而不是动态的。
  • 只添加用户会频繁用于查询的标签。
    • 如果没人实际使用这些标签,请不要增加索引大小并分散您的日志流。这将降低性能。

标签值必须始终是有限的

如果您动态设置标签,切勿使用可能具有无限或无限值范围的标签。这总是会导致 Loki 出现大问题。

尝试将值范围限制在尽可能小的集合内。关于 Loki 能处理多少值,我们没有完美的指导,但动态标签的值范围请考虑在个位数,或者可能在几十个以内。对于静态标签来说,这不太重要。例如,如果您的环境中有 1000 台主机,拥有一个带有 1000 个值的主机标签完全没问题。

作为一般规则,您应该尝试将 Loki 中的任何单个租户保持在少于10万个活动流,并在 24 小时内少于一百万个流。这些值是针对每天发送超过10 TB的超大型租户而言。如果您的租户大小是其十分之一,则标签数量应至少减少十倍。

注意客户端应用的动态标签

Loki 有多种客户端选项:Grafana AlloyPromtail(也支持 systemd journal 摄取和基于 TCP 的 syslog 摄取)、FluentdFluent BitDocker 插件等等。

每个客户端都提供了配置应用于创建日志流的标签的方式。但要注意可能应用的动态标签。使用 Loki 的 series API 可以了解您的日志流是什么样子,并查看是否有方法可以减少流和基数。可以通过Series API 查询系列信息,或者您可以使用 logcli

在 Loki 1.6.0 及更高版本中,logcli series 命令添加了 --analyze-labels 标志,专用于调试高基数标签。

Total Streams:  25017
Unique Labels:  8

Label Name  Unique Values  Found In Streams
requestId   24653          24979
logStream   1194           25016
logGroup    140            25016
accountId   13             25016
logger      1              25017
source      1              25016
transport   1              25017
format      1              25017

在此示例中,您可以看到 requestId 标签在发现它的 24979 个流中,有 24653 个不同的值,这很糟糕!!

这是不应作为标签的完美示例,应将 requestId 从标签中移除,转而使用过滤表达式来查询特定 requestId 的日志。例如,如果在日志行中找到 requestId 作为键值对,您可以编写如下查询:{logGroup="group1"} |= "requestId=32422355"