2. Loki 核心架构:组件、读写路径与职责
Loki 的架构设计深受 Prometheus 启发,采用 微服务 + 水平扩展 模式,将日志的接收、存储、查询与前端路由解耦为独立组件。理解这一架构是后续进行压测建模、容量预测与变更门禁设计的基础。
2.1 整体架构总览
Loki 的核心组件包括 Distributor、Ingester、Querier 与 Query Frontend。它们通过共享的 对象存储(如 S3、GCS、MinIO)与 一致性哈希环(Consul / etcd)协同工作。下图展示了各组件的逻辑关系与数据流向:
2.2 组件职责与关键特性
每个组件承担明确的职责,并可通过增加副本数实现水平扩展。下表总结了各组件的核心功能与压测关注点:
| 组件 | 核心职责 | 关键特性 | 压测关注点 |
|---|---|---|---|
| Distributor | 接收日志写入请求,验证并分发 | 无状态、一致性哈希路由、速率限制 | QPS、请求大小、gRPC 连接数 |
| Ingester | 缓存日志到内存,批量刷写到对象存储 | 有状态、chunk 管理、WAL 持久化 | 内存占用、chunk 刷写频率、磁盘 IO |
| Querier | 执行 LogQL 查询,合并结果 | 无状态、支持并行查询、缓存 | 查询并发、索引扫描、对象存储延迟 |
| Query Frontend | 查询路由、分片、缓存、限流 | 无状态、查询分片、结果缓存 | 缓存命中率、分片策略、超时控制 |
压测提示: Distributor 和 Querier 为无状态组件,适合作为水平扩展的压测入口;Ingester 为有状态组件,其内存与刷写策略直接影响写入吞吐与数据持久性,是容量预测的核心建模对象。
2.3 写入路径详解
一条日志从客户端到达对象存储,经历以下关键步骤:
- 客户端推送:Promtail / Fluent Bit 等客户端将日志流推送到 Distributor 的 HTTP/gRPC 端点。
- 验证与哈希:Distributor 校验日志标签(Label)合法性,并根据标签计算一致性哈希,确定目标 Ingester 副本。
- 转发至 Ingester:Distributor 将日志流转发给对应的 Ingester 实例。Ingester 将日志追加到内存中的 chunk(数据块)中。
- 确认响应:Ingester 写入成功后返回 ACK,Distributor 再向客户端返回 204 状态码。
- 异步刷写:Ingester 根据配置的
chunk_idle_period(默认 1 分钟)或chunk_target_size(默认 1.5 MB)将内存 chunk 压缩并上传到对象存储。
写入路径关键指标:
loki_distributor_bytes_received_total— 接收字节数loki_ingester_chunks_flushed_total— chunk 刷写总数loki_ingester_memory_chunks— 当前内存中 chunk 数量
2.4 读取路径详解
查询请求的处理路径与写入路径解耦,支持 即时查询 与 范围查询:
- 查询请求到达 Query Frontend:Frontend 根据查询时间范围进行 分片(split by time)和 并行化。
- 分发至 Querier:Frontend 将子查询分发给多个 Querier 实例并行执行。
- 数据源选择:Querier 同时查询 Ingester 内存中的热数据 和 对象存储中的冷数据,合并结果。
- 结果聚合:Querier 将子查询结果返回给 Frontend,Frontend 进行最终聚合与排序,返回给客户端。
2.5 组件协作与一致性保障
Loki 通过 一致性哈希环 确保写入请求被正确路由到持有对应日志流的 Ingester。当 Ingester 实例发生扩缩容或故障时,哈希环自动更新,Distributor 重新计算路由。Querier 在查询时通过 Read 路径 同时访问 Ingester 的内存数据与对象存储的持久化数据,保证数据完整性。
容量预测注意: Ingester 的内存消耗与
chunk 数量、日志流基数(active streams)强相关。在压测沙盘中,应重点监控 loki_ingester_memory_streams 与 loki_ingester_chunk_utilization 指标,以预测内存瓶颈点。
2.6 组件通信协议
组件间通信采用 gRPC 与 HTTP 两种协议,具体使用场景如下:
| 通信方向 | 协议 | 数据格式 | 说明 |
|---|---|---|---|
| 客户端 → Distributor | HTTP / gRPC | Protobuf / JSON | 日志推送接口 |
| Distributor → Ingester | gRPC | Protobuf | 内部转发,低延迟 |
| Ingester → 对象存储 | HTTP (S3/GCS API) | 压缩 chunk | 异步刷写 |
| Querier → Ingester | gRPC | Protobuf | 查询热数据 |
| Querier → 对象存储 | HTTP | 压缩 chunk | 查询冷数据 |
| Query Frontend → Querier | gRPC | Protobuf | 子查询分发 |
理解这些通信协议有助于在压测沙盘中模拟真实流量特征,例如 gRPC 连接复用、HTTP 连接池大小等参数调优。