当面对千万级日志时,如何用 Loki 索引并保留 30 天冷热分层?

解读

面试官想验证三件事:

  1. 你是否理解 Loki 只索引标签、不索引内容 的核心设计;
  2. 能否在 千万级 QPS/日增 TB 级 场景下,用 冷热分层 把 30 天总存储成本压到 对象存储低价层
  3. 是否具备 可观测性+FinOps 视角,让方案在 国内公有云(阿里云 OSS、腾讯云 COS、华为云 OBS) 上可落地、可回滚、可审计。

知识点

  • Loki 存储架构:Ingester → WAL → Chunk → Index Gateway → Object Store
  • boltdb-shipper + 24h 本地索引 机制,索引文件同样上传对象存储
  • compactor 单例模式 负责全局去重、压缩、Retention Mark
  • table_manager 与 retention_period 只能“删”,不能“搬”;冷热需靠 对象存储生命周期规则
  • 国内云厂商对象存储 均支持 Standard → IA → Archive 三级生命周期,最小粒度
  • Helm 参数ingester.max_transfer_retries=0 避免节点漂移丢数据;compactor.retention_enabled=true 必须显式开启
  • 可观测性:通过 loki_compactor_* 指标监控压缩耗时;通过 loki_ingester_memory_chunks 避免 OOM
  • 合规《网络安全法》 要求日志留痕 ≥6 个月,因此 30 天“热”后仍需 冷存 150 天,不能物理删除

答案

  1. 标签设计
    只把 {cluster, namespace, app, pod, level} 五个维度做成标签,error、msg 等高频文本字段强制转为内容,确保 每流 50 MB/天 以下,避免 cardinality 爆炸

  2. 存储桶规划
    国内统一用 阿里云 OSS 举例:

    • 创建 loki-hot-oss 桶,Standard 存储,绑定 3 天生命周期后转 IA;
    • 创建 loki-cold-oss 桶,Archive 存储,30 天生命周期后自动转入。
  3. Loki 配置(helm values 片段,可直接写进 values-production.yaml

    loki:
      schema_config:
        configs:
          - from: "2024-01-01"
            store: boltdb-shipper
            object_store: aliyun-oss
            schema: v13
            index:
              prefix: index_
              period: 24h
            chunks:
              prefix: chunks_
              period: 24h
      storage_config:
        aliyun-oss:
          bucketnames: loki-hot-oss
          endpoint: oss-cn-shanghai-internal.aliyuncs.com
          access_key_id: ${ALIBABA_CLOUD_ACCESS_KEY_ID}
          secret_access_key: ${ALIBABA_CLOUD_ACCESS_KEY_SECRET}
        boltdb_shipper:
          active_index_directory: /var/loki/index
          shared_store: aliyun-oss
          cache_location: /var/loki/cache
          resync_interval: 5m
      compactor:
        working_directory: /var/loki/compactor
        shared_store: aliyun-oss
        compaction_interval: 10m
        retention_enabled: true
        retention_delete_delay: 2h
        retention_delete_worker_count: 150
        compactor_ring:
          kvstore:
            store: memberlist
    

    关键:

    • period=24h 保证每天一个物理目录,方便 OSS 生命周期匹配前缀;
    • retention_enabled=true 只标记删除,不立即清理,给 冷存留出 150 天合规窗口
  4. 冷热分层脚本(一次性 Ansible 任务,可回滚)

    #!/bin/bash
    # 运行节点:运维跳板机,已配置 OSSCMD
    ossutil mb oss://loki-cold-oss --storage-class Archive
    ossutil lifecycle --method put oss://loki-hot-oss lifecycle_hot.json
    ossutil lifecycle --method put oss://loki-cold-oss lifecycle_cold.json
    

    lifecycle_hot.json 核心规则:

    • 前缀 index_、chunks_ 文件 3 天后转 IA
    • 30 天后转 Archive复制到 loki-cold-oss
    • 180 天后删除(满足 6 个月合规)。
  5. 查询加速

    • Index Gateway 组件独立 2 副本,16C32G,挂载 本地 NVMe 只读缓存 200 GB,命中率 ≥85%
    • Query Frontend 开启 max_retries=3query_split_by_interval=24h,把 30 天范围查询拆成 并行 30 段,降低 冷存取回延迟 对 RT 的影响。
  6. 成本效果

    • 原始日志 1 TB/天,30 天 ≈ 30 TB;
    • Loki 压缩+去重 后实际 8 TB
    • Standard 层 3 天 → IA 27 天 → Archive 150 天,综合存储单价 0.12 → 0.08 → 0.033 元/GB/月总成本下降 72%
    • 查询 P99 延迟 冷存 3.2 s,热存 400 ms,满足 内部 SLA ≤5 s
  7. 回滚与灰度

    • Archive 取回延迟 导致告警,5 分钟内 把 lifecycle 规则 30 天改为 7 天 即可回退到 IA;
    • 通过 ArgoCDGitOps,保留 旧 values 版本一键回滚

拓展思考

  • 如果日志量再涨 10 倍,单 Compactor 成为瓶颈,可启用 横向 Compactor(Loki 2.9+),但需 Kubernetes 1.25+ 并打开 ReadWriteMany 卷,国内云厂商需 NAS 或 CPFS 支持,成本翻倍,需要 提前做 PoC
  • 实时风控场景,30 天冷存仍不够快,可引入 Cortex/Thanos 降采样 思想,把 7 天前日志按 1:10 采样 后转 ParquetOSS-HDFS 桶,再用 Serverless Spark离线 ML 特征回填,实现 “温层” 补充。
  • 合规升级《数据出境安全评估办法》 要求 日志不出境,若公司后续在 海外有节点,需把 冷存桶开启同城冗余 + 访问跟踪,并配置 RAM 策略 禁止 跨区域复制,否则 审计直接不合格