菜单
开源

基数

数据属性的基数是指该属性可以拥有的不同值的数量。例如,数据库中的布尔列只能取 truefalse 值,因此基数为 2。

高基数是指数据库中可以有很多可能值的列或行。对于在线购物系统,像 userIdshoppingCartIdorderId 这样的字段通常是高基数列,可以拥有数十万个不同的值。

高基数属性的其他示例包括以下内容:

  • 时间戳
  • IP 地址
  • Kubernetes Pod 名称
  • 用户 ID
  • 客户 ID
  • Trace ID

在 Loki 中,当我们谈论 基数 时,我们指的是标签和值的组合以及它们创建的日志流数量。在 Loki 中,使用的标签越少越好。这就是 Loki 默认限制为 15 个索引标签的原因。

高基数可能由使用具有大范围可能值的标签引起,**或**组合许多标签引起,即使它们的取值范围有限且较小,例如组合 status_codeaction。一组典型的状态码(200、404、500)和操作(GET、POST、PUT、PATCH、DELETE)将创建 15 个唯一流。但是,如果只添加一个像 endpoint(/cart、/products、/customers)这样的标签,就会将唯一流的数量增加到 45 个,是原来的三倍。

要查看系列标签和基数的示例,请参阅 LogCLI 教程。如您所见,即使在您开始组合标签用于特定的日志流之前,单个标签的基数也可能相当高,这会进一步增加基数。

要查看当前标签的基数,您可以使用 logcli

logcli series '{}' --since=1h --analyze-labels

高基数在 Loki 中的影响

高基数会导致 Loki 创建大量流,特别是当标签具有许多唯一值时,以及当这些值是短暂存在(例如,活跃几秒或几分钟)时。这会导致 Loki 构建一个巨大的索引,并将数千个微小的数据块刷新到对象存储。

Loki 的设计和构建并非为了支持高基数标签值。事实上,它的设计恰恰相反。它旨在处理非常长期的流和非常低的标签基数。在 Loki 中,使用的标签越少越好。

高基数可能导致显著的性能下降。

避免高基数

为避免 Loki 中的高基数,您应该:

  • 避免使用无界值的标签,例如时间戳、trace ID、order ID。
  • 首选描述日志消息来源或上下文的静态标签,例如应用程序、命名空间、环境。
  • 不要分配“动态”标签(即日志消息本身中的值),除非它是低基数或一个长期存在的值。
  • 使用结构化元数据存储频繁搜索的高基数元数据字段,例如客户 ID 或交易 ID,同时不影响 Loki 的索引。

注意

结构化元数据 是 Loki 和 Cloud Logs 中的一项功能,允许客户存储对于日志行来说基数过高的元数据,而无需将该信息嵌入日志行本身。
对于不容易嵌入到日志行中,但基数过高而无法有效用作标签的元数据来说,它是一个极好的存储位置。使用 Bloom 过滤器进行查询加速 也利用了结构化元数据。