背景&目标
近期排查一个问题时,追根溯源到最后的结论是从 ES 中查询到的数据有问题。现很多企业都会使用 ELK 架构搭建一套日志分析系统。但实际上,我对 ELK 的的理解就是一个日志系统,是个很好用的搜索引擎。支持写入日志并可以从中进行查询操作。还是需要花点时间深入学习下这其中的来龙去脉。
ELK 是什么
ELK 说的就是 Elasticsearch 、Logstash、Kibana 这三大开源框架,由它们组成一个日志分析架构,作用就是收集、分析和存储日志的。Kibana 提供可视化功能,对日志查看、搜索、分析。
- E:Elasticsearch 一个全文本搜索和分析引擎。负责数据的存储、计算、查询以及分析。
- L:Logstash 从不同来源采集数据,然后将数据进行转换,转换后将其发送到各个终端并进一步处理。所以 Logstash 是负责数据的传输和 ETL中间预处理。
- K:Kibana 上可管理 ES 的数据,监控分析工具以及可看到报表。它是一个可视化层,能够通过它对数据进行可视化和分析。
但在官网中提供了 Elastic Stack 的生态图,如下所示:
Elastic Stack 中还有一个产品 Beats ,它主要负责数据的采集和投递。
问题:Logstash 和 Beats 区别??都是采集数据的吗?
- Beats 是一个采集器平台,采集到数据再向 Logstash 或 ElasticSearch 发送数据
- Logstash 是动态数据收集管道。具有实时传输能力,将数据收集,解析,然后发送给 ES
所以,我们搭建一个基础版的日志系统:Beats + Elasticsearch + Kibana,不适合用于生产,适合练手使用。由 Beats 采集数据,存储在 ES 中,再使用 Kibana 可视化界面管理和展示。升级版本是再增加 Logstash ,Beats + Logstash + Elasticsearch + Kibana。
Logstash 的优势:
- 实时解析和转换数据
- 可扩展,且拥有 200+ 多个插件
- 可靠性:通过持久化队列保证至少一次交付的可靠传输
- 安全性:传输过程有身份验证且是加密的,无论是从 Beats 到 Logstash传输,还是从 Logstash 到 Elasticsearch的传输,都保证了安全传输
ELK 原理
了解了 Elastic Stack 各个产品的作用,下一步就是在应用过程中其整个过程都发生了什么?
- 数据来源是由应用程序产生的。在使用过程中产生日志(用户行为日志,管理日志等等)
- Logstage 收集日志并将日志格式化并输出到 Elasticsearch
- Elasticsearch 将格式化的数据进行索引和存储
- Kibana 可视化这部分数据,也提供了对 数据索引管理,统计等功能
收集&格式化数据
Logstash 能够动态的采集、转换和传输数据,不受格式或复杂度影响。它支持很多输入插件,详细可查看官网
以下以 input : File 为例子。应用程序只需记录日志,产生日志文件,这样 Logstash 仅需监听日志文件并读取文件内容即可。
进入 Logstash 服务中 config 文件下,可以新建一个配置文件 logstash-file-input.conf (以配置 input 为例子)
input
file {
path => ["/var/log/*.log", "/var/log/message"]
type => "system"
start_position => "beginning"
}
}
- path 日志文件的位置
- type 用于过滤器激活
- start_position 读取日志的位置,默认值是 "end",如果启动时需要读取旧数据则设置为 "beginning"
- 还有其他配置项,具体查看
配置完之后,通过使用命令启动 logstash:
bin/logstash -f logstash-file-input.conf
input 是配置输入源。还有 filter 过滤器,是将数据转为你指定的格式,output 输出配置,将数据输出到目标位置。
写入&存储数据
由 Logstash 数据传输到 Elasticsearch 中。由 ES 客户端来完成一系列写过程。数据写入到 ES 节点中,使用索引文件。索引文件的数据模型是 Mapping(数据结构)以及数据文件(数据内容)。
但一个节点不能存放太多索引文件。所以 ES 提供分片机制,让一个索引文件存放在不同节点的不同分片中。分片由两种类型:主分片和副分片。主分片用来处理索引写入的请求,副本分片用来存储索引数据。
Elasticsearch 基本概念:
- Cluster 集群:一个集群的名字是唯一标识。集群名字在配置文件中指定。多个 Node 节点的集群名相同说明是同一个集群。
- Node 节点:存储集群的数据,参与集群的索引和搜索功能。一个集群里有多个节点,一个节点就是一个实例。
- Index 索引:一个索引是一个稳定的集合。每个索引名称都是唯一的。一个集群中可以有任意多个索引。
- Type 类型,一个索引中,可以不同类型的文档
- Document 文档,被索引的一条数据。Document 是索引的基本信息的单元
- Shard 分片,一个索引可以划分多个分片进行存储。分片可以分散在不同的 Node 节点上
可视化
打开 Kibana 访问:http://localhost:5601
部署安装 ELK 环境
话一千道一百,都不如自己亲自动手实践一下。
本地自己使用 docker 部署一套 ELK 环境。以下主要使用 docker-compose 方式部署。
需要注意的是,如果要安装 Elastic Stack ,必须使用相同版本号。比如 ElasticSearch 使用 8.3.2 版本,那么 Beats,Logstash、Kibana 都需要使用 8.3.2的版本。
version: '3'
services:
logstash:
image: "logstash:8.3.1"
container_name: logstash
ports:
- "5000:5000"
volumes:
- "${pwd}/pipelines.yml:/usr/share/logstash/config/pipelines.yml"
- "${pwd}/logstash-audit.conf:/usr/share/logstash/pipeline/logstash-audit.conf"
- "${pwd}/logstash-file-input.conf:/usr/share/logstash/pipeline/logstash-file-input.conf"
- "${pwd}/es/authing/log:/var/log/server-log"
environment:
- "MONITORING_ENABLED=false"
- "TZ=Asia/Shanghai"
networks:
- elastic
links:
- elasticsearch
elasticsearch:
image: elasticsearch:8.3.1
container_name: elasticsearch
networks:
- elastic
environment:
- "discovery.type=single-node"
- "TZ=Asia/Shanghai"
- ES_JAVA_OPTS=-Xms1024m -Xmx1024m
privileged: true
ports:
- "9200:9200"
- "9300:9300"
kibana:
image: docker.elastic.co/kibana/kibana:8.3.1
container_name: kibana
ports:
- 5601:5601
privileged: true #环境变量
environment:
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
- I18N_LOCALE=zh-CN
networks:
- elastic
depends_on:
- elasticsearch
networks:
elastic:
driver: bridge
- networks 是建立网络 bridge。
- ${pwd} 是读取配置环境里的变量,仅需于 docker-compose.yml 同目录下新建一个 .env 文件,加入变量
pwd=/user/{your_computer_name}/Document/server/config
参考资料:
- www.elastic.co/pdf/archite…
- developer.aliyun.com/article/707…
- www.elastic.co/guide/en/lo…
- dockone.io/article/243…
我正在参与掘金技术社区创作者签约计划招募活动,点击链接报名投稿。