2. Loki 架构回顾:核心组件、数据流与查询路径
在深入版本漂移校准之前,必须对 Loki 的经典架构形成肌肉记忆。Loki 采用 微服务 + 共享存储 架构,核心组件围绕“写路径”和“读路径”解耦设计。版本升级导致的接口差异,本质上就是这些组件之间 RPC 契约或 HTTP API 的变更。
2.1 核心组件一览
| 组件 | 职责 | 关键接口 | 版本漂移敏感点 |
|---|---|---|---|
| Distributor | 接收日志推送,验证数据,分片转发至 Ingester | /loki/api/v1/push (gRPC/HTTP) |
Push 协议字段变更、压缩算法切换 |
| Ingester | 内存缓冲、压缩、持久化日志块到对象存储 | gRPC Push、Flush、Transfer | Chunk 编码格式、索引 schema 版本 |
| Querier | 从 Ingester 和存储中读取日志,执行 LogQL 引擎 | /loki/api/v1/query_range (gRPC/HTTP) |
查询语法、聚合函数签名、时间戳精度 |
| QueryFrontend | 查询缓存、分片、合并、去重,加速读路径 | gRPC Frontend-to-Querier | 缓存键格式、分片算法、响应合并逻辑 |
SRE 视角: 版本升级时,Distributor → Ingester 的 gRPC 协议版本和 QueryFrontend → Querier 的查询分片协议是最容易产生“静默不兼容”的区域。即使 HTTP 路由不变,protobuf 字段编号或枚举值的变更也会导致解析失败。
2.2 写路径数据流
日志从客户端到持久化存储的完整路径,涉及两次数据转换和一次确认回传:
- 客户端推送:Promtail / Grafana Agent / SDK 通过 HTTP
/loki/api/v1/push发送日志流(Stream)到 Distributor。 - Distributor 验证与分片:校验标签合法性、租户 ID、时间戳范围;使用一致性哈希环(Consistent Hash Ring)将日志流路由到对应的 Ingester 副本。
- Ingester 接收与缓冲:将日志追加到内存中的 Chunk(块),按时间戳和标签组织。Chunk 达到阈值(如 1MB 或 1 小时)后标记为“就绪”。
- 持久化:Ingester 将就绪 Chunk 压缩、索引后写入对象存储(S3 / GCS / MinIO),并更新索引(Boltdb-shipper 或 TSDB)。
- 确认回传:Ingester 向 Distributor 返回 ACK,Distributor 再向客户端返回 204。
2.3 读路径查询流
查询路径比写路径更复杂,涉及 QueryFrontend 的智能路由 和 Querier 的分布式执行:
- 查询请求:客户端(Grafana / CLI)发送 LogQL 查询到 QueryFrontend。
- QueryFrontend 分片与缓存:将大查询按时间范围拆分为多个子查询;检查缓存(结果缓存 / 索引缓存),命中则直接返回。
- Querier 执行:每个子查询被发送到 Querier。Querier 同时查询 Ingester(内存数据) 和 对象存储(历史数据),执行 LogQL 引擎。
- 结果合并:QueryFrontend 收集所有 Querier 返回的子结果,按时间戳排序、去重、聚合,返回最终响应。
2.4 查询路径的版本漂移风险矩阵
版本升级时,以下接口最容易出现“新旧集群混跑”导致的查询差异:
| 接口 / 协议 | 常见变更 | 影响范围 | 检测手段 |
|---|---|---|---|
/loki/api/v1/query_range |
新增 step 参数校验、direction 枚举值 |
Grafana 面板、CLI 查询 | 对比新旧集群相同查询的响应体 |
gRPC QueryService |
protobuf 字段重命名、service 方法签名 | QueryFrontend ↔ Querier | gRPC reflection 版本比对 |
| Chunk 编码格式 | 压缩算法切换(gzip → snappy → lz4) | Ingester 写入 / Querier 读取 | 存储中 Chunk 的 magic number |
| 索引 schema | v11 → v12 → v13 字段增减 | Querier 索引查询 | loki-index-stats 命令 |
升级避坑: 如果集群采用 滚动升级,新旧版本的 Querier 和 Ingester 会短暂共存。此时必须确保 所有 Querier 的 LogQL 引擎版本一致,否则同一个查询在不同 Querier 上可能返回不同结果,导致 QueryFrontend 合并出错。
2.5 架构总结与校准切入点
Loki 的微服务架构通过 gRPC + HTTP 双协议解耦组件。版本漂移校准的核心在于:
- 写路径:Distributor 与 Ingester 之间的 Push 协议版本。
- 读路径:QueryFrontend 与 Querier 之间的查询分片协议,以及 Querier 自身的 LogQL 引擎版本。
- 存储层:Chunk 编码格式和索引 schema 版本,影响历史数据可读性。