揭秘魅族日志分析平台的建设

嘉宾介绍

林钟洪,2014年加入魅族研发中心,任运维架构师,负责魅族云平台虚拟化及魅族日志平台研发,主要包括:KVM虚拟化、docker容器化、分布式存储、集中式日志系统。

直播实录

揭秘魅族日志分析平台的建设

大家好,今天给大家带来的是我们魅族日志分析平台的建设。

在这之前,先跟大家简单的自我介绍下 ,我是2014年加入魅族的,现在主要负责的是云平台和日志平台的研发。

今天分享的内容主要有四大部分:

Ø  平台建设背景

Ø  平台建设

Ø  平台问题优化经验

Ø  平台新功能及展望

首先会给大家介绍下日志平台建设的大背景,是什么促使我们需要去建立这样一个日志平台,平台建设是今天跟大家分享的第二个主要内容,第三个部分是在平台上线之后我们又遇到了哪些问题,是如何解决的,并作了哪些优化会跟大家分享下,最后会给大家介绍一下平台目前正在做的功能和展望。

先来了解下日志平台建设的背景。2015年是魅族爆发增长的一年,活跃用户从不到1000万爆发增长到近2000万,三大中心每一天堆积的日志量达到数百GB甚至上TB级别,而且单个日志文件就可能非常大,比如说100G,在这么大的文件里面去找我们想要的信息是很麻烦的事情,通过传统命令行的方式去里面检索基本是不可能的。这时候问题就聚焦在日志量大和检索困难上。

另外一个就是由于业务的多样性又造成了日志格式混乱,日志存放位置混乱,一旦出现问题就苦逼了,你必须一台一台登陆上去查看,并且因为日志的多样化,有lvs的有Nginx的,也有业务jetty的日志,你必须要开很多个窗口,切换来切换去,最终你都不知道哪个窗口是看过的。总的来说就是一个字“乱”,造成出问题时排除困难,效率低。

再有一个问题就是由于大量日志堆积在磁盘,必然产生告警,告警一多又得想办法解决,想来想去也只能是删除日志了,想对日志进行分析就更不可能了。

总结一下在建设日志平台之前遇到的问题:

Ø  日志量大、检索困难

Ø  日志格式混乱、排查效率低

Ø  磁盘告警多,日志对于运维来说是一种负担

所以说有没有一种办法能够把这些日志都集中起来,我只需要在一个地方进行检索,查找就行了,并且能够做实时的分析统计,然后最好就是有一个清晰、直观的,能够很方便的进行查找、统计,能清楚看到哪个地方出错了的这么一个界面。

答案当然是有,而且开源的日志方案还很多,这时候你就会纠结这么多的开源日志方案到底哪种才是最合适自己的呢?

最后综合考虑到稳定性、扩展性、易用性、实时性,我们选择了ELK这个成熟的开源解决方案来建设我们的日志平台。

接下来我们就来了解下ELK以及我们为什么选择ELK作为日志平台建设的方案。

ELK包括三大组件ElasticSearch、Logstash、Kibana。

首先是ElasticSearch,它在ELK里面是最重要的一部分,它主要是帮你搞定海量日志数据。前面说到我们的日志量非常大,选择平台的时候必须考虑良好的水平扩展能力,然后就是要有实时响应的速度,并且能够提供实时分析的功能和方法。来看下ElasticSearch的哪些特性符合我们这些需求。

首先它是分布式的,高可用的搜索引擎,是全文检索的引擎,也是实时检索的引擎,有非常多针对分析的功能,这就满足了我们对日志平台处理量大,响应实时,具有分析能力的需求。

然后是日志收集,Logstash,它主要是帮你搞定日志的多样化,它可以用收集日志,然后加工处理,进一步解析,最后转发给es或者其他输出后端。

在日志接入Logstash之前,我们还做了一个动作来解决日志格式、存放位置的混乱,就是对业务日志格式进行了统一规范整改。

这样做的好处是。首先,如果让logstash来处理混乱的日志格式,那这处理逻辑将非常复杂,也非常的消耗资源。其次,规范化日志格式也有利于后期对日志做相关串联分析。

前面两块是关于日志存储和日志收集,最后一块是关于日志的展示。

我们将日志存进去之后,需要一套很好的工具去帮我们搞定前端展示,让我们很方便地去配一些分布图和做统计分析,这就是Kibana做的事情。简单截几张Kibana的效果图给大家看下。

讲到这里,有些小伙伴肯定会有疑问。你前面讲的都是ELK的特性,其他日志解决方案不可以么?我知道的就有hadoop、storm,我不能选这些方案吗?那我们就来看下都有哪些其他方案以及当初我们为什么不选择这些方案。

首先是hadoop。hadoop做日志平台有一个明显的缺点就是不实时,查询慢。做离线分析是hadoop的强项,但是在线数据挖掘则不行。如果说你的日志平台要求实话就不适合选择hadoop。

storm和spark,这些流式处理框架实时性比hadoop好不少。但这些都只是开发框架,用来建设日志平台,需要进行更多的二次开发。如果要快速的搭建日志平台,这些框架也不适合。

了解搜索引擎的小伙伴还会问,为什么不用solr。Solr也是高可用的、分布式的,全文检索的引擎,搜索也非常快。我们先来看几张图。

这是ElasticSearch和Solr检索速率的对比图。可以看到对已有数据进行检索时,solr的确比ElasticSearch要快不少。我们再来看一张图。

这是实时检索时的对比图。就是建立索引的同时进行检索。这时solr会产生io阻塞,检索性能明显比ElasticSearch差。而且,随着数据量的增加,solr的效率则会变得更差,而ElasticSearch基本没变化。

所以说,日志平台要求实时分析,solr也并不适合。

综合这么多方案,ELK也就成了我们日志分析平台建设方案的首选。

说了这么多,那ELK在魅族日志分析平台到底是怎么用的呢?我们直接上图。

这就是魅族日志分析平台的整体架构,可以看到主要分为四层。

最上面是日志收集层,各种类型的应用服务产生的日志,有网络的,主机的,windows的,Linux的。日志正常的输送流程是日志数据从各种客户端输送到redis。如果日志客户端不能直接与redis通讯,则由Logstash shipper集群进行中转。比如网络设备,是通过syslog发送到logstash的。还有windows的filebeat客户端也是先发给logstash,做些简单处理,再转发到redis。

中间是数据索引、数据处理层。主要是对收集的数据进行解析处理,再发送到es集群进行索引。

接下来访问控制层。这一层主要是对用户访问请求进行鉴权以及授权。我们的权限控制模块用的是用search guard这个插件,后面会讲到。

最下面一层就是用户层,可以是用户到Kibana上查询,也可以是其他第三方系统调用api进行查询。这就是ELK在魅族日志平台的应用。

看着上面这个架构图,熟悉业务的运维小伙伴肯定会有疑问:你们所有业务的日志都在一个集群里面?

我们都知道为了保证业务的可用性,业务都是部署在不同idc的,一般就是两地三中心这么一个架构。那么这些不同idc之间的日志怎么传输/存储?都存在一个集群?那肯定得消耗很多外网或者专线流量。各自建集群?那查询同一业务不同idc的日志怎么办?带着疑问,我们来看下魅族日志平台是怎样解决的?还是直接上图。

可以看到,我们用lvs保证了查询平台的高可用。然后使用ElasticSearch的tribe节点互连起不同idc间的ElasticSearch集群。通过tribe节点可以合并不同idc集群的日志查询结果。这样即做到了不同idc集群的独立,又保证了业务日志查询的统一。这时候日志平台已经搭建完成,idc之间的互连也解决了,日志就开始接进来了。各方面反馈都不错,查询、排错也不用再登陆到每台机器挨个看了。一些性能指标,比如Nginx错误代码统计、访问统计等也可以很直观的统计展示出来。但是,随着日志量越来越大,新的问题也开始出现了。。。。

当日志量上去了,用户多了,你就会发现平台开始报各种异常。比如频繁GC,内存溢出,文件数打开过多。甚至是节点长时间无响应,脱离集群。又或者是es索引速度跟不上日志流入速度,日志堆积,搜索失效。各种问题接连出现,怎么办呢?有么有办法解决呢?下面就跟大家分享下在这过程中我们遇到的坑,如何解决的,以及一些优化的经验。

我们知道日志平台问题的产生主要集中在ElasticSearch集群,所以优化重点也主要是ElasticSearch集群。分为三个方面来讲:1、如何保证集群稳定;2、如何优化索引速率;3、如何提高查询速度。

首先是集群稳定性。我们来先看下官方推荐的优化配置。

主要是增大文件打开数、关闭swap、设置java堆大小。做了这些调整之后,集群已经能够稳定运行了。随着日志量越来越多,机器也越来越多,这时候就会遇到一个问题,节点丢失。

你会发现,原来20个节点的集群,只剩下16个。然后登上那4个丢失的节点一看,这些节点都是在线的并且端口都还在,去访问的时候都是还能打开的。但是他们相互之间已经不是在一起了。有几台机器还会存在一个问题,就是这16台机器有4台上面一个分片都没有。就是整个是空白的,没有数据分配。

另外一个问题就是GC,在java里面GC是很常见的,但在GC时间比较长的时候。在默认配置下,节点会频繁失联。节点的失联又会导致数据频繁重传,甚至会导致整个集群基本不可用。怎么办?不用慌,我们可以通过参数调整来避免这些问题。

discovery参数ElasticSearch是用来做集群之间发现的,默认设置的超时时间是比较小的。我们把参数适当调大,避免集群GC时间较长导致节点的丢失、失联。

还有一个问题就是我们刚说的,有16个节点他们变成一个集群,后面4个节点变成另外一个集群。这个就是我们经常说的脑裂,脑裂会导致数据不一致,不一致又导致数据没法用。这时候你不得不进行数据重建,但是要知道数据重建的开销是非常大的,大概就是这样一个连锁反应,节点无响应->多个集群->脑裂->数据不一致->数据重建。怎么办呢?要如何来避免脑裂的发生呢?

脑裂主要是集群认为Master宕掉了,而选择了其他节点当maste。我们在配置discovery的时候就不要设置广播寻找master,而是指定几台作为master候选。

还有一种避免脑裂的方法就是角色分离,避免一个节点拥有多种角色,就是说一个节点不要既是数据节点,同时又是Master节点。

角色混合在一起会产生一个问题,当某个数据节点成为Master之后,它马上就会往其他节点发送数据以保证副本的冗余。如果数据量很大的情况下,这个Master就会一直在传送数据,而其他节点确认Master的请求可能就会被丢掉或者超时,这个时候其他节点就会重新选举新Master,造成集群脑裂。

在做了前面这些调优、配置之后,集群的稳定性已经得到保证。第二个优化方向就是索引速率,有两个参数可以调整。

调整索引刷新频率,但是不能太小。太小会造成索引频繁刷新,新的数据写进去就慢了,索引速度也并不一定就快。还有一个机制也会影响数据索引的写入,那就是索引合并。ElasticSearch会不断的将一些分散的小的索引合并成一个大的索引,然后再刷到磁盘。当日志量非常大或者说在导入大批数据时,我们就会发现ElasticSearch日志一直在报这个信息:now throttling indexing: numMergesInFlight=6, maxNumMerges=5。

这个信息是什么意思呢?意思是说新生成的索引太多了,ElasticSearch的merge速率赶不上了。这时候ElasticSearch就会开启索引节流机制,限制索引写入速率。但是在默认配置下,这个限速配置是比较小的只有20MB/s。对于写入量较大,磁盘转速较高,甚至使用 SSD 盘的服务器来说,这个限速是明显过低的。我们可以适当的调高,比如说调到100m,索引速率优化就讲这么多。

我们接下来讨论下第三个方面,提高查询速度。

首先是mapping优化,在我们往索引里面送数据之前,我们要把mapping提前定义好。这里有几个优化点:比如把source字段进行压缩,把all字段禁用掉,内容去重,把field.raw字段删除。总之,我们做这个mapping的优化是减少我们的索引体积,提高我们的查询速度。

接下来我们重点说下fielddata cache。我们都知道,搜索引擎会使用倒排索引(inverted index)来映射单词到文档的 ID 号。但是在排序和做聚合的时候,是不走这个倒排表的,它必须一个一个去查找排序,比如说有个姓名字段,内容有张三、李四等。如果要对这个字段进行排序,这个时候他们是不在内存里面的。ElasticSearch必须去磁盘逐个找出来,这时开销是非常大的。如果要减少开销当然就是把内容cache起来,放到内存,fielddata cache就是做这么一件事情。如果在数据量比较小的情况下,这个是非常好的,查询速度也很快,但是当数据量非常大的时候,你做排序,fielddata cache就会占用大量内存,很容易导致内存吃紧,集群频繁GC,也根本无法完成计算过程。所以,你会发现,当你配了cache的时候,需要十几秒才能查出来。不配的时候反而更快些,这也是我们说的要避免使用的原因。

那么如果不配置fielddata cache,有没有其他方法来提高排序、聚合的速度呢?其实ElasticSearch也是不怎么推荐使用fielddata cache。它有另外一个特性来提升速率,就是 doc values。Doc values ElasticSearch2.0以后是默认开启的,1.0需要手动更改mapping开启。这个Doc values有什么作用呢?其实就是在 ElasticSearch将数据写入索引的时候。就提前生成好字段的内容,并记录到磁盘上。因为字段数据是顺序读写的,所以即使在磁盘上,通过文件系统层的缓存,对热数据的访问也可以非常快。

这里需要注意一个点,doc values是在数据写入索引的时候就生成了字段内容,所以不能用在有分词的字段上,只能用在精准索引的字段。

说了这么多的优化,有一个不得不说的,就是索引的日常维护。

这样不仅可以释放内存、节省磁盘空间,还可以加快检索速率。

前面提到的都是ElasticSearch集群的坑和优化,这里还有一些关于logstash的优化经验跟大家分享下。

对于ElasticSearch output后面两个参数flush_size和workers,我们做过压测。来看下结果。

可以看到随着flush size的增加,ElasticSearch的索引速度也跟着增加。但是当达到极限时,再增加,索引速率反而有所下降。我们压测到是65000之后,速率就不增反而下降了。

而workers更加明显,1到2的时候是有所提升的,但是再往上加的时候,ElasticSearch索引速率明显掉了。说了这么多优化,是时候来看下我们优化后的成果了。

这是我们其中的一个集群,总共有20个节点,数据节点是10个,每天处理日志超过30亿条,单台节点峰值每秒可以处理10万条日志。我们日志平台已经稳定运行小半年了,有几个功能是我们欠缺的也是正在做的:冷热分离和权限控制。

冷热分离的目的在于合理的分配资源,提高资源利用率。我们将热数据存放在硬件配置相对较好的集群,不影响数据检索。同时可以将冷数据存放到配置较低的集群,节省资源。

权限控制,我们用的是search guard这款安全插件,并对其进行二次开发,结合ldap对用户进行认证及授权。

授权的维度分为用户和用户组,而权限粒度则细分为读、写、管理各种组合。建设完成日志平台之后,我们会发现,在之前,日志对于我们可以说是个负担,因为存的多,告警多,你还得去删除。但是现在呢?我们是希望日志越多越好,因为只有足够多的日志才能产生有价值的信息。只有足够多的日志才能够进行各项分析那么,利用这海量的日志,我们还能做些什么呢?

最后,跟大家介绍下魅族日志平台的展望。首先是最近很火的APM,运维可用性监控及应用性能监控。

Ø  我们可以通过日志对网络设备、服务器及应用程序进行实时监控

Ø  通过日志对应用程序性能进行监控,及时发现性能瓶颈

Ø  关联不同系统间的日志,排查服务故障

然后是docker。在Docker容器方面,日志一直是一个争议的问题。如果把日志存放到宿主机数据卷则不利于容器迁移存放到容器,又违背了容器轻量级的理念。统一日志平台完美解决了容器迁移过程日志的问题,也节省宿主机磁盘空间,轻量化了docker容器,有利于容器化的推广。

行为分析。关联不同业务间的日志,我们可以进行用户的行为分析,定位用户行为,进行精准推荐等。

操作审计。将用户的所有操作都存储到日志平台,如果有什么出现故障,需要查找原因,就可以马上检索到,还原故障现场。

最后是结合大数据。利用ElasticSearch强大的检索、聚合分析能力,为大数据提供分析支持。我今天的分享就到这里,内容有点多,谢谢大家。

欢迎加入本站公开兴趣群

软件开发技术群

兴趣范围包括:Java,C/C++,Python,PHP,Ruby,shell等各种语言开发经验交流,各种框架使用,外包项目机会,学习、培训、跳槽等交流

QQ群:26931708

Hadoop源代码研究群

兴趣范围包括:Hadoop源代码解读,改进,优化,分布式系统场景定制,与Hadoop有关的各种开源项目,总之就是玩转Hadoop

QQ群:288410967 

我来评几句
登录后评论

已发表评论数()