第一章:核心架构总览

做实时日志分析,说白了就是跟数据赛跑。

我刚开始接触这个领域时,总觉得不就是把日志收上来、存起来、查一下嘛。结果第一个线上项目就给我上了一课——数据量一上来,整个系统直接崩了。嗯,从那以后我才真正理解,架构设计不是堆组件,而是让每一层都各司其职。

今天咱们就把这个架构拆开看看。我个人习惯把实时日志分析引擎分成五层:数据采集层、传输层、处理层、存储层、查询与可视化层。每一层都有自己的职责,也都有自己的坑。

核心原则:每一层只做一件事,并且把它做到极致。不要试图让采集层去做清洗,也别让存储层去干查询的活。

实时日志分析引擎 — 五层架构总览 应用服务器日志 网络设备 Syslog 业务埋点 / 用户行为 数据采集层 Filebeat / Fluentd / Logstash / Agent 传输层 Kafka / Pulsar / RabbitMQ 处理层 Flink / Spark Streaming / Kafka Streams 存储层 Elasticsearch / ClickHouse / HDFS 查询与可视化层 Kibana / Grafana / 自定义 API

1. 数据采集层:一切从这里开始

采集层是整个管道的起点。你想想看,如果源头的数据都丢了或者格式乱七八糟,后面再好的处理引擎也白搭。

我建议你根据日志来源选择采集器:

  • 文件日志:用 Filebeat 或 Fluentd。轻量、稳定,不会吃掉太多业务机器的资源。
  • 容器日志:Fluentd 配合 Docker 日志驱动,或者直接上 Logstash。
  • 网络设备:Syslog 协议,用 rsyslog 或 syslog-ng 收。
  • 业务埋点:自研 Agent 或直接用 SDK 推送到采集层。

我的经验:采集层一定要加「背压」机制。曾经有个项目,业务高峰期日志量暴涨 10 倍,采集器直接把业务进程的 CPU 吃满了。后来加了限流和缓冲,才稳住局面。

2. 传输层:数据的高速公路

采集到的日志不能直接丢给处理层。为什么?因为处理层可能扛不住突发流量,或者下游挂了。这时候就需要一个「缓冲带」。

我个人最常用的是 Kafka。原因很简单:

  • 吞吐量极高,单机能扛几十万条/秒
  • 数据持久化到磁盘,不怕丢
  • 支持多消费者,一个 Topic 可以同时供给 Flink 和 Spark

如果你对延迟要求特别高,可以考虑 Pulsar。它的架构更现代,延迟更低。但说实话,大部分场景 Kafka 够用了。

注意:传输层最容易踩的坑是「消息积压」。我曾经遇到过 Kafka 磁盘写满导致整个集群挂掉的情况。一定要配好磁盘监控和自动清理策略。

3. 处理层:真正的「实时」在这里

日志到了处理层,才算真正开始干活。这一层要做的事情包括:

  • 解析:把非结构化的日志转成结构化数据
  • 清洗:过滤掉无效日志、去重
  • 聚合:按时间窗口做计数、求和、去重统计
  • 告警:命中规则就触发通知

我建议你优先考虑 Flink。它的状态管理和 Exactly-Once 语义做得非常成熟。如果你团队里 Java 功底强,Flink 是首选。

如果你们团队偏 Scala 或 Python,Spark Streaming 也可以。但要注意,Spark 的延迟是秒级,Flink 能做到毫秒级。

// 一个简单的 Flink 实时统计示例
DataStream<String> logStream = env.addSource(new FlinkKafkaConsumer<>("logs", ...));

logStream
    .map(log -> parseLog(log))
    .keyBy(log -> log.getLevel())
    .window(TumblingProcessingTimeWindows.of(Time.minutes(1)))
    .aggregate(new CountAggregator())
    .addSink(new ElasticsearchSink<>(...));

env.execute("实时日志统计作业");

核心要点:处理层一定要做「水位线」管理。否则乱序数据会让你统计结果一塌糊涂。我踩过这个坑,后来老老实实配了 Watermark。

4. 存储层:数据要能「存得住、查得快」

处理完的数据最终要落盘。存储层的选型直接决定了查询体验。

我一般分两种场景:

场景 推荐引擎 理由
全文检索、日志搜索 Elasticsearch 倒排索引,模糊查询快,生态成熟
聚合分析、大屏展示 ClickHouse 列式存储,聚合查询极快
长期归档、冷数据 HDFS / S3 成本低,容量大

我个人习惯用 ES + ClickHouse 混搭。热数据放 ES 做实时搜索,冷数据转 ClickHouse 做历史分析。这样既保证了查询速度,又控制了存储成本。

避坑指南:ES 的索引分片数别设太多。我曾经一个索引设了 60 个分片,结果集群 rebalance 时直接把网络打满了。一般建议每个分片 20-40GB 数据量。

5. 查询与可视化层:让数据「说话」

最后一层是给用户看的。你想想看,如果数据存得再好,查起来慢或者看不懂,那前面的努力都白费了。

我建议你根据用户角色来设计查询接口:

  • 运维人员:Kibana 或 Grafana 仪表盘,实时看日志趋势、错误率
  • 业务人员:封装好的 API,返回聚合后的指标
  • 数据分析师:提供 SQL 接口,让他们自己写查询

这里有个细节:查询层一定要做 缓存。同样的查询条件,5 分钟内重复查,直接从缓存拿结果。不然 ES 或 ClickHouse 扛不住高频查询。

我的建议:可视化层不要只展示「好看」的图表。要加「下钻」能力——看到异常了,能点进去看原始日志。否则图表再漂亮,排查问题时还是得去翻原始数据。

小结

五层架构,每一层都有自己的使命。采集层管「收」,传输层管「稳」,处理层管「算」,存储层管「存」,查询层管「看」。少了哪一层,系统都会出问题。

嗯,这一章咱们把骨架搭起来了。后面每一层我都会展开细讲,包括具体的选型对比、配置参数、以及我在项目中踩过的那些坑。


专注资料整理