搜 索

ELK技术栈

  • 220阅读
  • 2022年05月18日
  • 0评论
首页 / 编程 / 正文

什么是ELK

ELK是三个开源项目的首字母缩写:

字母全称角色一句话介绍
EElasticsearch搜索引擎存数据、查数据,快得离谱
LLogstash数据管道收数据、洗数据、发数据
KKibana可视化画图表、做看板、装门面

后来官方又加了个小弟 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说明
IndexDatabase索引,一类数据的集合
DocumentRow文档,一条数据(JSON格式)
FieldColumn字段,文档中的属性
ShardPartition分片,数据水平切分
ReplicaSlave副本,高可用保障

为什么快

  • 倒排索引(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

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]

适用场景:开发测试环境、日志量 < 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]

适用场景:生产环境、日志量 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
删除]
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]
# 查看集群健康
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。


参考资料


没有日志的系统就像没有后视镜的车——能开,但迟早要出事。 🚗

评论区
暂无评论
avatar