什么是ELK
ELK是三个开源项目的首字母缩写:
| 字母 | 全称 | 角色 | 一句话介绍 |
|---|---|---|---|
| E | Elasticsearch | 搜索引擎 | 存数据、查数据,快得离谱 |
| L | Logstash | 数据管道 | 收数据、洗数据、发数据 |
| K | Kibana | 可视化 | 画图表、做看板、装门面 |
后来官方又加了个小弟 Beats(轻量级数据采集器),所以现在更准确的叫法是 Elastic Stack。但大家还是习惯叫ELK,就像大家还是管"抖音"叫"抖音"而不是"字节跳动短视频平台"一样。
整体架构
先上一张全家福,看看这几位是怎么配合的:
flowchart LR
subgraph 数据源
A1[应用日志]
A2[系统日志]
A3[Nginx日志]
A4[数据库日志]
end
subgraph 采集层
B1[Filebeat]
B2[Metricbeat]
B3[Packetbeat]
end
subgraph 处理层
C[Logstash]
end
subgraph 存储层
D[(Elasticsearch)]
end
subgraph 展示层
E[Kibana]
end
A1 --> B1
A2 --> B1
A3 --> B1
A4 --> B1
B2 --> C
B3 --> C
B1 --> C
C --> D
D --> E
数据流向:日志文件 → Beats采集 → Logstash清洗 → Elasticsearch存储 → Kibana展示
各组件详解
1. Elasticsearch —— 搜索引擎之王
Elasticsearch(简称ES)是整个技术栈的核心,基于Lucene构建的分布式搜索引擎。
flowchart TB
subgraph Elasticsearch集群
subgraph Node1[节点1-Master]
S1[(Shard 1)]
S2[(Shard 2)]
end
subgraph Node2[节点2-Data]
S3[(Shard 3)]
R1[(Replica 1)]
end
subgraph Node3[节点3-Data]
R2[(Replica 2)]
R3[(Replica 3)]
end
end
Node1 <--> Node2
Node2 <--> Node3
Node1 <--> Node3
核心概念:
| 概念 | 类比MySQL | 说明 |
|---|---|---|
| Index | Database | 索引,一类数据的集合 |
| Document | Row | 文档,一条数据(JSON格式) |
| Field | Column | 字段,文档中的属性 |
| Shard | Partition | 分片,数据水平切分 |
| Replica | Slave | 副本,高可用保障 |
为什么快:
- 倒排索引(Inverted Index):不是"文档→词",而是"词→文档列表"
- 分布式架构:数据分片存储,查询并行执行
- 近实时(NRT):写入后1秒内可搜索
基础操作:
# 创建索引
PUT /logs-2024
# 写入文档
POST /logs-2024/_doc
{
"timestamp": "2024-01-15T10:30:00",
"level": "ERROR",
"message": "用户支付失败",
"service": "payment"
}
# 搜索
GET /logs-2024/_search
{
"query": {
"bool": {
"must": [
{ "match": { "level": "ERROR" } },
{ "match": { "service": "payment" } }
]
}
}
}2. Logstash —— 数据管道工
Logstash是一个数据处理管道,负责"收集 → 转换 → 输出"。
flowchart LR
subgraph Input[输入插件]
I1[file]
I2[beats]
I3[kafka]
I4[jdbc]
end
subgraph Filter[过滤插件]
F1[grok]
F2[mutate]
F3[date]
F4[geoip]
end
subgraph Output[输出插件]
O1[elasticsearch]
O2[kafka]
O3[file]
O4[email]
end
Input --> Filter --> Output
三段式配置:
# /etc/logstash/conf.d/nginx.conf
input {
beats {
port => 5044
}
}
filter {
# 解析Nginx日志格式
grok {
match => {
"message" => '%{IPORHOST:clientip} - - \[%{HTTPDATE:timestamp}\] "%{WORD:method} %{URIPATHPARAM:request} HTTP/%{NUMBER:httpversion}" %{NUMBER:response} %{NUMBER:bytes}'
}
}
# 解析时间
date {
match => [ "timestamp", "dd/MMM/yyyy:HH:mm:ss Z" ]
target => "@timestamp"
}
# 解析IP地理位置
geoip {
source => "clientip"
}
# 删除不需要的字段
mutate {
remove_field => ["message", "agent", "ecs"]
}
}
output {
elasticsearch {
hosts => ["http://localhost:9200"]
index => "nginx-logs-%{+YYYY.MM.dd}"
}
}Grok调试技巧:Grok表达式写错了日志就解析不出来,推荐用 Grok Debugger 在线调试。
3. Kibana —— 颜值担当
Kibana是ELK的可视化门面,提供了:
flowchart TB
subgraph Kibana功能
A[Discover] --> A1[日志搜索与浏览]
B[Visualize] --> B1[图表制作]
C[Dashboard] --> C1[看板组装]
D[Dev Tools] --> D1[ES查询调试]
E[Management] --> E1[索引管理]
F[Alerting] --> F1[告警配置]
end
常用功能:
| 功能 | 用途 | 使用场景 |
|---|---|---|
| Discover | 搜索原始日志 | 问题排查 |
| Visualize | 创建单个图表 | 数据分析 |
| Dashboard | 组合多个图表 | 监控大屏 |
| Dev Tools | 执行ES查询 | 开发调试 |
| Alerting | 配置告警规则 | 异常监控 |
4. Beats —— 轻量级特工
Beats是一系列轻量级数据采集器,比Logstash更省资源。
flowchart LR
subgraph Beats家族
FB[Filebeat
日志文件] MB[Metricbeat
系统指标] PB[Packetbeat
网络数据] HB[Heartbeat
健康检查] AB[Auditbeat
审计数据] end FB --> L[Logstash/ES] MB --> L PB --> L HB --> L AB --> L
日志文件] MB[Metricbeat
系统指标] PB[Packetbeat
网络数据] HB[Heartbeat
健康检查] AB[Auditbeat
审计数据] end FB --> L[Logstash/ES] MB --> L PB --> L HB --> L AB --> L
Filebeat配置示例:
# /etc/filebeat/filebeat.yml
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/nginx/access.log
- /var/log/nginx/error.log
tags: ["nginx"]
- type: log
enabled: true
paths:
- /var/log/app/*.log
tags: ["application"]
multiline:
pattern: '^\d{4}-\d{2}-\d{2}'
negate: true
match: after
output.logstash:
hosts: ["logstash:5044"]
# 或者直接输出到ES(跳过Logstash)
# output.elasticsearch:
# hosts: ["elasticsearch:9200"]架构演进
根据业务规模,ELK架构也有不同的玩法:
初级架构:单机版
flowchart LR
A[应用日志] --> B[Filebeat]
B --> C[Elasticsearch
单节点] C --> D[Kibana]
单节点] C --> D[Kibana]
适用场景:开发测试环境、日志量 < 10GB/天
中级架构:标准版
flowchart LR
subgraph 应用服务器
A1[App1] --> F1[Filebeat]
A2[App2] --> F2[Filebeat]
A3[App3] --> F3[Filebeat]
end
F1 --> L[Logstash]
F2 --> L
F3 --> L
L --> ES[(ES集群
3节点)] ES --> K[Kibana]
3节点)] ES --> K[Kibana]
适用场景:生产环境、日志量 10GB~100GB/天
高级架构:带缓冲队列
flowchart LR
subgraph 采集层
F1[Filebeat]
F2[Filebeat]
F3[Filebeat]
end
subgraph 缓冲层
K1[Kafka]
end
subgraph 处理层
L1[Logstash]
L2[Logstash]
end
subgraph 存储层
ES[(ES集群)]
end
F1 --> K1
F2 --> K1
F3 --> K1
K1 --> L1
K1 --> L2
L1 --> ES
L2 --> ES
ES --> Kibana
为什么要加Kafka:
- 削峰填谷:突发流量时Kafka先扛住
- 解耦:Logstash挂了数据不丢
- 多消费:一份数据可以给多个系统用
适用场景:大规模生产环境、日志量 > 100GB/天
实战:从零搭建ELK
Docker Compose一键启动
# docker-compose.yml
version: '3.8'
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.11.0
container_name: elasticsearch
environment:
- discovery.type=single-node
- xpack.security.enabled=false
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ports:
- "9200:9200"
volumes:
- es_data:/usr/share/elasticsearch/data
logstash:
image: docker.elastic.co/logstash/logstash:8.11.0
container_name: logstash
ports:
- "5044:5044"
volumes:
- ./logstash/pipeline:/usr/share/logstash/pipeline
depends_on:
- elasticsearch
kibana:
image: docker.elastic.co/kibana/kibana:8.11.0
container_name: kibana
ports:
- "5601:5601"
environment:
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
depends_on:
- elasticsearch
filebeat:
image: docker.elastic.co/beats/filebeat:8.11.0
container_name: filebeat
user: root
volumes:
- ./filebeat/filebeat.yml:/usr/share/filebeat/filebeat.yml:ro
- /var/log:/var/log:ro
depends_on:
- logstash
volumes:
es_data:# 启动
docker-compose up -d
# 访问Kibana
open http://localhost:5601运维要点
索引生命周期管理(ILM)
日志不能无限存,要设置自动清理策略:
flowchart LR
A[Hot
热数据
7天] --> B[Warm
温数据
30天] B --> C[Cold
冷数据
90天] C --> D[Delete
删除]
热数据
7天] --> B[Warm
温数据
30天] B --> C[Cold
冷数据
90天] C --> D[Delete
删除]
PUT _ilm/policy/logs-policy
{
"policy": {
"phases": {
"hot": {
"min_age": "0ms",
"actions": {
"rollover": {
"max_size": "50gb",
"max_age": "7d"
}
}
},
"warm": {
"min_age": "7d",
"actions": {
"shrink": { "number_of_shards": 1 },
"forcemerge": { "max_num_segments": 1 }
}
},
"delete": {
"min_age": "90d",
"actions": { "delete": {} }
}
}
}
}性能优化Checklist
| 层面 | 优化项 | 说明 |
|---|---|---|
| ES | 合理设置分片数 | 单分片20-40GB为宜 |
| ES | 使用SSD | 机械盘扛不住 |
| ES | 调整JVM堆内存 | 不超过物理内存50%,不超过32GB |
| Logstash | 调整worker数 | 等于CPU核数 |
| Logstash | 批量大小 | batch.size适当调大 |
| Filebeat | 限速 | 避免打满网络 |
常见问题排查
问题1:ES集群变黄/变红
flowchart TD
A[集群状态异常] --> B{检查原因}
B -->|分片未分配| C[检查磁盘空间]
B -->|节点掉线| D[检查节点状态]
B -->|副本数不足| E[调整副本数]
C --> C1[清理旧索引]
D --> D1[重启节点]
E --> E1[PUT index/_settings
number_of_replicas: 1]
number_of_replicas: 1]
# 查看集群健康
GET _cluster/health
# 查看未分配的分片
GET _cat/shards?v&h=index,shard,prirep,state,unassigned.reason
# 查看节点状态
GET _cat/nodes?v问题2:Logstash处理慢
# 检查管道状态
curl -X GET "localhost:9600/_node/stats/pipelines?pretty"
# 常见原因:
# 1. Grok表达式太复杂 → 优化正则
# 2. 外部调用阻塞 → 使用异步
# 3. 资源不足 → 加机器ELK vs 竞品
| 方案 | 优势 | 劣势 | 适用场景 |
|---|---|---|---|
| ELK | 功能全、生态好、社区大 | 资源占用高、运维复杂 | 大中型企业 |
| Loki+Grafana | 轻量、成本低 | 功能相对简单 | 云原生环境 |
| ClickHouse | 查询快、压缩高 | 非专业日志系统 | 海量日志分析 |
| SLS(阿里云) | 免运维、开箱即用 | 厂商锁定、费用 | 不想自建 |
总结
mindmap
root((ELK技术栈))
Elasticsearch
分布式搜索引擎
倒排索引
近实时查询
Logstash
数据管道
Input/Filter/Output
Grok解析
Kibana
可视化
Dashboard
告警
Beats
轻量采集
Filebeat
Metricbeat
一句话总结:
- Elasticsearch = 数据仓库(存得下、查得快)
- Logstash = 数据清洗工(收得来、洗得干净)
- Kibana = 数据门面(看得见、看得懂)
- Beats = 数据快递(轻量、省事)
ELK不是银弹,但在日志管理这个领域,它确实是目前最成熟的方案。用好了,凌晨3点不用起床;用不好,凌晨3点还得手动grep。
参考资料
- 🔗 Elastic官方文档
- 🔗 Elasticsearch权威指南(中文)
- 🔗 Grok Debugger
- 📖 《Elasticsearch实战》
- 📖 《深入理解Elasticsearch》
没有日志的系统就像没有后视镜的车——能开,但迟早要出事。 🚗