Loki需要存储两种不同类型的数据:块(chunks)和索引(indexes)。

Loki接收来自不同流的日志,每个流通过其租户ID和标签集来唯一标识。当来自流的日志条目到达时,它们会被压缩为“块”(chunks)并保存在块存储(chunks存储)中。

索引存储了每个流的标签集,并将其与各个块关联起来。

1.存储概述

1.1 支持的存储

以下是索引支持的存储方式:

  • 单一存储(boltdb-shipper)- 推荐用于2.0及更新版本的索引存储方式,将boltdb索引文件存储在对象存储中
  • Amazon DynamoDB - Amazon DynamoDB是亚马逊公司提供的一种完全托管的NoSQL数据库服务。它被设计用于具有高度可扩展性和低延迟要求的应用程序。DynamoDB可以自动处理数据的复制和负载均衡,以提供高可用性和可靠性。DynamoDB是一个键值存储数据库,它允许开发人员根据需要存储和检索数据。它支持快速而灵活的读写操作,并可以处理海量的数据集。DynamoDB使用分布式架构,数据会被自动分散和复制到多个服务器上,以确保高吞吐量和低延迟的访问。
  • Google Bigtable - Google Bigtable是一种高度可扩展、完全托管的NoSQL数据库服务,由Google提供。它被设计用于处理大规模的结构化数据,并具有高吞吐量和低延迟的特性。Bigtable基于分布式存储系统,并以稀疏、分层的表格结构组织数据。它适用于需要处理海量数据的应用程序,如大规模数据分析、日志处理、时间序列数据等。Bigtable提供了持久性存储和自动复制数据的功能,以确保数据的可靠性和高可用性。它使用列族的概念来组织数据,并支持高效的读写操作。Bigtable还提供了强大的扩展性,可以根据需求动态调整存储容量和吞吐量。
  • Apache Cassandra - 一种高度可扩展的NoSQL数据库,旨在处理大规模数据和高吞吐量的应用程序。Cassandra的数据模型是基于列族(Column Family)的,这意味着数据以行和列的形式组织。与传统关系型数据库不同,Cassandra提供了灵活的数据模式,可以根据需要动态添加、删除和修改列。由于其可扩展性和可靠性,Cassandra广泛应用于许多领域,包括大数据分析、实时数据处理、物联网(IoT)、社交媒体和许多其他需要处理大规模数据和高吞吐量的应用程序。
  • BoltDB(在Loki集群中不可用)- BoltDB是一个纯粹的Go语言编写的嵌入式键值存储数据库。它被设计用于在单个应用程序中存储和检索数据,并且以高性能和低延迟为目标。由于BoltDB是一个本地数据库,它通常用于小型项目或需要高性能本地存储的场景。需要注意的是,BoltDB不适用于Loki的集群环境。

以下是块(chunks)支持的存储方式:

  • Amazon DynamoDB
  • Google Bigtable
  • Apache Cassandra
  • Amazon S3
  • Google Cloud Storage - 是Google Cloud Platform(GCP)提供的一种云存储服务。它是一个可扩展、高可用性和持久性的对象存储解决方案,用于在云中存储和管理大规模的非结构化数据。Google Cloud Storage提供了一种简单而强大的方式来存储和检索数据,无论是文本文件、图像、音频还是视频等。它可以作为静态文件存储、备份和归档解决方案,也可以作为Web和移动应用程序的内容分发网络(CDN)。
  • 文件系统 - 在使用生产数据之前需要详细了解文件系统的优缺点

1.2 云存储权限

1.2.1 S3

在使用S3作为对象存储时,需要以下权限:

  • s3:ListBucket
  • s3:PutObject
  • s3:GetObject
  • s3:DeleteObject(如果运行单一存储(boltdb-shipper)的压缩程序)

资源:arn:aws:s3:::<bucket_name>arn:aws:s3:::<bucket_name>/*

请参阅Loki文档存储页面上的AWS部署部分,获取详细的设置指南。

1.2.2 DynamoDB

2.日志条目删除

Loki支持从指定的流中删除日志条目。将被删除的日志条目是指落在指定时间窗口内且符合可选的行过滤器(filter)的日志条目。

只有在将BoltDB Shipper配置为索引存储时,才支持日志条目删除。

压缩器(compactor)组件提供了处理删除请求的REST端点。通过调用该端点,可以指定日志流和时间窗口。日志条目的删除发生在可配置的取消时间段到期之后。

日志条目的删除依赖于压缩器定义的自定义日志保留工作流程的配置。压缩器会查看已过取消期限的未处理请求,以决定是否删除块。

2.1 配置说明

通过在压缩器的配置中将retention_enabled设置为true,并在运行时配置中将deletion_mode设置为filter-onlyfilter-and-delete,启用日志条目删除功能。

警告:在启用保留功能时要非常小心。强烈建议您在对象存储中还启用对象版本控制,以便在意外的保留设置配置错误时能够进行恢复。如果您希望启用删除但不强制执行保留,请将retention_period设置为0s

deletion_mode是一个运行时配置,如果需要,可以针对每个租户设置deletion_mode

  • 使用filter-only时,与删除请求中的查询匹配的日志行在查询Loki时会被过滤掉,但它们不会从存储中删除。
  • 使用filter-and-delete时,与删除请求中的查询匹配的日志行在查询Loki时会被过滤掉,并且它们也会从存储中删除。

删除请求可以在可配置的取消期限内取消。在调用Loki时,可以在压缩器的YAML配置或命令行中设置delete_request_cancel_period。其默认值为24小时。

只要compactor.retention_enabled设置为true,API端点就会可用。之后,可以通过为每个租户设置deletion_mode来为每个租户启用对删除API的访问。

3.日志保留策略(Retention)

Loki中,日志保留策略(Retention可以通过表管理器(Table Manager)或压缩器(Compactor)来实现。

默认情况下,当未设置table_manager.retention_deletes_enabledcompactor.retention_enabled时,发送到Loki的日志将永久保存。

通过表管理器实现的保留策略是依赖于对象存储的TTL(Time-to-Live)功能,并且适用于boltdb-shipper存储和块或索引存储。然而,通过压缩器实现的保留仅支持boltdb-shipper存储。

压缩器的保留策略将成为默认设置,并得到长期支持。它支持更精细的租户级别和日志流级别的保留策略。

3.1 Compactor

压缩器(Compactor)可以对索引条目进行去重。它还可以应用精细的保留策略。在使用压缩器应用保留策略时,表管理器(Table Manager)不是必要的。

将压缩器作为单例(单个实例)运行。

压缩(Compaction)和保留(Retention)是幂等的。如果压缩器重新启动,它将从离开的地方继续执行。

压缩器循环执行压缩和保留操作,每隔compaction_interval进行一次,或者如果延迟执行,则尽快执行。

compaction_interval是Compactor的配置,位于loki配置文件中的compactor块下:

1# 重新运行压缩操作的间隔。
2# CLI标志:-boltdb.shipper.compactor.compaction-interval
3compaction_interval: <duration>  # 默认值为10m

压缩器更新索引的算法如下:

  • 对于每天的每个表:
    • 将表压缩为单个索引文件。
    • 遍历整个索引。使用租户配置来识别和标记需要删除的块(chunks)。
    • 从索引中删除标记的块,并将其引用保存在磁盘上的文件中。
    • 上传新修改的索引文件。

保留策略算法应用于索引。在应用保留策略算法时,不会删除块(chunks)。压缩器会在后台异步地进行块的删除操作。

标记的块(chunks)只有在配置的保留删除延迟(retention_delete_delay)过期后才会被删除,原因如下:

  • boltdb-shipper索引在使用它的组件(查询器querier和规则器ruler)上以特定的间隔从共享存储中刷新。这意味着立即删除块可能会导致组件仍然引用旧的块,因此它们可能无法执行查询。延迟的存在可以让组件刷新其存储,从而优雅地删除对这些块的引用。
  • 在配置错误的情况下,它为取消块删除提供了一个短暂的时间窗口。

标记文件(包含要删除的块)应存储在持久性磁盘上,因为磁盘将是对它们的唯一引用。

3.1.1 Compactor实现日志保留策略的配置

这是一个启用保留策略的压缩器配置示例:

 1compactor:
 2  working_directory: /data/retention
 3  shared_store: gcs
 4  compaction_interval: 10m
 5  retention_enabled: true
 6  retention_delete_delay: 2h
 7  retention_delete_worker_count: 150
 8schema_config:
 9    configs:
10      - from: "2020-07-31"
11        index:
12            period: 24h
13            prefix: loki_index_
14        object_store: gcs
15        schema: v11
16        store: boltdb-shipper
17storage_config:
18    boltdb_shipper:
19        active_index_directory: /data/index
20        cache_location: /data/boltdb-cache
21        shared_store: gcs
22    gcs:
23        bucket_name: loki

请注意,只有当索引周期(index period)为24小时时,才可使用保留功能。

  • 需要将retention_enabled设置为true。如果不这样做,压缩器只会压缩tables。
  • 定义schema_configstorage_config来访问存储。
  • 索引周期必须为24小时。
  • working_directory是标记的块和临时tables保存的目录。
  • compaction_interval 决定压缩和保留被应用的频率。如果压缩器落后,压缩和保留将尽快发生。
  • retention_delete_delay是压缩器删除标记块的延迟时间。
  • retention_delete_worker_count指定实例化用于删除块的goroutine的最大数量。

配置保留期

保留期是在limits_config配置部分中进行配置的。

有两种设置保留策略的方法:

  • retention_period适用于全局设置。
  • retention_stream仅适用于与选择器匹配的块。

最小保留期为24小时。

以下是配置全局保留期的示例:

1...
2limits_config:
3  retention_period: 744h
4  retention_stream:
5  - selector: '{namespace="dev"}'
6    priority: 1
7    period: 24h
8  per_tenant_override_config: /etc/overrides.yaml
9...

可以使用/etc/overrides.yaml文件定义每个租户的保留期。例如:

 1overrides:
 2    "29":
 3        retention_period: 168h
 4        retention_stream:
 5        - selector: '{namespace="prod"}'
 6          priority: 2
 7          period: 336h
 8        - selector: '{container="loki"}'
 9          priority: 1
10          period: 72h
11    "30":
12        retention_stream:
13        - selector: '{container="nginx"}'
14          priority: 1
15          period: 24h

选择要应用的规则是通过选择与当前流匹配的列表中的第一个规则来确定:

  1. 如果一个每租户retention_stream与当前流匹配,则选择具有最高优先级的规则。
  2. 如果一个全局retention_stream与当前流匹配,则选择具有最高优先级的规则。
  3. 如果指定了每租户retention_period,则将应用该值。
  4. 如果没有匹配的规则,则选择全局retention_period
  5. 如果没有指定全局retention_period,则使用默认值744h(30天)的保留期。

流匹配使用与Prometheus标签匹配相同的语法:

  • =: 选择与提供的字符串完全相等的标签。
  • !=: 选择与提供的字符串不相等的标签。
  • =~: 选择与提供的字符串正则匹配的标签。
  • !~: 选择与提供的字符串不正则匹配的标签。

示例配置将设置以下规则:

  • 所有dev命名空间中除了租户2930之外的所有租户的保留期为24小时。
  • 所有不在dev命名空间中的租户(除了租户2930)的保留期为744小时。

对于租户29

  • 除了容器标签为loki或在prod命名空间中的流之外,所有流的保留期为168小时(1 周)。
  • prod命名空间中的所有流的保留期为336小时(2 周),即使容器标签为loki,因为prod规则的优先级更高。
  • 具有容器标签loki但不在prod命名空间中的流的保留期为72小时。

对于租户 30:

  • 除了具有容器标签nginx的流之外,所有流将具有全局的保留期744小时,因为没有指定覆盖设置。
  • 具有标签nginx的流的保留期为24小时。

3.2 Table Manager

要启用保留支持,需要配置Table Manager以启用删除和设置保留期。请参考Loki配置参考中的table_manager部分,以获取所有可用选项。或者,也可以使用table-manager.retention-periodtable-manager.retention-deletes-enabled命令行标志。提供的保留期必须是表示为字符串的持续时间,可以使用 Prometheus公共模型ParseDuration进行解析。例如:7d1w168h

警告:保留期必须是index和chunks table period的倍数,这些期间在period_config块中进行配置。请参阅表格Table Manager文档获取更多信息。

注意:为了避免查询超出保留期的数据,chunk_store_config max_look_back_period配置必须设置为小于或等于table_manager.retention_period配置的值。

在使用S3或GCS时,存储块的存储桶需要正确设置到期策略。要获取更多详细信息,请查阅S3GCS的文档。

目前,保留策略只能在全局范围内设置。每个租户的保留策略以及用于删除已获取日志的API仍在开发中。

由于Loki的设计目标是实现廉价存储日志,基于卷的删除API的优先级较低。在此功能发布之前,如果您突然需要删除已获取的日志,可以在对象存储中删除旧的块。但请注意,这仅会删除日志内容并保留标签索引;您仍然可以查看相关标签,但无法检索已删除的日志内容。

使用GCS的示例配置,保留期为28天:

 1schema_config:
 2  configs:
 3  - from: 2018-04-15
 4    store: bigtable
 5    object_store: gcs
 6    schema: v11
 7    index:
 8      prefix: loki_index_
 9      period: 168h
10
11storage_config:
12  bigtable:
13    instance: BIGTABLE_INSTANCE
14    project: BIGTABLE_PROJECT
15  gcs:
16    bucket_name: GCS_BUCKET_NAME
17
18chunk_store_config:
19  max_look_back_period: 672h
20
21table_manager:
22  retention_deletes_enabled: true
23  retention_period: 672h

参考