2. Loki 核心架构:组件、读写路径与 Prometheus 异同

Loki 的架构设计围绕“日志即数据流”的理念展开,将日志的接收、存储、查询与压缩解耦为多个独立组件。理解这些组件及其协作路径,是构建可靠日志门禁系统的基础。本章从组件职责、读写路径以及与 Prometheus 的对比三个维度展开。

2.1 核心组件与职责

Loki 采用微服务架构,各组件可独立部署与扩缩容。下表列出了生产环境中最重要的五个组件及其核心职责:

组件 职责 关键特性
Distributor 接收来自 Promtail 或 SDK 的日志流,验证数据合法性,并通过一致性哈希将日志分片转发至对应的 Ingester。 无状态、可水平扩展;负责数据准入与负载均衡。
Ingester 接收 Distributor 推送的日志,在内存中构建索引和块(chunk),并将块异步写入对象存储(如 S3、GCS)。 有状态;负责数据写入与短期缓存;支持故障转移。
Querier 处理 LogQL 查询请求,从 Ingester(热数据)和对象存储(冷数据)中拉取日志块,合并结果后返回。 无状态;负责查询路由与结果聚合。
Compactor 定期合并对象存储中的小索引和块,删除过期数据,优化存储布局。 后台任务;降低存储成本并提升查询效率。
Query Frontend 可选组件,位于 Querier 之前,负责查询拆分、缓存和限流。 提升大规模并发查询性能。
生产建议: 在蓝绿发布门禁场景中,Distributor 和 Querier 应优先配置多副本,避免单点故障导致日志写入或查询中断。

2.2 读写路径详解

Loki 的读写路径是架构的核心。写入路径强调低延迟与高吞吐,读取路径则强调索引效率与数据合并。下图展示了完整的读写流程:

Loki 读写路径架构图 Loki 读写路径架构 Promtail / SDK Distributor Ingester 对象存储 Grafana / API Query Frontend Querier 热数据 冷数据 Compactor 合并/删除 写入路径: Promtail → Distributor → Ingester → 对象存储 读取路径:API → Query Frontend → Querier → Ingester/存储
写入路径(Write Path):
  1. 数据采集: Promtail 或应用 SDK 将日志流推送到 Distributor 的 HTTP/gRPC 端点。
  2. 数据分片: Distributor 根据日志标签(label)计算一致性哈希,将日志转发至对应的 Ingester 副本。
  3. 内存缓冲与持久化: Ingester 将日志追加到内存中的流(stream),按时间或大小阈值切割为块(chunk),异步上传至对象存储。
读取路径(Read Path):
  1. 查询发起: Grafana 或 API 发送 LogQL 查询到 Query Frontend(或直接到 Querier)。
  2. 查询拆分: Query Frontend 将大查询按时间范围拆分为多个子查询,并缓存结果。
  3. 数据合并: Querier 并行查询 Ingester(热数据)和对象存储(冷数据),合并结果后返回。

2.3 与 Prometheus 的异同

Loki 的设计深受 Prometheus 影响,但两者在数据模型、存储目标和查询语言上存在本质差异。下表从六个关键维度进行对比:

维度 Prometheus Loki
数据类型 数值型时间序列(指标) 文本型日志行(事件)
索引方式 基于标签(label)的倒排索引 基于标签的倒排索引 + 日志内容全文索引(可选)
存储内容 数值 + 时间戳 日志文本 + 元数据(标签、时间戳)
查询语言 PromQL(聚合、运算、预测) LogQL(过滤、解析、指标提取)
数据压缩 gorilla 压缩(浮点数) gzip / snappy / lz4(文本块)
典型场景 告警、监控、容量规划 日志审计、故障排查、门禁分析
架构误区提醒: 不要将 Loki 视为 Prometheus 的“日志版”。Prometheus 的拉模型(pull)与 Loki 的推模型(push)在数据采集、存储和查询优化上完全不同。在蓝绿发布门禁中,Loki 更适合记录每次发布的日志事件流,而 Prometheus 更适合监控发布过程中的 CPU/内存/错误率指标。

2.4 组件协作与扩展性

Loki 的组件协作遵循“无共享”原则,每个组件均可独立扩缩容。下图展示了组件间的数据流与依赖关系:

Loki 组件协作关系图 Loki 组件协作与扩展性 Distributor Ingester 对象存储 Compactor Querier Query Frontend 热数据 冷数据
扩展性要点:
  • Distributor / Querier / Query Frontend: 无状态组件,通过增加副本数线性提升吞吐量。
  • Ingester: 有状态组件,扩缩容需配合数据重新分片(ring 调整),建议使用 StatefulSet 部署。
  • Compactor: 单副本即可,资源消耗与存储数据量成正比。