ELK原理详解
1.ELK介绍
ELK是三个开源软件的缩写,分别为:Elasticsearch、Logstash、Kibana,后面还有一个fileBeat,它是一个轻量级的日志收集处理(Agent),FileBeat占用的资源很少,适合在各个服务器上收集日志后传输给Logstash。
Elasticsearch是基于Lucene全文检索引擎框架,基于Java语言编写,是一个开源的分布式收缩引擎,提供收集、分析、存储数据三大功能,特点是:分布式、零配置、自动发现、索引自动分片,索引副本机制,restful风格接口,多数据源,自动搜索负载等。
Logstash是主要用来对日志进行收集、分析、过滤的,支持大量的数据获取方式。一般工作方式是C/S架构,client端安装在需要收集日志的主机上,server端负责将收到的各个节点日志进行过滤、修改操作在一并发往elasticsearchss上。ELK官网:https://www.elastic.co/
Kibana也是开源免费的工具,Kibana可以给Elasticsearch和Logstash提供很好的web界面,可以帮助汇总、分析和搜索重要的数据日志。
FileBeat属于Beats,是一个轻量型的日志采集器,早期的ELK架构中使用的是Logstash进行收集、解析并且过滤日志,但是Logstash对CPU、内存、IO等资源的消耗过高,相比于Logstash,Beats所占用的CPU和内存几乎可以忽略不记。目前Beats包括:Packagebeat(搜索网络流量数据)、Topbeat(搜集系统、进程和文件系统级别的CPU和内存使用情况等数据)、Filebeat(搜集文件数据)、Winlogbeat(搜集Windows事件日志数据)。
Logstash和Elasticsearch是用JAVA语言进行编写的,而Kibana使用的是node.js框架,在配置ELK环境时要保证系统又JAV JDK开发库。
2. 为什么要用ELK
在规模较大也就是日志量多而复杂的场景中,如果直接在日志文件中grep、awk获得自己想要的信息,那么效率就会很低下,而且也面临着包括日志量太大如何进行归档、文本搜索太慢、如何多维度进行查询等问题。这时候需要集中化的日志管理,所有服务器上的日志搜集进行汇总。常见的解决思路是建立集中式的日志搜集系统,将所有的节点上的日志进行统一的收集、管理、访问。大型的系统通常都是分布式部署的架构,不同的服务模块部署在不同的机器上,如果问题出现,那么大部分情况需要根据问题暴漏的关键信息,定位到具体的服务器和服务的模块,构建一套集中式的日志系统,可以提高定位问题的效率。一个完整的集中式日志系统,需要包括以下几个主要的特点:
- 收集:能够采集多种来源的日志数据
- 传输:能够稳定的把日志数据传输到中央系统
- 存储:如何存储日志数据
- 分析:可以至此UI分析
- 警告:能够提供错误报告,监控机制
ELK可以提供一整套的解决方案,并且都是开源的软件,之间相互配合使用,完美衔接,高效的满足了很多场合的使用。也是当前主流的一种日志系统。
3.ELK架构图
3.1 架构一
如果没有使用filebeat,logstash搜集日志,进行过滤处理,并将 数据发送到elasticsearch的架构图如下:
这是最简单的一种ELK架构方式,优点时搭建简单,容易上手,缺点是Logstash消耗的资源比较大,运行占用的CPU和内存很高,另外也没有消息队列缓存,存在数据丢失的隐患。此架构由Logstash分布于各个节点上搜集相关日志、数据,并经过分析、过滤后发送给远端服务器上的Elasticsearch进行存储。Elasticsearch将数据以分片的形式压缩存储并提供多种API供用户查询,操作。用户亦可以更直观的通过配置Kibana Web方便的对日志查询,并根据数据生成报表。
3.2 架构二
这种架构加入了消息队列机制,位于各个节点上的Logstash Agent首先将数据/日志传输给Kafka(或者Redis),并将队列中消息或数据间接传递给Logstash,Logstash过滤分析之后将数据传输给Elasticsearch进行存储,最后再由Kibana将日志和数据呈现给用户,而正是因为引入了Kafka(或者redis),才使得远端的Logstash server因为故障停止运行之后,数据会先被存储下来,从而避免数据的丢失。
3.3架构三
这种架构将收集日志端换成了beats,这样会更灵活,消耗资源会更少,扩展性也会更强。同时也可以配置Logstash和Elasticsearch集群用于支持大集群系统的运维日志数据监控和查询。
4.FileBeat的工作原理
filebeat由两个主要组件组成:prospectors和harvesters。这两个组件协同工作将文件变动发送到指定的输出中。
Haverster(收割机):负责读取单个文件的内容。每个文件会启动一个Haverster,每个Haverster会逐行读取各个文件,并将文件内容发送到制定的输出中。Haverster负责打开和关闭文件,意味着Haverster运行的时候,文件描述符处于打开的状态,如果文件在收集中被重命名或者是被删除,Filebeat会继续读取此文件。所以在Haverster关闭之前,磁盘是不会被释放的。默认情况下filebeat会保持文件打开状态,直到达到close_inactive(如果此选项打开,filebeat会在指定的时间内将不会再更新的文件句柄关闭,时间从haverster读取最后一行的时间开始计时。如果文件句柄被关闭后,文件发生了变化,就会启动一个新的Haverster。关闭文件句柄的时间不取决于文件的修改时间,如果这个参数配置不合适,就有可能发生日志不实的情况,由scan_frequency参数所决定,默认是10s.Haverster使用内部时间戳来记录文件最后被搜集的时间。例如:设置5m则在Harvester读取文件的最后一行之后,开始倒计时5分钟,若5分钟内文件无变化,则关闭文件句柄。默认5m)
prospector(勘探者):负责管理Haverster并找到所有读取源。
filebeat.prospectors: - input_type: log path: - /data/xxx.log
prospector会找到/data/下的所有log文件,并为每一个文件启动一个Haverster。prospector会检查每个文件,看Haverster是否已经启动,是否需要启动,或者文件是否可以忽略。如果Haverster关闭,只有在文件大小发生变化的时候Prospector才会执行检查。只能检查本地文件。
filebeat如何记录文件的状态:
将文件状态记录在文件中,默认是在/var/lib/filebeat/registry。此状态可以记住Haverster搜集文件的偏移量,若连接不上输出设备,如ES等,filebeat会记录发送前的最后一行,并再可以连接的时候继续发送。Filebeat在运行的时候,Prospector状态会被记录在内存中。Filebeat重启的时候,利用registry记录的状态来进行重建,用来还原到重启之前的状态。每个Prospector会为每个找到的文件记录一个状态,对于每个文件,Filebeat存储唯一标识符以检测文件是否先前被收集。
Filebeat如何保证事件至少被输出一次:
Filebeat之所以能保证事件至少被传递到配置的输出一次,没有数据丢失,是因为filebeat将每个事件的传递状态保存在文件中。在未得到输出方确认时,filebeat会尝试一直发送,直到得到回应。若filebeat在传输过程中被关闭,则不会再关闭之前确认所有时事件。任何在filebeat关闭之前为确认的时间,都会在filebeat重启之后重新发送。这可确保至少发送一次,但有可能会重复。可通过设置shutdown_timeout
参数来设置关闭之前的等待事件回应的时间(默认禁用)。
5. Logstash工作原理
Logstash事件处理有三个阶段:inputs → filters → outputs。是一个接收,处理,转发日志的工具。支持系统日志,webserver日志,错误日志,应用日志,总之包括所有可以抛出来的日志类型。
Input:输入数据到logstash:
一些常用的输入为:
- file:从文件系统的文件中读取,类似于tail -f命令
- syslog:在514端口上监听系统日志消息,并根据RFC3164标准进行解析
- redis:从redis service中读取
- beats:从filebeat中读取
Filters:数据中间处理,对数据进行操作:
一些常用的过滤器为:
- grok:解析任意文本数据,Grok是Logstash最重要的插件。它的主要作用就是将文本格式的字符串,转换成为具体的结构化的数据,配合正则表达式使用。
- 官方提供的grok表达式:https://github.com/logstash-plugins/logstash-patterns-core/tree/master/patterns
- grok在线调试:https://grokdebug.herokuapp.com/
- mutate:对字段进行转换。例如对字段进行删除、替换、修改、重命名等。
- drop:丢弃一部分events不进行处理。
- clone:拷贝 event,这个过程中也可以添加或移除字段。
- geoip:添加地理信息(为前台kibana图形化展示使用)
Outputs:outputs是logstash处理管道的最末端组件
一个event可以在处理过程中经过多重输出,但是一旦所有的outputs都执行结束,这个event也就完成生命周期。
一些常见的outputs为:
- elasticsearch:可以高效的保存数据,并且能够方便和简单的进行查询。
- file:将event数据保存到文件中。
- graphite:将event数据发送到图形化组件中,一个很流行的开源存储图形化展示的组件。
Codecs:codecs 是基于数据流的过滤器,它可以作为input,output的一部分配置。
Codecs可以帮助你轻松的分割发送过来已经被序列化的数据。
一些常见的codecs:
- json:使用json格式对数据进行编码/解码。
- multiline:将汇多个事件中数据汇总为一个单一的行。比如:java异常信息和堆栈信息。