2. 日志检索系统架构概览:数据采集层、传输层、存储层、查询层、展示层核心组件
日志检索系统是保障业务可观测性的核心基础设施。一套生产级日志检索系统通常采用五层架构:数据采集层、传输层、存储层、查询层、展示层。每一层承担独立的职责,层与层之间通过标准协议解耦,从而支持水平扩展与故障隔离。
架构设计原则: 日志检索系统的每一层都应具备独立的故障域。采集层故障不影响存储与查询;存储层故障不应导致展示层完全不可用。层间通过缓冲队列(如 Kafka)削峰填谷,是保障高可用的关键。
2.1 五层架构总览
下图展示了日志检索系统的完整数据流与核心组件关系。数据从业务服务器产生,经过采集、传输、存储、索引构建,最终通过查询接口呈现给用户。
2.2 各层核心组件与职责
| 架构层 | 核心组件 | 主要职责 | 关键指标 / 关注点 |
|---|---|---|---|
| 采集层 | Filebeat, Fluentd, Logstash, Vector, SDK | 从业务服务器、容器、中间件实时采集日志;支持多源接入、日志解析、元数据注入 | 采集延迟 < 1s;单节点吞吐 > 10MB/s;资源占用(CPU/内存) |
| 传输层 | Apache Kafka, Apache Pulsar, RabbitMQ | 缓冲削峰、异步解耦、消息持久化、多消费者订阅;保障数据不丢失 | 消息堆积量、消费延迟、分区副本同步状态 |
| 存储层 | Elasticsearch, OpenSearch, ClickHouse | 日志索引构建、分片与副本管理、数据压缩、冷热分层存储、生命周期管理 | 索引写入 TPS、查询 P99 延迟、磁盘使用率、分片健康状态 |
| 查询层 | ES Query DSL, SQL 网关, 查询路由, 缓存 | 接收查询请求、解析语法、路由到对应索引分片、聚合计算、结果缓存 | 查询并发数、慢查询比例、缓存命中率、跨集群查询延迟 |
| 展示层 | Kibana, Grafana, 自研 Web UI, API 网关 | 可视化日志检索、仪表盘、告警配置、用户权限管理、API 暴露 | 页面加载时间、图表渲染性能、API 响应时间 |
2.3 数据采集层详解
采集层是日志检索系统的入口,直接面对业务服务器、容器平台和中间件。采集器需要解决资源消耗与采集完整性之间的平衡。
- Filebeat:轻量级采集器,基于 Golang 开发,资源占用极低,适合容器化环境。通过 Harvester 逐行读取日志文件,使用 Registry 文件记录读取偏移量,支持断点续传。
- Fluentd:Ruby 生态,插件丰富,支持输入/输出/过滤/缓冲四阶段管道。适合复杂日志解析场景。
- Logstash:ELK 生态核心组件,支持丰富的 filter 插件(grok、date、mutate),但资源消耗较高,通常作为采集侧轻量级预处理节点。
- Vector:Rust 编写,高性能低内存,支持单元化配置,适合大规模集群部署。
- SDK 埋点:业务代码内直接发送日志到传输层,适用于高频、结构化业务日志。
采集层故障演练要点: 模拟采集器进程 OOM、采集器与 Kafka 网络中断、日志文件轮转丢失、采集器配置错误导致日志格式异常。演练目标:验证断点续传、自动重连、告警通知是否生效。
2.4 传输层详解
传输层是系统的数据总线,承担着削峰填谷、异步解耦、多消费者分发等核心职责。生产环境中,Apache Kafka 是最主流的选择。
| 特性 | Kafka | Pulsar | RabbitMQ |
|---|---|---|---|
| 存储模型 | 分区日志(磁盘顺序写) | Segment + BookKeeper | 队列 + 交换机(内存优先) |
| 吞吐量 | 极高(百万 msg/s) | 高(支持分层存储) | 中等(万级 msg/s) |
| 消息持久化 | 支持(可配置保留策略) | 支持(默认持久化) | 支持(需配置持久化模式) |
| 消费模式 | 拉模式(Consumer Pull) | 拉模式 + 独占/共享/灾备 | 推模式 + 拉模式 |
| 日志场景适用性 | ★★★★★ | ★★★★☆ | ★★★☆☆ |
传输层配置的核心参数包括:retention.ms(日志保留时长)、replication.factor(副本数)、min.insync.replicas(最小同步副本数)。这些参数直接影响数据可靠性与存储成本。
2.5 存储层详解
存储层是日志检索系统的数据核心,负责索引构建、数据压缩、分片管理与生命周期管理。Elasticsearch 是目前日志检索领域的事实标准。
存储层核心概念:
- 索引(Index):日志数据的逻辑容器,通常按时间(如
logs-2025-01-15)或业务维度划分。 - 分片(Shard):索引的物理子集,每个分片是一个独立的 Lucene 实例。主分片数在索引创建时确定,不可修改。
- 副本(Replica):主分片的冗余拷贝,用于故障转移和查询负载分担。
- 冷热分层:热节点(SSD + 高内存)承载近期高频写入与查询;冷节点(HDD + 大容量)存储历史归档数据。
- 生命周期管理(ILM):自动将索引从热阶段迁移到冷阶段,最终删除,降低运维成本。
2.6 查询层详解
查询层负责将用户的检索请求转化为存储层可执行的查询计划,并聚合返回结果。查询层的性能直接影响用户体验。
- ES Query DSL:基于 JSON 的查询语法,支持全文搜索、精确匹配、聚合分析、地理位置查询等。
- SQL 网关:如 Elasticsearch SQL、OpenSearch SQL,允许用户使用标准 SQL 语法查询日志,降低使用门槛。
- 查询路由:根据索引别名、时间范围、租户 ID 将请求路由到正确的索引或分片,避免全集群扫描。
- 缓存加速:查询结果缓存(Query Cache)、分片级缓存(Shard Request Cache)、字段数据缓存(Field Data Cache)三级缓存体系。
常见查询层故障: 慢查询导致集群 CPU 飙升、缓存未命中引发查询毛刺、跨集群查询网络超时、查询并发数超过集群承载能力。故障演练应重点验证:查询熔断机制、缓存预热策略、查询超时配置是否生效。
2.7 展示层详解
展示层是用户与日志检索系统交互的界面。生产环境中,展示层需要兼顾易用性与安全性。
| 组件 | 适用场景 | 核心能力 | 局限性 |
|---|---|---|---|
| Kibana | ELK 生态标准展示层 | Discover 检索、Dashboard、Canvas、Alerting、ML | 大规模集群下页面加载慢;权限管理依赖 X-Pack |
| Grafana | 多数据源统一监控与日志 | 丰富的图表类型、告警规则、Explore 日志查询 | 日志检索交互不如 Kibana 原生;对 ES 聚合支持有限 |
| 自研 Web UI | 定制化需求、多租户隔离 | 灵活权限控制、业务定制字段、集成工单系统 | 开发维护成本高;需自行实现查询网关与缓存 |
2.8 层间交互与数据流
理解层间交互是故障定位的基础。以下是一个典型日志检索请求的完整数据流:
- 采集:Filebeat 读取
/var/log/app/*.log,解析为 JSON 格式,发送到 Kafka Topicapp-logs。 - 传输:Kafka 将消息持久化到分区,等待消费者拉取。Logstash 或 ES 的 Kafka 消费端从 Topic 拉取数据。
- 写入:ES 接收批量请求,将文档写入对应索引的主分片,主分片同步到副本分片。
- 查询:用户在 Kibana 输入检索语句,Kibana 将请求发送到 ES 查询网关,网关解析后路由到对应分片。
- 聚合:各分片返回匹配结果,查询节点合并、排序、聚合后返回给 Kibana 渲染展示。
故障演练切入点: 每一层都可能成为故障点。演练设计应覆盖:采集层断流、传输层消息积压、存储层分片丢失、查询层慢查询、展示层超时。通过分层演练,验证各层的故障隔离与恢复能力。