ES原理与Filebeat日志采集全攻略
ES原理与Filebeat日志采集全攻略
一、概述
本文全面覆盖ElasticSearch(ES)核心原理与Filebeat日志采集实战,包含ES倒排索引底层机制、节点角色分类与主从分离部署、Filebeat两种安装方式(RPM/二进制)、多类型输入插件(stdin/tcp/log)、数据处理器配置、Nginx/Tomcat/ES/Docker等多场景日志采集,以及Filebeat数据丢失故障处理方案。内容从原理到实操层层递进,命令清晰、案例丰富,助力快速掌握ES集群角色规划与日志采集标准化配置能力。
二、核心知识点
2.1 ES核心原理(底层存储与检索)
| 索引类型 | 核心定义 | 检索方式 | 适用场景 | 性能对比 |
|---|---|---|---|---|
| 正排索引(正向索引) | 按文档ID关联数据,如MySQL主键索引 | 全表扫描(无索引时) | 关系型数据库(如MySQL) | 10亿文档查询耗时久 |
| 倒排索引(反向索引) | 按词条关联文档ID,含词典+倒排表 | 词条匹配→倒排表查询→文档定位 | ES全文检索 | 10亿文档查询毫秒级响应 |
倒排索引核心组成
- 词条:最小查询单元(英文为单词,中文为词组);
- 词典:词条集合,底层基于Btree+HashMap实现,快速匹配词条;
- 倒排表:记录词条出现的文档ID、频率、位置,每条记录为倒排项。
2.2 ES节点角色分类(常用)
| 角色标识 | 角色名称 | 核心功能 | 配置参数 |
|---|---|---|---|
| m | 主节点(master node) | 维护集群状态、管理索引元数据、主分片选举 | node.master: true |
| d | 数据节点(data node) | 存储数据、执行数据读写、分片管理 | node.data: true |
| c | 协调节点(coordinating node) | 接收客户端请求、分发任务、聚合结果 | 所有节点默认是协调节点,不可取消 |
| i | 预处理节点(ingest node) | 数据写入前预处理(如过滤、转换) | node.ingest: true |
| h | 热节点(hot node) | 存储热点数据(高频读写) | 需配合索引生命周期管理(ILM) |
| w | 温节点(warm node) | 存储温数据(低频读写) | 需配合ILM |
| c | 冷节点(cold node) | 存储冷数据(只读) | 需配合ILM |
2.3 Filebeat核心概念
| 组件 | 核心作用 | 关键特性 |
|---|---|---|
| Input | 数据输入端,采集源数据 | 支持stdin/tcp/log/file等多种类型 |
| Output | 数据输出端,发送处理后的数据 | 支持console/elasticsearch/kafka等 |
| Processors | 数据处理器,预处理数据 | 支持过滤、字段修改、类型转换等 |
| Modules | 预配置模块,快速采集主流软件日志 | 内置Nginx/Tomcat/MySQL等模块 |
2.4 Filebeat Input插件类型(常用)
| 插件类型 | 适用场景 | 核心配置 |
|---|---|---|
| stdin | 标准输入测试,快速验证配置 | type: stdin |
| tcp | 采集TCP端口接收的数据 | type: tcp + host: 0.0.0.0:端口 |
| log | 采集文件日志(核心场景) | type: log + paths: 日志路径 |
2.5 Filebeat核心处理器(常用)
| 处理器类型 | 功能 | 适用场景 |
|---|---|---|
| drop_event | 丢弃符合条件的事件 | 过滤无效日志(如以linux开头的消息) |
| drop_fields | 丢弃指定字段 | 移除冗余字段(如自定义标签、临时字段) |
| rename | 重命名字段 | 规范字段名称(如school→学校) |
| convert | 转换字段类型 | 如字符串IP→ip类型、字符串端口→整数类型 |
三、步骤/命令
3.1 ES主从角色分离实战(生产推荐)
操作场景:分离主节点与数据节点,提升集群稳定性(主节点专注集群管理,数据节点专注数据存储)
# 前提:已部署3节点ES集群(elk101/102/103),当前为混合角色
# 1. 所有节点停止ES服务
⭐️systemctl stop es7
# 2. 所有节点清空历史数据(避免角色切换冲突)
rm -rf /oldboya/{data,logs}/es7/* /tmp/*
# 3. 分别修改各节点配置文件
# 3.1 数据节点(elk101/102):仅开启data角色,关闭master角色
cat > /oldboya/softwares/es7/elasticsearch-7.17.5/config/elasticsearch.yml << EOF
cluster.name: oldboya-linux85-binary
path.data: /oldboya/data/es7
path.logs: /oldboya/logs/es7
network.host: 0.0.0.0
discovery.seed_hosts: ["elk101.oldboya.com","elk102.oldboya.com","elk103.oldboya.com"]
cluster.initial_master_nodes: ["elk103.oldboya.com"] # 指定主节点候选
node.master: false # 关闭master角色
node.data: true # 开启data角色
EOF
# 3.2 主节点(elk103):仅开启master角色,关闭data角色
cat > /oldboya/softwares/es7/elasticsearch-7.17.5/config/elasticsearch.yml << EOF
cluster.name: oldboya-linux85-binary
path.data: /oldboya/data/es7
path.logs: /oldboya/logs/es7
network.host: 0.0.0.0
discovery.seed_hosts: ["elk101.oldboya.com","elk102.oldboya.com","elk103.oldboya.com"]
cluster.initial_master_nodes: ["elk103.oldboya.com"]
node.master: true # 开启master角色
node.data: false # 关闭data角色
EOF
# 4. 所有节点启动ES服务
systemctl start es7
# 5. 效果验证(查看节点角色)
⭐️curl 10.0.0.101:9200/_cat/nodes
# 输出说明:elk103标识含"m"(主节点),不含"d"(非数据节点);elk101/102含"d"(数据节点),不含"m"
# 6. 创建索引测试(验证主节点不存储分片)
curl -X PUT 10.0.0.101:9200/oldboya-linux85 -H "Content-Type: application/json" -d '{
"settings":{
"number_of_shards": 10,
"number_of_replicas":0
}
}'
# 验证分片分配:主节点(elk103)无分片,分片仅分配在elk101/102
curl 10.0.0.101:9200/_cat/shards/oldboya-linux85
3.2 Filebeat安装(RPM/二进制)
3.2.1 RPM安装(快速部署)
# 1. 下载Filebeat RPM包(与ES版本一致:7.17.5)
⭐️wget http://192.168.15.253/ElasticStack/day04-/filebeat-7.17.5-x86_64.rpm
# 2. 安装Filebeat
rpm -ivh filebeat-7.17.5-x86_64.rpm # -i:安装,-v:显示过程,-h:进度条
# 3. 效果验证(查看帮助文档)
filebeat -h # 输出帮助信息即为安装成功
3.2.2 二进制安装(自定义路径,生产推荐)
# 1. 下载Filebeat二进制包
wget http://192.168.15.253/ElasticStack/day04-/filebeat-7.17.5-linux-x86_64.tar.gz
# 2. 解压到自定义目录
⭐️tar xf filebeat-7.17.5-linux-x86_64.tar.gz -C /oldboya/softwares/
# 3. 创建软链接(方便全局调用)
ln -svf /oldboya/softwares/filebeat-7.17.5-linux-x86_64/filebeat /usr/local/sbin/
# 4. 效果验证
filebeat -h # 输出帮助信息即为安装成功
3.3 Filebeat Input插件实操
3.3.1 标准输入(stdin)→ 控制台输出
操作场景:快速验证Filebeat配置是否生效
# 1. 创建配置文件(二进制安装路径为例)
cd /oldboya/softwares/filebeat-7.17.5-linux-x86_64
mkdir -p config
⭐️cat > config/01-stdin-to-console.yaml << EOF
filebeat.inputs:
- type: stdin # 输入类型:标准输入
output.console:
pretty: true # 格式化输出,便于查看
EOF
# 2. 启动Filebeat
filebeat -e -c config/01-stdin-to-console.yaml # -e:日志输出到控制台,-c:指定配置文件
# 3. 效果验证
# 在启动后的终端输入任意内容(如"test filebeat stdin input"),控制台会输出格式化的日志数据
3.3.2 TCP输入 → 控制台输出
操作场景:采集TCP端口接收的日志数据
# 1. 创建配置文件
cat > config/02-tcp-to-console.yaml << EOF
filebeat.inputs:
- type: tcp
host: 0.0.0.0:8888 # 监听所有网卡的8888端口
output.console:
pretty: true
EOF
# 2. 启动Filebeat
filebeat -e -c config/02-tcp-to-console.yaml
# 3. 客户端测试(另一台节点执行)
# 3.1 安装测试工具
yum -y install nc telnet
# 3.2 发送测试数据
echo "Filebeat TCP input test" | nc 10.0.0.103 8888 # 10.0.0.103为Filebeat部署节点IP
# 4. 效果验证:Filebeat控制台会输出接收到的TCP数据
3.3.3 日志文件(log)→ 控制台输出
操作场景:采集指定路径的日志文件(支持递归匹配)
# 1. 创建配置文件
cat > config/03-log-to-console.yaml << EOF
filebeat.inputs:
- type: log
paths:
- /tmp/oldboya-linux85/*.log # 匹配/tmp下的.log文件
- /tmp/oldboya-linux85/**/*.json # 递归匹配所有子目录的.json文件
output.console:
pretty: true
EOF
# 2. 启动Filebeat
filebeat -e -c config/03-log-to-console.yaml
# 3. 测试数据(创建测试日志)
mkdir -p /tmp/oldboya-linux85
echo '{"message":"test log input","time":"2024-01-01 10:00:00"}' > /tmp/oldboya-linux85/test.log
# 4. 效果验证:Filebeat控制台会输出解析后的日志数据
3.4 Filebeat处理器配置(数据预处理)
操作场景:对采集的TCP数据进行标签添加、字段转换、过滤
# 1. 创建配置文件
⭐️cat > config/04-input-common-options.yaml << EOF
filebeat.inputs:
- type: tcp
enabled: true
host: "0.0.0.0:8888"
tags: ["jiaoshi05","linux85","oldboya"] # 添加标签字段
fields: # 自定义字段
school: oldboya
class: linux85
ip: 219.141.136.10
port: 13306
fields_under_root: true # 自定义字段提升为顶级字段(默认在fields下)
processors:
# 丢弃以"linux"开头的消息
- drop_event:
when:
regexp:
message: "^linux"
# 消息含"error"时,丢弃class和tags字段
- drop_fields:
when:
contains:
message: "error"
fields: ["class","tags"]
ignore_missing: false # 字段不存在时报错(默认true忽略)
# 重命名字段
- rename:
fields:
- from: "school"
to: "学校"
- from: "log"
to: "日志"
# 转换字段类型(ip→ip类型,port→整数类型)
- convert:
fields:
- {from: "ip", to: "oldboya-linux85.jiaoshi07_ip", type: "ip"}
- {from: "port", to: "oldboya-linux85.jiaoshi07_port", type: "integer"}
output.console:
pretty: true
EOF
# 2. 启动Filebeat
filebeat -e -c config/04-input-common-options.yaml
# 3. 测试验证
# 3.1 发送以"linux"开头的消息(会被丢弃)
echo "linux test drop event" | nc 10.0.0.103 8888
# 3.2 发送含"error"的消息(class和tags字段被丢弃)
echo "test error drop fields" | nc 10.0.0.103 8888
# 3.3 发送正常消息(字段重命名和类型转换生效)
echo "test processor success" | nc 10.0.0.103 8888
3.5 多场景日志采集实战
3.5.1 采集Nginx日志(JSON格式)
# 1. 搭建Nginx环境(若未安装)
# 1.1 添加Nginx YUM源
cat > /etc/yum.repos.d/nginx.repo <<'EOF'
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
EOF
# 1.2 安装并启动Nginx
yum -y install nginx
systemctl start nginx
# 1.3 配置Nginx输出JSON格式日志
⭐️vim /etc/nginx/nginx.conf
# 注释原有log_format,添加JSON格式配置
log_format oldboya_nginx_json '{"@timestamp":"$time_iso8601",'
'"host":"$server_addr",'
'"clientip":"$remote_addr",'
'"SendBytes":$body_bytes_sent,'
'"responsetime":$request_time,'
'"upstreamtime":"$upstream_response_time",'
'"upstreamhost":"$upstream_addr",'
'"http_host":"$host",'
'"uri":"$uri",'
'"domain":"$host",'
'"xff":"$http_x_forwarded_for",'
'"referer":"$http_referer",'
'"tcp_xff":"$proxy_protocol_addr",'
'"http_user_agent":"$http_user_agent",'
'"status":"$status"}';
access_log /var/log/nginx/access.log oldboya_nginx_json;
# 1.4 热加载Nginx配置
systemctl reload nginx
> /var/log/nginx/access.log # 清空原有日志
# 2. 创建Filebeat配置文件
cat > config/07-nginx-json-to-console.yaml << EOF
filebeat.inputs:
- type: log
paths:
- /var/log/nginx/access.log*
json.keys_under_root: true # JSON字段提升为顶级字段
json.add_error_key: true # 解析失败时添加error字段
output.console:
pretty: true
EOF
# 3. 启动Filebeat并测试
filebeat -e -c config/07-nginx-json-to-console.yaml
# 访问Nginx生成日志
curl http://10.0.0.103/
# 效果验证:Filebeat控制台输出解析后的JSON格式Nginx日志
3.5.2 采集Tomcat日志(访问日志+错误日志多行匹配)
# 1. 搭建Tomcat环境
# 1.1 下载并解压Tomcat
wget http://192.168.15.253/ElasticStack/day04-/apache-tomcat-9.0.73.tar.gz
tar xf apache-tomcat-9.0.73.tar.gz -C /oldboya/softwares/
# 1.2 配置Tomcat输出JSON格式访问日志
⭐️vim /oldboya/softwares/apache-tomcat-9.0.73/conf/server.xml
# 修改Host节点配置(约133-149行)
<Host name="tomcat.oldboya.com" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="tomcat.oldboya.com_access_log" suffix=".txt"
pattern="{"clientip":"%h","ClientUser":"%l","authenticated":"%u","AccessTime":"%t","request":"%r","status":"%s","SendBytes":"%b","Query?string":"%q","partner":"%{Referer}i","http_user_agent":"%{User-Agent}i"}"/>
</Host>
# 1.3 配置环境变量并启动Tomcat
cat > /etc/profile.d/tomcat.sh <<EOF
export TOMCAT_HOME=/oldboya/softwares/apache-tomcat-9.0.73
export PATH=\$PATH:\$TOMCAT_HOME/bin
EOF
source /etc/profile.d/tomcat.sh
catalina.sh start
# 2. 采集Tomcat访问日志(JSON格式)
cat > config/08-tomcat-access-to-console.yaml << EOF
filebeat.inputs:
- type: log
paths:
- /oldboya/softwares/apache-tomcat-9.0.73/logs/tomcat.oldboya.com_access_log*.txt
json.keys_under_root: true
json.add_error_key: true
output.console:
pretty: true
EOF
filebeat -e -c config/08-tomcat-access-to-console.yaml
# 3. 采集Tomcat错误日志(多行匹配,合并堆栈信息)
⭐️cat > config/09-tomcat-error-to-es.yaml << EOF
filebeat.inputs:
- type: log
paths:
- /oldboya/softwares/apache-tomcat-9.0.73/logs/catalina*
# 多行匹配配置:合并以非数字开头的行(堆栈信息)
multiline.type: pattern
multiline.pattern: '^\d{2}' # 匹配以两位数字开头的行(日志时间)
multiline.negate: true # 否定匹配(非数字开头的行)
multiline.match: after # 合并到上一行之后
output.elasticsearch:
hosts: ["http://10.0.0.101:9200","http://10.0.0.102:9200","http://10.0.0.103:9200"]
EOF
# 4. 启动Filebeat并验证
filebeat -e -c config/09-tomcat-error-to-es.yaml
# 效果验证:ES中会创建filebeat索引,包含合并后的Tomcat错误日志
curl 10.0.0.101:9200/_cat/indices?v | grep filebeat
3.5.3 采集ES启动日志并写入ES
# 1. 创建Filebeat配置文件
cat > config/10-es-log-to-es.yaml << EOF
filebeat.inputs:
- type: log
paths:
- /oldboya/logs/es7/elasticsearch.log* # ES日志路径
tags: ["es-log","elk-cluster"]
output.elasticsearch:
hosts: ["http://10.0.0.101:9200","http://10.0.0.102:9200","http://10.0.0.103:9200"]
index: "es-logs-%{+yyyy.MM.dd}" # 按日期拆分索引
EOF
# 2. 启动Filebeat
filebeat -e -c config/10-es-log-to-es.yaml
# 3. 效果验证
curl 10.0.0.101:9200/_cat/indices?v | grep es-logs-$(date +%Y.%m.%d)
3.6 Filebeat数据丢失故障处理
故障案例:Filebeat崩溃导致4-5点数据未采集
现象:Filebeat在16:00崩溃,16:00-17:00的日志未采集到ES,仅存16点前和17点后的数据。
原因:Filebeat崩溃后停止日志采集,源日志文件未丢失,可通过重新读取日志文件恢复数据。
解决方案:
# 1. 修复Filebeat故障(如重启服务、修复配置)
systemctl restart filebeat # RPM安装
# 或二进制安装:pkill filebeat && filebeat -e -c 配置文件
# 2. 配置Filebeat重新读取历史日志(启用回溯采集)
⭐️cat > config/11-recover-logs.yaml << EOF
filebeat.inputs:
- type: log
paths:
- /var/log/nginx/access.log* # 源日志文件路径
ignore_older: 24h # 读取24小时内的日志(覆盖丢失时段)
scan_frequency: 10s # 扫描频率
harvester_limit: 1000 # 最大并发采集数
output.elasticsearch:
hosts: ["http://10.0.0.101:9200"]
index: "nginx-recover-logs-%{+yyyy.MM.dd}"
EOF
# 3. 启动Filebeat执行数据恢复
filebeat -e -c config/11-recover-logs.yaml
# 4. 验证恢复结果
curl 10.0.0.101:9200/nginx-recover-logs-$(date +%Y.%m.%d)/_search -H "Content-Type: application/json" -d '{
"query": {
"range": {
"@timestamp": {
"gte": "2024-01-01T16:00:00",
"lte": "2024-01-01T17:00:00"
}
}
}
}'
四、原理说明
4.1 倒排索引工作机制
倒排索引是ES实现快速全文检索的核心,工作流程分为“索引构建”和“检索”两步:
- 索引构建:
- 对文档内容进行分词,提取词条(如“我爱Linux”分词为“我”“爱”“Linux”);
- 将词条存入词典(Btree+HashMap),建立词条与倒排表的映射;
- 记录每个词条在文档中的位置、频率,生成倒排项,组成倒排表。
- 检索流程:
- 用户输入查询词,分词后匹配词典中的词条;
- 若词条存在,获取对应的倒排表,得到包含该词条的文档ID;
- 按词条频率、位置计算文档相关性得分,返回排序后的结果。
4.2 ES文档读写流程
文档写入流程:
- 客户端请求发送到协调节点;
- 协调节点通过
hash(文档ID) % 主分片数计算目标主分片; - 协调节点将请求转发到目标主分片所在的数据节点;
- 主分片写入数据并同步到所有副本分片;
- 所有副本分片写入成功后,主分片返回成功响应给协调节点,再由协调节点返回给客户端。
文档读取流程:
- 客户端请求发送到协调节点;
- 协调节点计算目标主分片,随机选择一个主分片或副本分片作为读取节点;
- 读取节点返回数据给协调节点;
- 协调节点返回数据给客户端(若需聚合,协调节点会汇总所有分片数据后返回)。
4.3 Filebeat日志采集原理
Filebeat通过“采集器(Harvester)”和“ prospector”实现日志采集:
- Prospector:扫描配置的日志路径,发现新文件并为每个文件启动一个Harvester;
- Harvester:打开文件句柄,逐行读取日志内容,发送到输出端;
- 状态持久化:Filebeat会记录每个文件的读取位置(offset),存储在
data/registry目录,重启后可从上次位置继续读取,避免重复采集; - 多行匹配原理:通过
pattern匹配日志起始行,将非起始行合并到上一行,解决错误日志堆栈信息拆分问题(如Tomcat错误日志的多行堆栈)。
4.4 Filebeat处理器工作原理
Processors是Filebeat的数据预处理模块,在数据从Input到Output的传输过程中执行操作,核心原理:
- 数据按处理器配置的顺序依次处理(如先过滤再转换);
- 每个处理器独立工作,修改后的字段会传递给下一个处理器;
- 处理器仅修改内存中的数据,不改变源日志文件;
- 支持条件判断(
when),仅对符合条件的事件执行处理操作,提升效率。
五、注意事项
- ES角色分离配置:主节点建议单独部署,避免数据节点负载过高影响集群稳定性;生产环境主节点至少配置2个(候选主节点),防止单点故障;
- Filebeat配置语法:YAML配置严格区分缩进(建议2空格),字符串含特殊字符需加引号,避免语法错误;
- 日志路径配置:使用
paths时,避免配置过大的目录(如/var/log/*),建议精准匹配(如/var/log/nginx/access.log*),提升扫描效率; - 多行匹配规则:
pattern需精准匹配日志起始行(如Tomcat错误日志以日期开头),否则会导致日志合并异常; - 数据去重:Filebeat依赖
registry文件记录读取位置,若删除该文件,会导致日志重复采集,生产环境需备份data/registry目录; - 性能优化:采集大量日志时,可增加
harvester_limit(并发采集数)、worker(输出线程数),避免队列阻塞; - JSON日志解析:确保源日志为标准JSON格式,否则
json.keys_under_root: true会解析失败,需启用json.add_error_key: true排查错误; - 权限控制:Filebeat需拥有日志文件的读取权限,若日志文件权限为600(root仅读),需配置
filebeat.yml中的user: root(RPM安装)或使用sudo启动(二进制安装)。
六、结尾
总结
本文核心覆盖两大模块:一是ES底层原理与集群配置,包括倒排索引机制、节点角色分类、主从分离部署,为日志存储与检索提供基础;二是Filebeat日志采集实战,涵盖两种安装方式、多类型输入插件、数据处理器配置,以及Nginx/Tomcat/ES/Docker等主流场景的日志采集方案,同时包含数据丢失故障的恢复方法。通过“原理+实操”的组合,形成了从日志采集、传输到存储的完整链路解决方案,可直接应用于生产环境的ELK/EFK架构搭建。
避坑指南(核心坑点+解决方案)
- 坑点:ES主从分离后,主节点无法选举;解决方案:确保
cluster.initial_master_nodes配置的节点node.master: true,且所有节点的cluster.name一致,关闭防火墙或开放9300端口; - 坑点:Filebeat采集不到日志,无报错;解决方案:检查日志路径是否正确、Filebeat是否有读取权限、日志文件是否被
ignore_older过滤(默认72小时); - 坑点:Tomcat错误日志被拆分为多行,无法查看完整堆栈;解决方案:配置
multiline参数,精准匹配日志起始行,合并非起始行; - 坑点:JSON日志解析后字段缺失;解决方案:启用
json.add_error_key: true,查看error字段排查JSON格式错误(如引号不匹配、逗号缺失); - 坑点:Filebeat重启后重复采集日志;解决方案:避免删除
data/registry目录,若需重新采集,可通过clean_inactive参数清理过期状态; - 坑点:ES索引分片仅分配在部分数据节点;解决方案:检查数据节点的
node.data: true配置,确保节点正常加入集群,且磁盘空间充足(磁盘使用率超过85%会停止分配分片)。

浙公网安备 33010602011771号