
Grafana Loki 存储管理完全指南Chunk 与索引架构、TSDB 单存储与对象存储选型【免费下载链接】lokiLike Prometheus, but for logs.项目地址: https://gitcode.com/GitHub_Trending/lok/loki本篇指南以 Grafana Loki 官方运维文档 docs/sources/operations/storage/_index.md 为骨架系统讲解 Loki 的两类核心数据chunks 与 indexes如何组织与落盘、三类数据类型的区别、受支持与推荐的对象存储后端、云存储所需的最小权限清单并结合仓库源码深入剖析 chunk 二进制磁盘格式、TSDB 单存储索引、schema 演进机制与 retention 清理策略。读完本文你将掌握 Loki 存储层的完整模型能够为自己的部署正确选择并配置对象存储、设计 schema 迁移计划并读懂 chunk 文件的字节级结构。Loki 的存储模型chunks、indexes 与 bloom blocksGrafana Loki 的存储设计与其他日志系统如直接全文索引日志内容的 ELK有本质区别Loki 只索引日志的元数据标签而日志正文本身被压缩成 chunk 存入对象存储。正如 configure/storage.md 所述这种小索引 高压缩 chunk的设计显著简化了运维并降低了存储成本。Loki 需要持久化两类数据Chunks数据块日志正文按流压缩后的数据块。Loki 接收的日志被组织为独立的流stream每个流由其tenant ID租户 ID和一组标签唯一标识。当流的日志条目到达后会被压缩成 chunk 并写入 chunk 存储。Indexes索引索引保存每个流的标签集合并将标签链接到对应的 chunk。查询时 Loki 先查索引定位相关 chunk再读取 chunk 内容。当启用Accelerated Search加速搜索实验特性时还会引入第三种数据类型bloom blocks布隆过滤块用于在大规模部署中加速日志内容检索。索引与 chunk 的配置入口分别对应仓库中的storage_config与schema_config详见下文。Store Types支持的索引存储与 chunk 存储推荐的索引存储Single Store TSDB从 Loki 2.8 开始TSDB 索引存储成为官方推荐的索引方案。它将 TSDB 格式的索引文件直接存放在对象存储中与 chunk 同处一桶因此只需一个对象存储即可同时容纳索引与数据这被称为Single Store单存储。相关详细说明见 tsdb 运维文档。TSDB 索引深受 Prometheus TSDB 子项目启发相比此前的 boltdb-shipper 更高效、更快、扩展性更好。推荐用于生产的 chunk 存储以下托管对象存储均可作为生产级 chunk 存储同时用于 Single Store TSDB 模式下的索引存储Amazon Simple Storage ServiceS3Google Cloud StorageGCSMicrosoft Azure Blob StorageIBM Cloud Object StorageCOSBaidu Object StorageBOSAlibaba Object Storage ServiceOSS可用但通常不建议用于生产的存储Filesystem本地文件系统最易上手详见 filesystem 存储文档 中的利弊分析S3 API 兼容存储如 MinIO适合本地开发与私有化部署配置上直接复用 S3 参数。Cloud Storage Permissions云存储最小权限清单S3AWS使用 S3 作为对象存储时需要以下权限s3:ListBuckets3:PutObjects3:GetObject资源Resource范围arn:aws:s3:::bucket_name arn:aws:s3:::bucket_name/*若通过 IAM 角色进行跨账户访问还需要iam:GetRoleiam:PassRole资源范围arn:aws:iam::aws_account_id:role/role_name仓库中 configure/storage.md 给出了完整的 IAM 策略 JSON 示例含s3:DeleteObject并提供了基于 Terraform 的 S3 桶与 IAM 角色自动化搭建步骤适用于已预置 EKS 集群的场景依次执行terraform init、导出AWS_PROFILE与AWS_REGION、通过aws eks describe-cluster获取 OIDC issuer最后terraform -var region... -var cluster_name... -var oidc_id... apply桶名默认loki-data可通过bucket_name变量修改。IBM Cloud Object StorageCOS使用 IBM COS 时需要授予 IAMWriter角色。注意 COS 不支持 Thanos 版对象存储客户端见下文必须将use_thanos_objstore设为false才能使用。Chunk Formatchunk 的二进制磁盘结构本部分对应原文档的Chunk Format小节并结合源码 pkg/chunkenc/memchunk.go 展开。chunk 在磁盘上是一个高度紧凑的二进制结构依次包含Header头部、Blocks数据块、Metas元数据段、Structured Metadata结构化元数据段四大部分最后是Footer尾部。Header头部----------------------------------- | Magic Number (uint32, 4 bytes) | ----------------------------------- | Version (1 byte) | ----------------------------------- | Encoding (1 byte) | -----------------------------------Magic Number4 字节魔数用于快速识别文件类型。源码中定义为var magicNumber uint32(0x12EE56A)见 memchunk.go读取时若魔数不匹配会直接报错。Version1 字节格式版本。源码定义了ChunkFormatV1到ChunkFormatV4四个版本见 memchunk.go各版本对应不同的内部块head block组织方式V1/V2 使用有序块V3 使用无序块V4 开始支持带结构化元数据的无序块。Encoding1 字节压缩编码标识对应pkg/compression中支持的编码器如 gzip、snappy 等。Blocks数据块------------------------------------------------ | block 1 (n bytes) | checksum (uint32, 4 bytes) | ------------------------------------------------ | block 2 (n bytes) | checksum (uint32, 4 bytes) | ------------------------------------------------ | ... | ------------------------------------------------ | block N (n bytes) | checksum (uint32, 4 bytes) | ------------------------------------------------每个 block 之后紧跟一个 4 字节 CRC32 校验和用于检测数据损坏。源码中使用 Castagnoli 多项式的 CRC32 表crc32.MakeTable(crc32.Castagnoli)见 memchunk.go并以blocksPerChunk 10作为每块 chunk 的默认块数常量。Metas元数据段------------------------------------------------------------------------------------------------------------------------ | #blocks (uvarint) | ------------------------------------------------------------------------------------------------------------------- | #entries (uvarint) | minTs (uvarint) | maxTs (uvarint) | offset (uvarint) | len (uvarint) | uncompressedSize (uvarint) | ------------------------------------------------------------------------------------------------------------------- | ... | ------------------------------------------------------------------------------------------------------------------------ | checksum (uint32, 4 bytes) | ------------------------------------------------------------------------------------------------------------------------元数据段以 uvarint 编码的块数量#blocks开头随后为每个 block 重复一行元信息条目数#entries、最小时间戳minTs、最大时间戳maxTs、块在文件中的偏移offset、压缩后长度len、解压后大小uncompressedSize。整段结尾同样带一个 4 字节校验和。这些元信息使得 Loki 在查询时可以基于时间范围直接跳过不相关的块实现高效的定点读取。Structured Metadata结构化元数据段--------------------------------- | #labels (uvarint) | -------------------------------- | len (uvarint) | value (n bytes) | -------------------------------- | ... | -------------------------------- | checksum (uint32, 4 bytes) | ---------------------------------该段以 uvarint 的标签数量#labels开头随后是len长度加value原始字节交替编码的标签列表段尾带校验和。结构化元数据是 ChunkFormatV4 及之后版本支持的能力用于携带标签之外的键值对信息。Footer尾部------------------------------------------------- | len (uint64, 8 bytes) | offset (uint64, 8 bytes) | // offset to Structured Metadata ------------------------------------------------- | len (uint64, 8 bytes) | offset (uint64, 8 bytes) | // offset to Metas -------------------------------------------------Footer 由两对 8 字节的len offset组成分别指向Structured Metadata 段的偏移与Metas 段的偏移。这一设计使读取端可以只读 Footer 便获知元数据段位置实现随机访问而无需顺序扫描整个 chunk 文件。配置实战Single Store TSDB 对象存储本地开发的最小配置TSDB Filesystem仓库自带的 cmd/loki/loki-local-config.yaml 是一份可直接运行的本地单机示例其核心存储相关配置如下common: instance_addr: 127.0.0.1 path_prefix: /tmp/loki storage: filesystem: chunks_directory: /tmp/loki/chunks rules_directory: /tmp/loki/rules replication_factor: 1 ring: kvstore: store: inmemory schema_config: configs: - from: 2020-10-24 store: tsdb object_store: filesystem schema: v13 index: prefix: index_ period: 24h要点common.storage.filesystem指定 chunk 与 rule 文件的落盘目录schema_config声明从2020-10-24起使用tsdb索引 filesystem对象存储 v13schema索引前缀index_、索引周期24h。TSDB 单存储的生产配置骨架在 tsdb 运维文档 的基础上一个从 boltdb-shipper 迁移到 TSDB 的config.yaml骨架如下schema_config: configs: # 旧 boltdb-shipper schema仅供参考迁移后可移除 - from: 2023-01-03 # 过去的日期 index: period: 24h prefix: index_ object_store: gcs schema: v12 store: boltdb-shipper # 新 TSDB schema - from: 2023-01-05 # 未来的日期 index: period: 24h prefix: index_ object_store: gcs schema: v13 store: tsdb storage_config: tsdb_shipper: active_index_directory: /data/tsdb-index cache_location: /data/tsdb-cache index_gateway_client: # 微服务模式下独立部署 index-gateway 时使用 server_address: dns:///index-gateway.namespace.svc.cluster.local:9095 query_scheduler: # TSDB 会产生更多但更小的查询适当调大待处理队列 max_outstanding_requests_per_tenant: 32768 querier: # 每个 querier 进程的并行 worker 数TSDB 下推荐约 16 max_concurrent: 16TSDB 相关的租户级限制tsdb_max_query_parallelism默认128与旧max_query_parallelism并存专门作用于 TSDB 查询的并行度便于在索引类型切换期间共存。可在limits_config全局设置也可在 per-tenant overrides 中覆盖。tsdb_max_bytes_per_shard默认600MBTSDB动态查询分片的目标分片大小。与旧索引的静态分片不同TSDB 依据查询将处理的数据量动态分片并在索引中额外记录每个 chunk 的大小KB与行数供查询前端规划。查询所需处理的数据超过该目标时Loki 会将分片数翻倍使每个分片实际处理约 300–600 MB 数据即目标值的一半到全部。tsdb_sharding_strategy默认power_of_two查询规划时的分片策略可选的bounded策略需在滚动升级前确认集群所有组件支持。tsdb_precompute_chunks默认false置为true时在查询规划阶段一次性计算 chunk 引用减少查询执行期的索引调用次数但内存占用更高仅在tsdb_sharding_strategy: bounded下生效。无需索引缓存TSDB 格式紧凑高效Loki 当前不对 TSDB 使用索引缓存。若从旧索引迁移建议在存量数据全部超出 retention 或max_query_lookback之前保留原有索引缓存之后可移除。Schema Configschema 演进与升级Loki 承诺向后兼容历史上多次内部存储结构演进都通过schema存储模式版本化实现Loki 允许逐步增量升级到新 schema并可透明地跨 schema 查询因此升级过程无服务中断。从 v11 迁移到 v13 的配置示例以下示例展示了从 BoltDB v11 schema 迁移到 TSDB v13 schema自 2023-07-01 起生效schema_config: configs: - from: 2019-07-01 store: boltdb-shipper object_store: filesystem schema: v11 index: prefix: index_ period: 24h - from: 2023-07-01 store: tsdb object_store: filesystem schema: v13 index: prefix: index_ period: 24h2023-07-01 之前摄入的数据由 BoltDB v11 管理之后切换到 TSDB v13。这些配置在 retention 覆盖期间应保持不可变immutable。升级 schema 的正确姿势升级要点在schema_config.configs中新增一条period_config且from日期必须设置为未来的时间点然后滚动下发配置。这样 table manager 会提前创建好新表避免存量数据被误按新 schema 解析。例如今天是 2023-07-14希望 20 号启用 v13schema_config: configs: - from: 2019-07-14 store: tsdb object_store: filesystem schema: v11 index: prefix: index_ period: 24h - from: 2023-07-20 store: tsdb object_store: filesystem schema: v13 index: prefix: index_ period: 24hLoki 会透明地在两个 schema 之间查询并合并结果使升级对查询完全无感。更多 schema 细节参见 storage/schema 文档。对象存储客户端Thanos 版与遗留客户端的取舍仓库中对象存储客户端的开关位于 pkg/storage/factory.gouse_thanos_objstore的默认值为true即默认使用基于thanos-io/objstore的客户端读取storage_config.object_store或common.storage.object_store下的配置此时遗留客户端配置段如storage_config.aws、storage_config.gcs会被忽略。若需继续使用遗留客户端必须显式设置use_thanos_objstore: false此时启动日志会提示遗留客户端已废弃、建议迁移见 factory.go。需要特别注意的是IBM COS 不受 Thanos 版客户端支持在默认use_thanos_objstore: true下直接配置cos会导致启动失败报错unrecognized object_store type cos。生产部署配置示例S3 / GCS / Azure / MinIO / COS以下配置均以 TSDB v13 schema Single Store 为基准。S3AWSstorage_config: use_thanos_objstore: true object_store: s3: bucket_name: BUCKET_NAME endpoint: s3.REGION.amazonaws.com # 必须指定AWS 使用区域级 endpoint region: REGION # 可在配置中写 access_key_id / secret_access_key # 也可不写改由环境变量 AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY 提供 access_key_id: ACCESS_KEY_ID secret_access_key: SECRET_ACCESS_KEY tsdb_shipper: active_index_directory: /loki/index cache_location: /loki/index_cache cache_ttl: 24h # 查询跨度更长时可调大以提速代价是占用更多磁盘 schema_config: configs: - from: 2020-07-01 store: tsdb object_store: s3 schema: v13 index: prefix: index_ period: 24h要点Thanos 版客户端只支持一个桶若此前使用bucketnames多桶配置需合并为单桶不硬编码凭据时可借助 EC2 实例角色——留空access_key_id与secret_access_key客户端会依次从环境变量、AWS 凭据文件、EC2 实例元数据中寻找凭据。GCSGoogle Cloudstorage_config: use_thanos_objstore: true object_store: gcs: bucket_name: BUCKET_NAME service_account: | { type: service_account, ... } tsdb_shipper: active_index_directory: /loki/index cache_location: /loki/index_cache cache_ttl: 24h schema_config: configs: - from: 2020-07-01 store: tsdb object_store: gcs schema: v13 index: prefix: index_ period: 24hservice_account应填入 GCP Console 的client_credentials.json或服务账号密钥 JSON留空时多数服务会回退到 GCP 的 Application Default CredentialsADC。预定义的storage.objectUser角色或参照其建模的自定义角色包含 Loki 运行所需的足够权限。Azure Blob Storageschema_config: configs: - from: 2020-12-11 index: period: 24h prefix: index_ object_store: azure schema: v13 store: tsdb storage_config: use_thanos_objstore: true object_store: azure: account_name: ACCOUNT_NAME container_name: CONTAINER_NAME # 不填 account_key 时使用 Azure 托管身份 account_key: ACCOUNT_KEY user_assigned_id: USER_ASSIGNED_IDENTITY_ID # 用户分配托管身份 endpoint_suffix: ENDPOINT_SUFFIX # 私有云如 Azure Stack Hub # 若设置了 connection_string则 account_name / endpoint_suffix 不再生效 # 可用 SAS token 或 Azurite 模拟器认证 connection_string: CONNECTION_STRING tsdb_shipper: active_index_directory: /loki/index cache_location: /loki/index_cache cache_ttl: 24hAzure 支持两种认证方式账号名 账号密钥或托管身份以及服务主体Service Principal。Thanos 版客户端没有服务主体的storage_config配置项而是读取 Azure Identity Client 模块的标准环境变量AZURE_TENANT_ID、AZURE_CLIENT_ID、AZURE_CLIENT_SECRET此时须留空account_key但account_name仍必须设置用于拼装存储 URL。MinIOS3 兼容私有化部署MinIO 实现 S3 API直接复用 S3 配置storage_config: use_thanos_objstore: true object_store: s3: bucket_name: BUCKET_NAME endpoint: FQDN:PORT # 使用不带 scheme 的完整域名如 localhost:9000 access_key_id: USERNAME secret_access_key: SECRET insecure: true # MinIO 走 https 时设为 false bucket_lookup_type: path # 相当于 s3forcepathstyle tsdb_shipper: active_index_directory: /loki/index cache_location: /loki/index_cache cache_ttl: 24h schema_config: configs: - from: 2020-07-01 store: tsdb object_store: s3 schema: v13 index: prefix: index_ period: 24hIBM COS需禁用 Thanos 客户端schema_config: configs: - from: 2020-10-01 index: period: 24h prefix: loki_index_ object_store: cos schema: v13 store: tsdb storage_config: use_thanos_objstore: false # COS 不受 Thanos 版客户端支持必须关闭 tsdb_shipper: active_index_directory: /loki/index cache_location: /loki/index_cache cos: bucketnames: BUCKET_1, BUCKET_2 endpoint: ENDPOINT api_key: API_KEY_TO_AUTHENTICATE_WITH_COS region: REGION service_instance_id: COS_SERVICE_INSTANCE_ID auth_endpoint: IAM_ENDPOINT_FOR_AUTHENTICATION使用文件系统存储的利弊对于本地开发、低流量场景与概念验证文件系统存储是上手最快的选择官方文档见 filesystem.md。推荐配置方式common: storage: filesystem: chunks_directory: /tmp/loki/chunks rules_directory: /tmp/loki/rules也可以直接在storage_config下配置storage_config: filesystem: directory: /tmp/loki/Loki 会为每个租户创建独立目录chunk 存放在对应租户目录下单租户模式下所有 chunk 会放入名为fake的合成租户目录。优点无需任何额外软件即可运行 Loki与推荐的 TSDB 索引存储兼容非常适合低流量应用、POC 与本地体验。缺点官方不支持生产环境包括购买支持合同的客户扩展性单个目录能高效容纳的 chunk 文件数有限曾有用户在约 550 万个 chunk 文件时遇到问题。Loki 每个流对应一个 chunk保持活跃流数量较低即可减少文件数同时可调整以下 ingester 参数减少 flush 次数代价是内存占用上升chunk_target_size默认 1.5 MB每个 chunk 的目标压缩大小max_chunk_age默认 2hchunk 在内存中的最大驻留时间可考虑调大chunk_idle_period默认 30m空闲 chunk 的 flush 等待时间可考虑上调以匹配max_chunk_age。持久性完全依赖底层文件系统远不及 S3/GCS 等托管对象存储的内置高持久性高可用除非通过 NFS 等方式共享文件系统往往体验不佳否则无法以集群方式运行保留与删除文件系统存储不会基于磁盘用量或剩余空间删除数据仅按 retention 配置删除磁盘写满需要自行在 Loki 之外处理。retention 删除经由 compactor 执行启用compactor.retention_enabled时还需设置compactor.delete_request_store: filesystem来存储删除请求。Retention 与日志删除使用 TSDB 时Loki 通过Compactor管理 retentioncompactor 识别超出配置保留期的数据删除对应索引条目并异步删除底层 chunk 对象。对于 S3、GCS、Azure Blob 等对象存储后端Loki 不再单纯依赖外部 TTL 或桶生命周期规则这些仍可作为额外保险而是由 Loki 自身在配置后执行 retention 删除。此外Loki 还支持租户级或流级的有目标删除。详见 retention 文档 与 logs-deletion 文档。【免费下载链接】lokiLike Prometheus, but for logs.项目地址: https://gitcode.com/GitHub_Trending/lok/loki创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考