ELK 日志分析系统
一、ELK 各组件概述与工作原理
(一)Elasticsearch(ES)
概述:基于 Lucene 的分布式搜索与分析引擎,提供高可用、可扩展的全文搜索能力,支持分布式存储与多租户架构。
工作原理:
- 索引与分片机制
-
数据存储于索引(Index),索引拆分为多个分片(Shard),每个分片可配置副本(Replica)实现负载均衡与故障恢复。
-
主分片处理读写请求,副本分片用于冗余和扩展,搜索请求由协调节点分发至各分片并行处理后合并结果。
- 倒排索引核心
-
通过倒排索引记录词(Term)与文档的关联关系(出现位置、频率等),实现快速全文检索。
-
搜索时根据词频、位置等因素对文档进行相关性排序,提升检索效率。
- 分布式协调架构
-
集群(Cluster)通过 Zen Discovery 或云原生发现机制自动发现节点,选举主节点管理元数据(索引创建、分片分配等)。
-
数据节点存储处理数据,客户端节点转发请求,支持水平扩展与高可用性。
(二)Logstash
概述:开源数据收集与处理管道工具,支持从多数据源提取、转换、传输数据至目标存储。
工作原理(插件化架构):
- 输入(Input)
- 支持文件、syslog、TCP/UDP 等多种数据源,将原始数据转换为 Logstash 事件(Event),包含内容与元数据(时间戳、来源等)。
- 过滤(Filter)
- 通过插件解析日志(如 JSON、正则表达式提取字段)、清洗数据(去除敏感信息)、转换格式(日期格式化、字段重命名),使数据结构化。
- 输出(Output)
- 将处理后的数据输出至 Elasticsearch、文件、Kafka 等目标,支持自定义输出格式与传输协议。
(三)Kibana
概述:数据可视化与分析平台,与 Elasticsearch 深度集成,提供图表、仪表盘等可视化组件。
工作原理:
- 数据查询
- 根据用户配置生成 Elasticsearch 查询(关键词搜索、聚合分析等),获取结构化数据结果。
- 可视化渲染
- 基于 Canvas/SVG 技术渲染折线图、柱状图、饼图等,支持自定义样式、标签与交互,直观展示数据趋势。
- 仪表盘管理
- 支持创建仪表盘组合多个可视化图表,配置刷新频率、布局,实现实时监控与多维度分析。
二、ELK 协同工作流程与组件职责
(一)协同工作流程
- 数据收集(Logstash 输入)
- 从日志文件、API、消息队列等数据源实时采集原始日志,转换为 Event 格式。
- 数据处理(Logstash 过滤)
- 解析非结构化日志(如提取时间戳、日志级别),清洗敏感数据,补充环境元数据,生成规范化结构化数据。
- 存储与检索(Elasticsearch)
- 接收处理后的数据,通过分片与副本机制分布式存储,利用倒排索引快速响应查询请求(全文搜索、聚合统计)。
- 可视化分析(Kibana)
- 从 Elasticsearch 获取数据,生成可视化图表(如错误日志趋势、服务响应时间分布),支持仪表盘实时监控与交互式分析。
(二)各组件核心职责
组件 | 核心职责 |
---|---|
Logstash | 数据收集(多源接入)、格式转换(非结构化→结构化)、数据清洗与丰富,数据传输至目标存储。 |
Elasticsearch | 分布式存储海量日志,提供高速搜索(全文 / 聚合查询)、分片副本机制保障高可用性与扩展性。 |
Kibana | 数据可视化(图表、仪表盘)、交互式分析(过滤、钻取)、实时监控与报表生成,降低数据解读门槛。 |
(三)各组件优缺点对比
1. Logstash
-
优点:
-
多数据源支持(文件、数据库、网络协议等),插件生态丰富;
-
灵活的数据处理能力(解析、转换、清洗),适配复杂日志格式;
-
易于扩展,支持自定义插件开发。
-
缺点:
-
大规模数据处理时 CPU / 内存开销较高,性能瓶颈明显;
-
配置文件复杂,需掌握 DSL 语法,新手入门难度大;
-
实时性有限,处理管道存在延迟,需配合 Beats 等轻量工具优化。
2. Elasticsearch
-
优点:
-
分布式架构支持水平扩展,轻松应对 PB 级数据;
-
倒排索引实现亚秒级搜索,聚合分析能力强大;
-
丰富的 API 与客户端支持(Java、Python、RESTful),生态完善。
-
缺点:
-
资源消耗高(需大量内存用于缓存索引),硬件成本较高;
-
分布式系统复杂度高,集群管理(分片均衡、故障恢复)需专业运维;
-
数据一致性模型(近实时)在极端场景下可能出现副本延迟。
3. Kibana
-
优点:
-
零代码可视化,拖拽式操作降低使用门槛;
-
深度集成 Elasticsearch,支持实时数据可视化与仪表盘共享;
-
提供地理空间分析、日志链路追踪等高级功能。
-
缺点:
-
完全依赖 Elasticsearch,后者故障时无法独立工作;
-
复杂可视化需求(自定义图表交互)需二次开发插件;
-
大规模数据下图表加载速度受限于 ES 查询性能。
总结
ELK 栈通过 Logstash 的数据管道、Elasticsearch 的分布式存储搜索、Kibana 的可视化分析,形成完整的日志处理闭环,适用于日志监控、故障排查、业务分析等场景。实际应用中需根据数据规模、实时性要求及团队技术能力,合理配置组件(如引入 Beats 轻量采集器优化 Logstash 性能,使用 Elastic Cloud 简化集群管理),以发挥最佳效能。
三,示例
3.1主机描述
主机 | 描述 | 所需软件 |
---|---|---|
192.168.10.101 | http | http |
192.168.10.102 | Logstash | Logstash |
192.168.10.103 | elk1 | elasticsearch kibana |
192.168.10.104 | elk2 | elasticsearch |
3.2搭建Elasticsearch
在103和104上操作
注意在编辑elasticsearch.yml是两台主机名称是不一样的这个要注意哦
bash
# 编辑主机名映射文件,添加elk1和elk2的IP地址映射,用于集群节点间通信
[root@elk1 ~]# vim /etc/hosts
192.168.10.103 elk1 # 本机IP与主机名映射
192.168.10.104 elk2 # 集群另一节点IP与主机名映射
# 创建elasticsearch运行用户es
[root@elk1 ~]# useradd es
# 将es用户添加到wheel组,使其拥有sudo权限(便于执行管理员操作)
[root@elk1 ~]# gpasswd -a es wheel
# 切换到es用户(Elasticsearch不允许root用户直接运行)
[root@elk1 ~]# su - es
# 安装Java环境(Elasticsearch依赖Java运行)
[es@elk1 ~]$ sudo dnf -y install java
# 配置系统资源限制,优化Elasticsearch运行环境
[es@elk1 ~]$ sudo vim /etc/security/limits.conf
es soft nofile 65535 # es用户软限制:最大文件描述符数
es hard nofile 65535 # es用户硬限制:最大文件描述符数
es soft nproc 65535 # es用户软限制:最大进程数
es hard nproc 65535 # es用户硬限制:最大进程数
es soft memlock unlimited # es用户软限制:内存锁定(不限制)
es hard nproc unlimited # es用户硬限制:最大进程数(不限制)
# 配置内核参数,调整虚拟内存映射数量(Elasticsearch需要大量内存映射)
[es@elk1 ~]$ sudo vim /etc/sysctl.conf
vm.max_map_count=655360 # 增加虚拟内存映射数上限
# 重启系统,使上述配置生效
[es@elk1 ~]$ sudo reboot
# 重启后再次切换到es用户
[root@elk1 ~]# su - es
# 进入/opt目录(通常用于存放第三方软件)
[es@elk1 ~]$ cd /opt/
# 查看目录下的Elasticsearch安装包
[es@elk1 opt]$ ls
elasticsearch-7.10.0-linux-x86_64.tar.gz # Elasticsearch 7.10.0版本安装包
# 解压Elasticsearch安装包
[es@elk1 opt]$ sudo tar xf elasticsearch-7.10.0-linux-x86_64.tar.gz
# 将解压后的目录移动到/etc/elasticsearch(统一管理配置文件)
[es@elk1 opt]$ sudo mv elasticsearch-7.10.0 /etc/elasticsearch
# 进入Elasticsearch主目录
[es@elk1 opt]$ cd /etc/elasticsearch/
# 查看Elasticsearch目录结构
[es@elk1 elasticsearch]$ ls
bin # 可执行脚本(如启动脚本)
elasticsearch-7.10.0 # 版本标识文件
lib # 依赖库
logs # 默认日志目录(后续会被配置文件覆盖)
NOTICE.txt # 版权声明文件
README.asciidoc # 说明文档
config # 配置文件目录
jdk # 内置JDK(7.10.0版本自带)
LICENSE.txt # 许可证文件
modules # 内置模块
plugins # 插件目录
# 进入配置文件目录
[es@elk1 elasticsearch]$ cd config/
# 查看配置文件列表
[es@elk1 config]$ ls
elasticsearch.yml # 主配置文件
jvm.options.d # JVM参数配置目录
role_mapping.yml # 角色映射配置
users # 用户密码文件
jvm.options # JVM参数主配置文件
log4j2.properties # 日志配置文件
roles.yml # 角色权限配置
users_roles # 用户-角色映射文件
# 编辑JVM参数配置文件,调整堆内存大小
[es@elk1 config]$ sudo vim jvm.options
-Xms2g # JVM初始堆内存为2GB
-Xmx2g # JVM最大堆内存为2GB(建议与初始值一致,避免频繁扩容)
# 编辑Elasticsearch主配置文件
[es@elk1 config]$ sudo vim elasticsearch.yml
cluster.name: my-application # 集群名称(所有节点需一致)
node.name: elk1 ### 节点名称(需与主机名对应,唯一标识)
path.data: /path/to/data # 数据存储目录
path.logs: /path/to/logs # 日志存储目录
bootstrap.memory_lock: false # 是否锁定内存(false表示不锁定,生产环境建议设为true)
network.host: 0.0.0.0 # 监听地址(0.0.0.0表示所有网卡)
http.port: 9200 # HTTP服务端口(默认9200)
discovery.seed_hosts: ["elk1", "elk2"] # 集群发现节点列表
cluster.initial_master_nodes: ["elk1"] # 初始主节点候选列表
# 创建数据存储目录
[es@elk1 config]$ sudo mkdir -p /path/to/data
# 创建日志存储目录
[es@elk1 config]$ sudo mkdir -p /path/to/logs
# 查看/path目录权限(确认目录结构正确)
[es@elk1 config]$ ll /path
总计 4
drwxr-xr-x. 4 root root 4096 7月 2日 00:11 to # to目录(包含data和logs子目录)
# 修改数据和日志目录权限,确保es用户有读写权限
[es@elk1 config]$ sudo chown -R es:es /path/to/
# 修改Elasticsearch目录权限,确保es用户可操作
[es@elk1 config]$ sudo chown -R es:es /etc/elasticsearch/
# 后台启动Elasticsearch(&表示后台运行)
[es@elk1 config]$ /etc/elasticsearch/bin/elasticsearch &
[1] 2049 # 后台进程ID
# 检查9200端口是否被监听(确认Elasticsearch启动成功)
[es@elk1 config]$ sudo netstat -anpt | grep 9200
tcp6 0 0 :::9200 :::* LISTEN 2049/java # 9200端口被Java进程(Elasticsearch)监听
验证elasticsearch
bash
[es@elk1 config]$ sudo curl 192.168.10.103:9200/_cat/nodes
192.168.10.103 26 96 0 0.00 0.02 0.00 cdhilmrstw * elk1
192.168.10.104 18 96 0 0.00 0.02 0.00 cdhilmrstw - elk2
3.3搭建logstash
在102上操作
安装logstash
bash
# 使用dnf包管理器安装Java运行环境(Elasticsearch和logstash依赖Java)
[root@logstash ~]# dnf -y install java
# 解压Logstash安装包(使用tar命令解压tar.gz格式的压缩包)
[root@logstash ~]# tar xf logstash-7.10.0-linux-x86_64.tar.gz
# 将解压后的Logstash目录移动到/etc/logstash路径下(便于统一管理配置)
[root@logstash ~]# mv logstash-7.10.0 /etc/logstash
# 递归修改Logstash数据目录权限为777(所有用户可读可写可执行)
# 注意:生产环境不建议使用777权限,可能存在安全风险,建议使用更严格的权限设置
[root@logstash ~]# chmod -R 777 /etc/logstash/data/
测试logstash
bash
# 启动Logstash并通过命令行参数(-e)指定临时配置
# 配置说明:
# input { stdin { } }:从标准输入(键盘输入)获取数据
# output { stdout { codec => rubydebug } }:将数据通过标准输出(控制台)以rubydebug格式展示
[root@logstash ~]# /etc/logstash/bin/logstash -e 'input { stdin { } } output { stdout { codec => rubydebug } }'
### 执行完上面的命令后,在键盘上随便输入内容再按下回车,即可测试Logstash是否正常工作
# 测试结果展示(当输入"test"并回车后):
{
"message" => "test", # 输入的原始内容(这里输入的是"test")
"@version" => "1", # Logstash事件的版本号(默认值为1)
"host" => "logstash", # 产生事件的主机名(这里是运行Logstash的主机"logstash")
"@timestamp" => 2025-07-01T16:39:06.523Z # 事件被Logstash处理的时间戳(UTC时间)
}
# 以上输出表明Logstash成功接收输入数据并按配置格式输出,测试成功
3.4 logstash采集日志并交给elasticsearch
bash
# 为/var/log/messages文件添加其他用户的读权限(确保Logstash能读取系统日志)
[root@logstash ~]# chmod o+r /var/log/messages
# 进入Logstash配置文件目录
[root@logstash ~]# cd /etc/logstash/config/
# 查看当前目录下的文件(确认配置文件位置)
[root@logstash config]# ls
jvm.options # JVM参数配置文件
log4j2.properties # 日志配置文件
logstash-sample.conf # 示例配置文件
logstash.yml # Logstash主配置文件
pipelines.yml # 管道配置文件(多管道时使用)
startup.options # 启动选项配置文件
# 创建并编辑自定义的Logstash配置文件system.conf(.conf是Logstash配置文件的标准后缀)
[root@logstash config]# vim system.conf ### 自定义配置文件,用于定义日志采集规则
# 配置文件内容解析:
input{ # 输入部分:定义从哪里采集日志
file{ # 使用file插件(采集文件日志)
path=>"/var/log/messages" # 采集的目标文件路径(系统消息日志)
type=>"system" # 给日志标记类型(便于后续过滤或区分)
start_position=>"beginning" # 从文件开头开始采集(默认从末尾开始)
}
}
output{ # 输出部分:定义日志发送到哪里
elasticsearch{ # 使用elasticsearch插件(发送到Elasticsearch)
hosts=>["192.168.10.103:9200"] # Elasticsearch的地址和端口
index=>"system-%{+YYYY.MM.dd}" # 存储到ES的索引名称(按日期分割,如system-2025.07.02)
}
}
# 使用-f参数指定配置文件启动Logstash(根据system.conf的规则采集并输出日志)
[root@logstash config]# /etc/logstash/bin/logstash -f /etc/logstash/config/system.conf
3.5安装kibana
在103上安装
bash
# 使用root权限解压Kibana安装包(使用tar命令解压tar.gz格式的压缩包)
[es@elk1 opt]$ sudo tar xf kibana-7.10.0-linux-x86_64.tar.gz
# 将解压后的Kibana目录移动到/etc/kibana路径下(便于统一管理配置)
[es@elk1 opt]$ sudo mv kibana-7.10.0-linux-x86_64 /etc/kibana
# 递归修改Kibana目录的所有者为es用户和组(确保es用户有操作权限)
[es@elk1 opt]$ sudo chown -R es:es /etc/kibana/
# 进入Kibana配置文件目录
[es@elk1 opt]$ cd /etc/kibana/config/
# 查看配置文件列表(Kibana的主要配置文件是kibana.yml)
[es@elk1 config]$ ls
kibana.yml # Kibana主配置文件
node.options # Node.js运行选项配置文件
# 编辑Kibana主配置文件
[es@elk1 config]$ vim kibana.yml
# 配置文件内容解析:
server.port: 5601 # Kibana服务监听的端口(默认5601)
server.host: "0.0.0.0" # Kibana服务监听的地址(0.0.0.0表示监听所有可用接口)
elasticsearch.hosts: "http://192.168.10.103:9200" # 指定Elasticsearch的连接地址(指向之前配置的Elasticsearch服务)
i18n.locale: "zh-CN" # 设置Kibana界面语言为中文(简体)
# 后台启动Kibana服务(&表示在后台运行)
[es@elk1 config]$ /etc/kibana/bin/kibana &
[2] 2573 # 后台进程ID(Kibana服务的进程ID为2573)
客户端网页访问 http://192.168.10.103:5601查看kibana图形页面
