TL;DR
- 场景: 搭建集中式日志系统,实现日志采集、存储、分析、可视化
- 结论: ELK 栈提供完整的日志解决方案,ES 负责存储与搜索,Logstash 负责采集,Kibana 负责可视化
- 产出: 架构设计、核心概念、查询 DSL、错误速查
集中式日志系统
核心功能
| 功能 | 说明 |
|---|---|
| 收集 | 多源日志采集 |
| 传输 | 日志传输管道 |
| 存储 | 分布式存储 |
| 分析 | 全文搜索与聚合 |
| 告警 | 异常监控与告警 |
架构
日志源 → Logstash → Elasticsearch ← Kibana
Elasticsearch 核心概念
集群(Cluster)与节点(Node)
| 节点类型 | 职责 |
|---|---|
| Master 节点 | 集群管理、索引创建、负载均衡 |
| Data 节点 | 数据存储、文档 CRUD |
| Coordinating 节点 | 请求转发、结果聚合 |
索引(Index)
- 类似关系型数据库的表
- 支持动态映射
- 可设置分片与副本数
分片(Shard)与副本(Replica)
| 类型 | 作用 |
|---|---|
| 主分片 | 数据水平扩展 |
| 副本分片 | 高可用、读并发 |
查询 DSL
// 全文搜索
{"query": {"match": {"content": "error"}}}
// 精确查询
{"query": {"term": {"status": "failed"}}}
// 范围查询
{"query": {"range": {"@timestamp": {"gte": "now-1h"}}}}
// 布尔组合
{"query": {"bool": {"must": [{"match": {"level": "error"}}], "filter": [{"range": {"@timestamp": {"gte": "now-1h"}}}]}}}
聚合
| 类型 | 用途 |
|---|---|
| Bucket | 分组统计 |
| Metric | 数值计算 |
| Pipeline | 管道聚合 |
Logstash
作用
实时数据收集引擎,支持多种数据源:
- 文件日志
- 网络协议(TCP/UDP/HTTP)
- 数据库(JDBC)
- 消息队列(Kafka、Redis)
配置文件结构
input {
file {
path => "/var/log/*.log"
start_position => "beginning"
}
}
filter {
grok {
match => {"message" => "%{TIMESTAMP_ISO8601:timestamp} %{LOGLEVEL:level} %{GREEDYDATA:content}"}
}
date {
match => ["timestamp", "yyyy-MM-dd HH:mm:ss"]
}
}
output {
elasticsearch {
hosts => ["h121.wzk.icu:9200"]
index => "app-logs-%{+YYYY.MM.dd}"
}
}
Kibana
作用
Elasticsearch 可视化分析平台:
- 索引管理
- 图形化查询
- 可视化仪表盘
- 监控告警
对比 Solr
| 特性 | Elasticsearch | Solr |
|---|---|---|
| 分布式协调 | 内置 | 依赖 ZooKeeper |
| JSON 支持 | 原生 | 需要配置 |
| 实时搜索 | 优势 | 需配置近实时 |
| 文档模型 | 灵活 | 严格模式 |
排错清单
集群 Yellow/Red
症状: 集群状态为 Yellow 或 Red
根因:
- 节点离线
- 磁盘水位过高
- 分片分配失败
修复:
# 检查节点状态
curl -XGET 'h121.wzk.icu:9200/_cluster/health'
# 检查磁盘水位
curl -XGET 'h121.wzk.icu:9200/_cat/allocation?v'
# 清理磁盘或调整分片
写入被拒
症状: 写入请求被拒绝
根因:
- JVM 堆压力
- 字段爆炸
修复:
# 监控 JVM
curl -XGET 'h121.wzk.icu:9200/_nodes/jvm'
# 限制字段数
index.mapping.total_fields.limit: 1000
慢查询
症状: 查询响应时间长
根因:
- 通配符查询
- 深分页
- 未建索引
修复:
- 避免通配符开头:
*error - 使用 scroll 或 search_after 替代 from/size
- 优化查询条件
时间轴错乱
症状: 日志时间顺序混乱
根因:
- 时区未统一
- Logstash 时间解析错误
修复:
filter {
date {
match => ["timestamp", "yyyy-MM-dd HH:mm:ss"]
timezone => "Asia/Shanghai"
}
}
索引只读
症状: 索引变为 read-only
根因:
- 磁盘高水位触发(默认 85%)
修复:
# 清理磁盘或调整阈值
curl -XPUT 'h121.wzk.icu:9200/_all/_settings' -d '{"index.blocks.read_only_allow_delete": null}'
# 调整高水位线
cluster.routing.allocation.disk.threshold_enabled: true
cluster.routing.allocation.disk.watermark.low: 85%
cluster.routing.allocation.disk.watermark.high: 90%
ILM 索引生命周期管理
阶段
| 阶段 | 操作 |
|---|---|
| Hot | 频繁写入/查询 |
| Warm | 定期合并,只读 |
| Cold | 归档存储 |
| Delete | 删除 |
配置
{
"policy": {
"phases": {
"hot": {
"min_age": "0ms",
"actions": {
"rollover": {"max_age": "1d", "max_size": "50gb"}
}
},
"warm": {
"min_age": "30d",
"actions": {"forcemerge": {"max_num_segments": 1}}
},
"cold": {
"min_age": "90d",
"actions": {"freeze": {}}
},
"delete": {
"min_age": "365d",
"actions": {"delete": {}}
}
}
}
}