腾讯技术课|基于Elastic Stack 搭建日志分析平台
随着互联网、物联网的飞速发展,软硬件系统架构变得越来越复杂,分析各种系统产生的日志也变得越来越困难。在日志分析过程中,相信大部分同学会碰到以下问题:
1. 定位问题耗费大量时间 通常一个系统的各模块是分散在各个机器上的,定位问题时运维同学只能逐台登录机器查看日志。特别是分布式系统,需要逐个模块查日志,流程比较繁琐,也浪费大量的时间。
2. 定位到问题日志后,难以过滤有效信息 日志是以普通文本的形式存储的,尤其生产环境的系统会打印很多冗余日志。在错误信息的上下文中,查找与问题相关的日志时,只能通过一些简单的less、grep等命令来做过滤,效率比较低。而且过滤出来的结果集也未必完全符合预期,分析起来比较困难。
3. 日志量大,容易被删除 前面提到,生产环境的系统为了在故障时提供更多的信息,往往会打印比较多的冗余日志,占用过多的本机存储空间,侵占业务可以使用的资源。 机器故障无法登录时,也无法查看日志。
以上问题,Elastic Stack都可以解决! 本次课程就主要分享下怎样通过Elastic Stack解决日志分析碰到的各种问题。
Elastic Stack架构
Elastic Stack由四个组件组成,分别是Beats、Logstash、Elasticsearch、Kibana。它们提供了日志采集、清洗、存储、可视化的能力,是一个比较完备的架构。
1. Beats:是一组工具集,一些轻量的数据采集器。 需要把他们安装在生产环境的各个机器上,他们采集了本机日志后,向Logstash或Elasticsearch发送数据。
2. Logstash:动态数据收集管道,负责数据的清洗、格式化、添加附属信息等。 Logstash的功能是很强大的,它支持从多种系统中收集数据,又可以把数据推送到各种系统里。
3. Elasticsearch:是一种分布式搜索引擎,数据的存储、查询都集中在这里。 它本身有较为强大的集群管理功能,支持水平扩展。 数据多分片、多副本存储,即提供高并发的写入查询能力,又能保证数据可靠性。
4. Kibana:数据可视化平台 支持各种丰富的图表,可以直观的呈现日志数据。 也提供了易用的搜索界面,简化问题定位过程。
从Elastic Stack的架构出发,可以看出它具备以下能力:
1. 提供了完整的解决方案,包括日志采集、清洗、存储、可视化的完整工具链。 没有外部依赖,整个日志分析系统的架构比较简单。 功能完备,日志分析领域里的需求基本都覆盖了。
2. 强大的分析能力 Elastic Stack即有能力将普通文本格式化成json结构存储,又提供了丰富的查询、聚合接口,便于统计分析。 也支持全文索引、模糊匹配、中文分词等能力,这对于定位问题是非常有用的。
3. 可靠的分布式存储 存储核心Elasticsearch是一个分布式的存储系统,可以弹性伸缩(水平扩展),多副本存储保证数据可靠性,并且自身有比较完备的集群管理能力,简单易用。
使用Elastic Stack做日志分析
前面主要介绍了Elastic Stack的架构和基本能力,后面着重分享怎样使用Elastic Stack做日志分析。主要使用三个组件:
1. Elasticsearch,主要负责日志的清洗、存储、查询。
2. Filebeat,日志的采集工具,是Beats家族中的一员,顾名思义是用来采集文本文件内容的。
3. Kibana,主要提供数据可视化的能力。
Elastic Stack的架构中,有四个组件,本次课程去掉了Logstash。原因是虽然它功能强大,但是资源消耗也比较高,很容易成为整个系统的性能瓶颈。它数据日志格式化的能力,通过Elasticsearch的数据预处理模块替代。这样有助于精简架构、提整体的高性能。
中间的这张图是本次课程的架构方案,也代表了日志数据流动的过程,从左到右分别经过Beats(也就是Filebeat)、Elasticsearch和Kibana。但是为了便于大家理解,后面的课程会先介绍Elasticsearch,因为他是整个架构的核心,然后再介绍日志采集器Filebeat,最后介绍可视化工具Kibana。
经过本次课程,大家能了解到怎样把纯文本的日志文件变为格式化的数据,以及怎样通过kibana快速搜索到有效信息,或者把日志数据转变为可视化的图表。
Elasticsearch简介
第一部分来介绍Elasticsearch,后续称之为ES。在Elastic Stack的中它处于中心位置,是数据存储的核心,所以也是最重要的部分。
这里会带大家了解下ES的总体架构和负责日志清洗功能的Ingest Pipeline。
ES的数据模型分为几个层级,Index、Type、Document。这张图把这几个层级和传统关系型数据库中的相关概念做了类比,便于大家理解。
Index:类似于关系型数据库的Database或Table,用于对数据做最上层的分类。我们可以把不同模块产生的日志,存放在不同的Index中。
Type:类似于关系型数据库中Table的概念,这里和上面Index的概念有些重复。因此6.0以后的ES版本中,一个Index只能存在一个Type了,7.0以后的版本会取消对Type的支持。在使用ES时,不要再指定多个Type,数据分类完全通过Index划分即可。
Document:类似于关系型数据库中Row的概念,也就是一行数据。ES里的每个Document是一个Json格式的结构体,可以有多个字段,存放不同的信息。
还有一个单独的概念是Mapping,类比于关系型数据库中的schema,用于指定每个字段的数据类型。通常情况下,ES是Schema free的。只有碰到特殊类型的字段,比如ES默认无法识别的Date(时间)类型的字段、不需要分词的String类型字段时,才需要指定Mapping。本次课程中,将不涉及这个概念,我们使用ES默认生成的Mapping即可。
上面讲的Index是一个逻辑上的概念,它从命名空间的维度把ES里存储的数据做了分类(也就是分表),同一类的数据放在同一个Index中。
而实际存储时,一个Index的数据会分布在多个分片上(称之为shard),每个shard承载一个Index的一部分数据。而每个分片又可以有多个副本,其中一个是主副本,称之为primary,其他是从副本,称之为replica。
图中有两个Index,Index1和Index2. 其中Index1 有两个Primary Shard,P1和P2. 每个Primary Shard又有两个副本,比如P1的两个R1副本。
至此大家理解了Index和Shard的关系,以及Primary、Replica的概念。
ES本身又是一个多节点的分布式集群,shard被打散后分布在各个node上。不同的node可以分布在不同的机器上。
而且ES默认同一个shard的primary和replica不会同时存在于同一个Node上,这样即使某个Node故障脱离集群,也可以保证不丢数据,因为集群中还有另一个副本在。
图中的P1和两个R1,分别分布在三个Node(Node1,Node2,Node3)上,它们所承载的数据是一模一样的。当Node1、Node2同时故障宕机时,ES集群里仍然有一个R1存在,不会影响数据的读写服务,更不会丢数据。
由ES的分布式架构,可以总结ES的一些优点:
高性能
o 分布式搜索引擎,可线性扩展提升系统性能
o 多个shard分摊压力,高并发写入、查询
高可靠
o 多副本存储,节点故障不丢数据
o 基架、机房感知,可以设置同一个shard的副本分配到不同的机房里,避免机房故障导致数据丢失,达到主从容灾的效果
易管理
o 自带强大的集群管理功能,弹性可伸缩 - shard自动均衡,可以根据业务变化随时增减节点数
易使用
o RESTful接口,易于开发和调试
o 强大的聚合分析能力,可以做复杂的统计分析(分桶、geo hash、多层聚合等)
默认情况下,下载ES的安装包后,进入ES目录,直接执行下面的命令,ES就会在后台启动,并监听机器的9200端口。我们通过这个端口就能读写数据了,不需要对ES做额外的配置。
ES这个章节的第二部分,来介绍ES的一个特殊模块,Ingest Pipeline,这个模块用来对写入数据做预处理。
在数据真正写入到ES的Index之前,可以通过Ingest Pipeline对数据做一定的修改。它里面可以定义一些processor,不同的processor可以对写入数据做不同的处理。比如可以通过Grok Processor做日志的格式化,来替代Logstash。
最下面的图是Grok Processor的工作原理。对于写入ES的文本(Simple Data),可以定义一个表达式(Grok Pattern),来规定如何对输入的文本做解析。也就是按照一定的规则,把输入文本分割为几个部分,每个部分是一个单独的字段。经过解析后,最终形成最下面的结构化数据。
所谓的Grok Pattern其实是正则表达式,只不过ES对常用的正则表达式做了别名,方便我们使用。所谓的文本解析也就是正则匹配,然后把匹配到的各个部分分别放入不同的字段,形成结构化数据。
图中的数据是一段样例日志,被分为三个部分,分别通过正则匹配解析为三个字段。 - 红色部分被解析为time字段,代表这条产生这条日志的时间。 - 黄色部分被解析为client字段,代表访问该服务的客户端IP地址。 - 蓝色部分被解析为duration字段,代表本次服务的耗时。
那么该如何定义一个Pipeline呢?
图中显示的是本次课程使用的pipeline,根据ES的API,我们通过REST PUT命令即可定义一个Pipeline。
URL中的ingest/pipeline是ES定义pipeline的固定API,最后的apachelog是我们定义的这个pipeline的名字(pipeline_name),后面写入数据时会用到这个pipelinename。后面会使用Filebeat采集apache的一段日志,因此这里的pipelien取名为apachelog。
Http的Body是json格式的,定义了processors,里面有三个processor:grok、date、dateindexname. - grok processor我们介绍过了,这里采用的pattern是ES内部预定义的用于解析apache日志的表达式,我们拿来直接使用即可。 - date processor是把grok生成的timestamp字段,改为Date类型。因为默认情况下grok生成的字段是string类型的,这里需要转换一下。 - dateindexname processor:通常我们的日志是跟时间强相关的,为了便于管理、删除过期日志等,通常index是按照时间范围划分的,比如一天生成一个index,当天的数据都写到同一个index里面,然后第二天生成的日志会写到一个新的index里面。 dateindexname processor可以根据根据时间字段(也就是上面生成的timestamp字段),自动生成index name,这样在写入数据时就不用指定index name了。 图中定义的index name是的一个前缀apache_log@加上当天的日期,实际生成的index name如图中最下面部分所示。
至此,ES的部分就介绍完了。
Filebeat原理
第二部分介绍Filebeat,它处于整个Elastic Stack最上游,负责日志采集。主要介绍下Filebeat的基本原理以及怎样配置启动。
filebeat的基本原理 Filebeat是Beats家族中的一员,Beats包括很多工具,感兴趣的同学可以去官网了解下。
如第一张图所示,Filebeat是一种文本采集器,它可以监听文本文件,类似于linux的tailf命令,不断采集文件中的新增内容,然后把采集到的数据发送至Logstash或者Elasticsearch。
它需要安装在生产环境上,也就是产生日志文件的机器上,但是它采用Golang语言编写,效率比较高;而且功能简单,比较轻量,占用的机器资源较少。
它具备重启续传的能力。filebeat会把当前在监听文件的元信息保存在一个registry文件中。如第二张图所示,里面记录了相应文件的路径、inode信息以及采集器已读取的位置(offset)。当Filebeat进程退出,下次重新启动后,会读取regstry文件,对于其中监听的文件,从offset的位置开始,继续读取文件内容。
Filebeat还具备压力感知的能力,它会根据ES集群当前的负载状况,动态调整自己传送数据的速度,防止ES集群压力过高。
filebeat的基本配置
filebeat的配置文件就在filebeat根目录下,yaml格式。 默认状态下,我们只需要修改input(采集哪些文件)和output(数据输出到哪里)即可。
input:
o enabled:默认是false,改为true后,Filebeat才会去采集文件内容。
o paths:需要采集的文件路径,这是一个序列,可以配多个路径,filebeat会同时监听这些路径下的文件。paths也支持通配符,方便配置一个路径下的多个文件。
output: 日志需要输出到ES中,所以需要修改output.elasticsearch:
o hosts: ES集群各节点的ip和port,是个序列,可配置集群中多个节点的地址
o pipeline: 写入数据时使用的pipeline,这里填前面在ES里创建的apache_log
这样filebeat就配置好了,启动的话直接执行filebeat二进制即可。 如果要后台执行的话,可以用nohup命令启动 如果担心filebeat占用过多的机器资源,可以通过taskset绑核启动,限制filebeat的资源使用。
当采集的日志量比较大时,默认的配置可能无法满足需求,这里给出一些通常使用的调优参数,大家可以做个参考。当然不同场景下,最佳的参数配置也是不同的,需要根据自己的实际使用场景,做适当的取舍和调整。对于这些参数,此处不做过多的阐述,可以参考filebeat的官方文档。有问题可以留言交流,后面有时间也会整理下调整这些参数的原因及效果。
Kibana简介
最后一部分介绍Kibana,它处于Elastic Stack的最下游,主要提供数据分析、可视化的能力。主要介绍Kibana的基本功能以及怎样通过它来查询数据、生成可视化的图表。
Kibana提供了数据查询、可视化及统计分析的能力。
它是一个独立的进程,需要下载后独立部署,它只能绑定一个ES集群,无法同时查询多个ES集群的数据。
搜索 Discovery 查询界面,通过简单的查询条件就能获取目标数据,提高问题定位的效率。
可视化 Visualize功能,这是它最大的亮点,可以借助ES的聚合查询接口,生成如图所示的各种图表。
数据管理 提供命令行界面Console,可以完成数据的增删改查、通过命令管理ES集群。
X-Pack Monitor 同ES提供的增值服务X-Pack一起使用的话,Kibana还可以提供监控的能力,这部分不在本次课程范围。
kibana的启动也很简单,默认情况下直接执行kibana/bin目录下的kibana二进制文件即可,它会默认连接本机的9200端口,这是ES的默认监听端口。
要通过Kibana查询数据的话:
第一步:先要告知Kibana我们期望查询的Index是哪些。如第一张图所示,通过Management页面,配置一个Index pattern,来匹配我们要查询的Index。Filebeat上传的数据,会经过名为apachelog的pipeline,然后生成apachelog@开头的Index,所以需要把index pattern指定为apache_log@*,这样就能匹配到pipelien创建的index,如图中蓝色部分显示。
第二步:需要选择数据的时间字段,这里指定为pipeline中定义的timestamp字段。
第三步可以在Discovery界面搜索数据了。可以在图中红色标注的文本框中输入查询条件。比如查询response为403的apache日志,只要输入response:403即可。下面显示的就是查询到的相应的apache日志,并且是结构化的数据,可以看到client ip/verb/request等信息都被解析出来了。
查询的具体语法可以参考Kibana的官方文档。
kibana数据可视化相关的界面主要是Visualize、Timelion和Dashboard。
因为数据可视化图表是基于ES的聚合查询来做的,需要对ES的聚合查询有一定的理解。所以这里以介绍功能为主,具体的创建方法需要理解ES的聚合查询后,参考Kibana的官方文档来配置。
Visualize界面主要用来创建单个图表,比如第一张饼图,可以看出apache的请求中,response code是200的请求占总请求数的82.06%。还有第二章面积图,可以看到apache每个时刻的数据吞吐量。
Timelion界面主要用来看同一个时间点,不同指标间的关系。图中两个图表红色竖线所在的位置是同一时刻,通过各个图表的取值,可以看到相同时刻不同的指标间的关联关系,便于定位分析。
Dashboard是仪表盘,可以将上面创建的各种图表放置在同一个Dashboard页面上,然后命名保存。这样每次登录Kibana可以直接通过Dashboard一目了然的看到各个图表、各种指标。并且Dashboard可以生成url链接,方便共享给其他人;它也提供了iframe的链接,可以很方便的嵌入到其他系统的前台页面中。
至此本次课程的内容就介绍完了,最后分享下我们基础架构部 ES团队做的一些工作。我们主要基于Elasticsearch开发了两款产品,一个是源生的Elasticsearch服务,一个是时序数据库CTSDB。
非常感谢大家参加今天的课程,我们在腾讯云+社区设置了Elasticsearch实验室的专栏,定期对外发布相关文章的同时,也会交流相关问题,欢迎各位来访,再次感谢大家!