日志采集与存储:选对工具,事半功倍
日志采集和存储,是整个日志分析体系的基石。说白了,你后面分析得再花哨,如果源头数据没采好、存得乱,那一切都是白搭。我在这个环节踩过的坑,比后面分析阶段多得多。今天咱们就把这块掰开揉碎了讲清楚。
日志采集工具:三驾马车怎么选?
目前主流的采集工具就三个:Filebeat、Logstash、Fluentd。很多人纠结选哪个,其实没那么复杂。我个人的习惯是:轻量级采集用 Filebeat,复杂处理用 Logstash,云原生场景用 Fluentd。
Filebeat:轻量级选手
Filebeat 是 Elastic 家的轻量采集器。它最大的优点就是轻——资源占用极低,部署简单。你想想看,如果要在几百台服务器上装采集器,Filebeat 几乎是无感的。
核心特点:
- 基于 Golang 编写,内存占用通常不到 20MB
- 支持自动多行合并(比如 Java 异常栈)
- 内置 Elasticsearch 和 Logstash 输出
- 支持 SSL/TLS 加密传输
我曾经在一个金融项目中,用 Filebeat 采集了 2000+ 台服务器的 Nginx 日志。部署完一看,每台机器 CPU 占用不到 1%。嗯,这就是轻量的好处。
Logstash:重型数据处理引擎
Logstash 是 ELK 栈里的老大哥。它功能强大,但代价就是吃资源。我建议只在需要复杂数据转换的场景下用它。
举个例子,你采集的日志里 IP 地址需要转换成地理位置,或者需要从 JSON 里提取嵌套字段,这时候 Logstash 的 filter 插件就派上用场了:
input {
beats {
port => 5044
}
}
filter {
geoip {
source => "client_ip"
target => "geo"
}
mutate {
rename => { "[geo][location]" => "[geo][coordinates]" }
}
}
output {
elasticsearch {
hosts => ["localhost:9200"]
index => "nginx-%{+YYYY.MM.dd}"
}
}
避坑指南:我曾经在一个日志量日均 50TB 的项目里,直接用 Logstash 做采集。结果呢?集群 CPU 直接飙到 90%,最后不得不改成 Filebeat + Kafka + Logstash 的架构。记住:Logstash 不适合做第一层采集,它更适合做中间处理层。
Fluentd:云原生时代的宠儿
Fluentd 是 CNCF 毕业项目,在 Kubernetes 生态里用得特别多。它的插件生态非常丰富,有 1000+ 个插件。我个人觉得,如果你在用 K8s,Fluentd 几乎是标配。
| 特性 | Filebeat | Logstash | Fluentd |
|---|---|---|---|
| 资源占用 | 极低 | 较高 | 中等 |
| 数据处理能力 | 弱 | 强 | 中 |
| 插件生态 | 有限 | 丰富 | 非常丰富 |
| K8s 支持 | 一般 | 一般 | 原生支持 |
| 学习曲线 | 低 | 中 | 中 |
| 典型场景 | 轻量采集 | 复杂处理 | 云原生 |
日志存储方案:ELK、Loki、ClickHouse 怎么选?
存日志这件事,没有银弹。不同的场景,适合不同的方案。我这些年三个都用过,说说我的真实感受。
ELK:经典组合,功能全面
ELK(Elasticsearch + Logstash + Kibana)是日志领域的黄金标准。它最大的优势是全文搜索能力极强,而且 Kibana 的可视化做得非常好。
适合场景:
- 需要全文搜索日志内容
- 需要复杂的聚合分析
- 团队有 Elasticsearch 运维经验
我的建议:ELK 虽然好用,但别盲目上。我见过太多团队把 ELK 当数据库用,结果集群动不动就挂。记住:ELK 是搜索引擎,不是存储系统。日志保留周期一定要规划好,热数据 7 天,温数据 30 天,冷数据归档到对象存储。
Loki:轻量级日志聚合系统
Loki 是 Grafana 团队推出的,它和 Prometheus 的理念很像——只索引元数据,不索引日志内容。这意味着它比 ELK 省资源得多。
我为什么喜欢 Loki?因为它和 Grafana 无缝集成。你可以在同一个 Dashboard 里看指标和日志,不用来回切换。对于中小团队来说,Loki 的运维成本比 ELK 低太多了。
# Loki 的配置示例
auth_enabled: false
server:
http_listen_port: 3100
ingester:
lifecycler:
ring:
kvstore:
store: inmemory
replication_factor: 1
schema_config:
configs:
- from: 2020-10-24
store: boltdb-shipper
object_store: filesystem
schema: v11
index:
prefix: index_
period: 24h
注意:Loki 不适合需要全文搜索的场景。比如你要查某个特定的错误信息,Loki 的查询速度会比 ELK 慢很多。它更适合基于标签的日志检索,比如查某个 Pod、某个服务的所有日志。
ClickHouse:列式存储的异类
ClickHouse 本来是做 OLAP 分析的,但很多人发现它存日志也特别好用。为什么?因为日志数据的特点就是写多读少、按时间范围查询,这正好是 ClickHouse 的强项。
我曾经在一个广告系统里,每天产生 100 亿条点击日志。用 ELK 根本扛不住,后来换成 ClickHouse,查询速度提升了 10 倍以上。
| 方案 | 查询速度 | 存储成本 | 运维复杂度 | 全文搜索 | 典型场景 |
|---|---|---|---|---|---|
| ELK | 快(全文搜索) | 高 | 高 | 支持 | 通用日志分析 |
| Loki | 中等(标签查询) | 低 | 低 | 不支持 | K8s 日志、指标关联 |
| ClickHouse | 极快(聚合查询) | 低 | 中 | 有限 | 海量日志、实时分析 |
日志轮转策略:别让磁盘爆了
日志轮转是个老生常谈的问题,但很多人就是不在意。我见过最夸张的一次,某台服务器因为日志没轮转,直接把 2TB 的磁盘写满了,导致整个业务挂了 3 个小时。
Linux 下最常用的轮转工具是 logrotate。它的配置其实很简单,但有几个关键点要注意:
/var/log/nginx/*.log {
daily # 每天轮转一次
rotate 30 # 保留 30 天的日志
compress # 压缩旧日志
delaycompress # 延迟一天压缩
missingok # 日志文件不存在不报错
notifempty # 空文件不轮转
create 0640 nginx adm # 创建新日志文件的权限
sharedscripts # 所有日志轮转后执行一次脚本
postrotate
/usr/sbin/nginx -s reopen # 通知 Nginx 重新打开日志文件
endscript
}
轮转策略的核心原则:
- 按时间轮转:每天或每小时轮转一次,方便按时间范围查询
- 按大小轮转:设置最大文件大小,防止单个文件过大
- 压缩旧日志:文本日志压缩率很高,通常能压缩到原来的 10%
- 设置保留周期:根据磁盘空间和业务需求,确定保留天数
我个人习惯的配置是:每天轮转一次,保留 30 天,超过 30 天的自动删除。如果日志量特别大,可以改成每小时轮转一次,保留 7 天。
小技巧:很多应用在写日志时,会持有文件句柄。如果直接删除日志文件,应用可能不会释放句柄,导致磁盘空间无法回收。所以一定要用 copytruncate 或者通知应用重新打开日志文件的方式。嗯,这个坑我踩过两次才记住。
整体架构图
下面这张图,是我在实际项目中常用的日志采集与存储架构。你可以看到,从日志产生到最终存储,每个环节都有对应的工具和策略。
这张图展示的是我比较推荐的通用架构。你想想看,从日志产生到最终存储,中间经过采集、缓冲、处理、存储四个环节。每个环节都有多种选择,关键是根据你的业务场景来取舍。
好了,日志采集与存储这块就聊这么多。记住一句话:没有最好的方案,只有最适合的方案。选工具的时候,多想想你的业务场景、团队能力、运维成本,别盲目跟风。