基于 Kafka 和 ElasticSearch,LinkedIn是如何构建实时日志分析系统的

      及时有效地搜索日志是 SRE  (Site Reliability Engineer) 平常工做的重要内容。LinkedIn 从使用 Splunk 到创建基于 ES 和 kafka 的日志分发、索引系统,为 SRE 提供了近似实时的搜索平台来检索超过 400 多个子系统的日志。在本文中,来自LinkedIn的李虓将和你们分享这套系统从无到有的一些技术架构经验。css

本文整理自李虓在QCon上海2016的演讲,原题为:《LinkedIn 基于 Kafka 和 ElasticSearch 的实时日志分析系统》。回复关键词「领英」,下载完整版PPT。java

写在前面node

今天,和跟你们分享咱们在用ElasticSearch和Kafka作日志分析的时候遇到的问题,系统怎么样一步一步演变成如今这个版本。你若是想拿ElasticSearch和Kafka来作日志分析的话,会有一些启发。全文主要包括如下几个Topic:python

  1. 日志分析系统的基本需求;nginx

  2. LinkedIn的日志系统演进过程;shell

  3. 咱们的经验和教训。安全

为何要作日志分析系统?服务器

首先,什么是日志?简单的说日志就是一个结构化的数据+时间戳。计算机开始日志就已经存在,从那时候就有各类各样的工具来帮咱们分析、解析或者查找日志。网络

一开始作这个东西的时候,不少团队以为不是很须要,工程师登陆到服务器上面作一些cat或者grep和简单的表达式处理就够了,能够找到须要的信息。若是不够的话,好比在不少台机器上的话,有mssh、cssh等工具。架构

还不够的话,能够本身写工具,有一次我发如今咱们的生产服务器上面,有一个SRE写了一套系统,从本身的台式机,作了一个ssh tunnel到实际的生产系统里面作了远程代码调用,远程把那些文件拿回来,这是一个一级的安全生产事故,是很是不负责任的事情,可是这也就暴露了咱们确实有这个需求。

当咱们有五万台服务器,五百多个微服务的时候,你不可能期望每一个人都很是熟练的去解决这样的事情。开发或者运维常常会遇到这样的需求,好比拿某两个时间点之间的全部的日志,只须要看WARN或者ERROR或者FATAL的消息,而且有十几个错误是已知的,要忽略。

这个服务是跑在好几个数据中心几百台服务器上面,还须要关心有没有新的错误,这个错误是否是因为某个特定的用户形成的,或者某些特定的用户行为形成的,好比说他post了什么,或者request的长度超过一个固定长度;这个服务器上的错误信息有没有和其余服务器上的错误信息相关联。给我30分钟我有可能写出来一个四五行的grep命令去几百台服务器上把日志拉下来,但若是在凌晨三点钟,这就是一个不太可能的任务。

日志分析系统须要知足如下基本的要求:

  1. 对于重要的日志,知足索引,检索、排序、分类,而且提供必定程度的可视化、分析日志的功能;

  2. 可根据数据规模横向扩展。由于互联网的发展很是很是的快,咱们但愿找到一个解决方案,不要过了一年甚至半年,当服务器或者用户数量加倍之后,解决方案就彻底不可用。须要找到一个方案,当用户数量加倍时,简单的加几台机器或者服务器就能够继续使用;

  3. 这套系统可以很轻易的扩展,由于不少公司已经有了不少的报警或者监控系统。能够方便的经过API或者经过扩展接入到已经有的监控、报警,或者其余系统里面。

还有一些其余扩展性的需求,包括日志采样,提升安全性、保护日志里面包含的信息,也是后面着重谈的一个问题。

LinkedIn日志系统演进

回到四年前,从LinkedIn成立到2012年咱们有一个系统叫Splunk,很是好用,只有一个问题,太贵了。2012年的时候,咱们当时生产环境有3、四千台的服务器,续签第二年的合约时他们的报价是2000万美圆一年。这实在是不能够接受的,而且那个时候是2012年,咱们如今的服务器台数、用户请求数已经翻了差很少十倍,当时的价格若是是2000万,如今更多,由于它是根据数据量来算license的。

从2012年到2014年,由于咱们当时决定不用Splunk,就进入了一个混沌期,这段时间很是痛苦,你们都有需求,可是没有人有方法,不少人开始搞本身的小动做,作些小工具。我以前看了一下内部工具库,里面有2、三十个用python或者shell写的小工具,这些小工具是用来找一个时间段内的log或者特定用户的log,可是有很大的浪费,不少工具重复的写,也很是难维护。

2014年到2015年这一年多的时间咱们痛下决心,必定要作一套可以横跨LinkedIn全部log的系统,而且推广到整个LinkedIn。当时选择了ELK,它的优势就是:开源,发布周期很是快,固然也有缺点,它很是的新,因此有不少小毛病。

相信你们不少人已经知道ELK是什么——ElasticSearch、Logstash、Kibana。ElasticSearch就是基于Lucene的储存,索引,搜索引擎;Logstash是提供输入输出以及转换处理插件的日志标准化管道;Kibana提供可视化和查询ES的用户界面。

LinkedIn日志系统演进V1

每一个人花30分钟就能够在本身的电脑或者生产环境上搭一个这样的东西,Log经过Logstash读出来,放到ElasticSearch里,而后Kibana去读。这步作完之后其实就能达到很是好的效果。LinkedIn全部的业务群都会要求有一个异常面板,好比说支付系统业务群,它大概有十个左右不一样的小服务。

当报警系统发现支付系统有了各类各样的问题以后,咱们第一步就是到异常面板来看Log里面有没有什么东西,能够根据时间线上看,有没有哪些新的服务在近期有了新的log或者error log数量不同。而且它会根据不一样的exception/java stack拿出来作count,这也给分析带来很大的帮助,还能够写出不少复杂的query。

第一个版本很是简单,咱们只把它应用到了一两个很是关键的系统上。这套系统作完以后咱们作了一个对比,平均故障解决时间从之前的五十几分钟缩短到小于30分钟。咱们的线上系统通常最快会花5到10分钟才有一个不是很关键的警报出来,若是能很快发现问题在哪里,解决这个问题,好比说一个简单的rollback操做,在几百台机器上也会花5到10分钟的时间,真正留给人根据log去判断问题在哪里的时间也只有短短的5到10分钟。

若是不是有一个异常面板能看到全部的信息,好比有没有哪一个服务器的异常比其余服务器多,有没有一个异常是忽然今天出了不少次的,或者有没有一个服务器今天出了不少的异常,最起码要花二十到三十分钟的时间手工的看log。

第一个版本有几个问题,第一是Logstash Agent的维护不是很理想,Logstash是基于Ruby的,启动它就要有几十兆内存被jvm吃掉,咱们想避免在每一个机器上都要起一个Logstash。而且在咱们使用过程当中Logstash很是不稳定,莫名其妙就死掉了,还须要一个守护进程守护它。第二个是log标准化,也是很是头疼的问题。

第一个Logstash Agent的问题经过引入Kafka解决,引入Kafka后不须要每一个host上有agent。LinkedIn内部有专门的SRE团队维护Kafka,很便宜,不须要花钱去维护。对于Log标准化,咱们花了很是多的时间看,LinkedIn有99%的服务都是java service,有15种以上log,最重要的是access log和application log。咱们作的一件事情是经过java Container logger标准化直接写入Kafka。有的程序直接写到kafka,不上磁盘,有的程序还要同时写到磁盘里面,这是可配置的。

这些是经过LinkedIn standard container一块儿rollout到全部的service上。开发人员什么都不用管,只要在程序里写logger.info/logger.error,那些信息就会直接进到Kafka。对于程序日志,默认警告以上的级别进入Kafka,能够在线经过jmx控制。对于访问日志,咱们有10%采样,能够经过ATS入口动态控制。

LinkedIn日志系统演进V2

这是第二个版本,能够看到在生产环境的Java service那边,Host上已经没有Logstash,全部的log直接写入Kafka,Logstash从Kafka里消费这些日志,写到ElasticSearch里面去。

第二个版本还会出现一些问题,好比说一个服务出现问题的时候会影响整个ELK cluster。咱们出现过这样的状况,一个团队写了一个新的服务,把全部的log的级别都定义成error,整个ElasticSearch就被它冲垮了。不少时候还会出现网络饱和的状况。

很简单,第二步很是简单的决定就是把它进行拆分优化:

  1. 首先按照业务功能拆分ELK cluster,好比说负责支付的,跟钱有关的系统用一个集群;全部跟用户登录有关的系统,安全有关的系统用一个集群;

  2. 将Logstash和ElasticSearch分开运行。ElasticSearch是磁盘密集的操做,Logstash是CPU密集的操做,咱们当时想把他们放到一个物理机上,可是试下来相互影响仍是挺大的,因此决定把Logstash跟其余的系统混用,与ElasticSearch分开运行;

  3. 对于每一个Kafka话题,Logstash数量很多于话题partition数量。LinkedIn有500多个服务,每一个服务会产生访问日志、程序日志两个Kafka topic。Logstash消费Kafka的时候,若是consumer数量少于partition数量,会触发Kafka一个隐藏的漏洞,致使Kafka partition不均匀,出现各类诡异的问题。咱们的建议是,通常状况下,每一个topic有四到八个partition,而后根据状况设置相应数量的Logstash。

LinkedIn日志系统演进V3

根据业务需求拆分,咱们拆出来20几个这样的相同的集群,这个版本,还有一些问题。首先是跨业务分组集群的查询,虽然不少的时候,一个问题在一个业务分组里面就能找到,可是还有不少的时候要跨到另一个集群里面才能找到问题究竟是从哪开始的。

第二,千万不要跨数据中心作ElasticSearch的集群,很是很是差,根本跑不起来。即便两个数据中心很是近这样作也很差,尤为当数据量上来以后,会有一些很是诡异的问题。数据量很是大的ElasticSearch集群咱们会要求它所有在一个机架上,若是有一个服务器在另外一个机架上都会出现timeout的问题。

为了解决刚刚说的问题,咱们引入Tribe,用下来的感受能够用,可是这明显不是一个他们支持的功能。Tribe理念很好,可是它不支持分层,咱们须要两种不一样的Tribe,首先要能跨业务分组,还要跨数据中心。

最好的状况是作一个分层的结构,数据中心在最外面,业务分组在最里面,可是从设计理念上是另一个概念,因此不行。只能退而求其次,在一个数据中内心面会有跨全部业务分组的一个Tribe,还会对相同的业务分组有一个跨数据中心的Tribe,有两个不一样类型的Tribe进行查询。

LinkedIn日志系统演进V4

到这一步,基本上功能实现的差很少了,就开始慢慢的把500多个服务的日志打到Kafka里面,大概花了一两个月,发现consume跟不上,遇到了性能瓶颈。用ElasticSearch超过50或者100台服务器,就会遇到不少这样的瓶颈。咱们花了三个月的时间,作了各类性能调优。

这一步算是最后一步,首先理解了一下本身的业务逻辑,咱们要作的事情很是明白,很是单一,就是须要实时的,或者准实时的log来作在线的trouble shooting,基本上不会用到14天之前的数据,保留14天之前的数据就是为了看两周的周期而已。

今天的问题都解决不完,根本没有时间考虑几个月以前的问题,实际的业务状态是24小时以内的日志查询的最多,14天之前用的很是少,查询速度要求在15秒以内,超过30秒就timeout了。索引速度30秒之内能够接受,超过5分钟会触发警报。

LinkedIn日志系统演进V5

采用冷热分区的方式解决这个问题,咱们测试了不少种不一样的硬件,最后选定了在很是重要和数据量很大的集群上用ssd作热索引,24小时以内的索引所有上到SSD机器上,超过24小时就挪到普通的机器上。至关于在集群里边,有一个热的Cluster,数据全面走到热的cluster里面,24小时之后,会被挪到冷的cluster。作了这个以后,系统变得比较稳定,功能也正常,内部会根据需求保留7到14天的数据。

这步以后,咱们把它推广到LinkedIn整个公司,次日我接到法务和安所有的电话。当咱们作了一个很是容易的系统,把全部的log展示给全部人的时候,若是你们能很轻易的把4亿用户的用户名、密码、邮箱等信息搜出来,这个事情就很是严重,因此咱们又作了几个调整。

第一个是按期扫描全部的ES,根据特定的关键字来防止敏感信息进入日志,若是进入立刻报警。还有用户隐私的问题,全部Elasticsearch的查询记录一样送入Kafka,并对敏感业务部门的访问进行隔离,全部访问日志按期审核。咱们的作法是在前面加一个Nginx,在nginx上能够作访问控制,把用户全部的访问日志所有送回Kafka作按期审核,有一个扫描进程按期的扫描各类各样的关键字。

LinkedIn日志系统演进现状

这是咱们如今生产系统里的状态,有20多个针对不一样业务模块的ELK集群,1000+服务器,主要都是Elasticsearch。1分钟以内生产系统发生的log咱们这边就能够搜索,全部的log保留7到14天。如今大概有500亿的索引文档,500到800T,以前测试时推到1500到2000T都是能够工做的。

由于咱们是500多个service,20多个集群,没有办法很好的维护这么多集群,因此是每一个业务模块的SRE团队维护本身的Elasticserach集群。Virtual Team模式确保ELK的及时更新。还有一点比较关键,须要保证你的ES不会被没有受权的用户访问,默认的状况下是不接受SSL链接的,SearchGuard和Sheild这两种解决方式都是能够解决这个问题的。

我想着重提一下采样方式,这个是比较有意思的,也是比较通用的方式。采样方式是10%+特定的用户,为何要这么作?咱们调过不一样的比例,发现不影响,若是有问题,10%的采样就能发现。为何还要特定用户呢?不少时候,有一些active的用户会常常给你报错,给你反馈意见,须要及时去看到底发生了什么事情。

对LinkedIn来讲有大概百分之零点几的power user在网站上很是活跃,作不少事情,咱们须要把他们的log加到sample里。全部的用户请求,都是经过Apache Traffic Server进入数据中心,在这层它会去访问LiX,询问是否要对当前用户打标签,若是打了标签就把这个标签放在InvocationContext里面。

从前台到后台全部的服务器只要touch到这个request,都会在InvocationContext里看到一个requestID。经过java container的bydefault获得requestID,把那条访问的日志发到Kafka里面,经过这样的方式作成sample。

这样作有两点好处,一点是若是有什么问题,只须要把他的memberID或者requestID拿到最上面一层Tribe里面,系统就会出现关于这条request的全部service的log。99.9%的状况能够一目了然的知道哪里出了问题。作微服务的你们都知道,dependence很是乱,咱们LinkedIn的状况,一个request会touch二三十个service。因此说有这样一个方式是很是重要的。

平常运维之坑

我想聊一下咱们遇到的几个坑,ES集群的默认名字是大坑,若是不改集群名字就把它放在本身的电脑上或者测试系统上跑,一旦相同子网的人加了一个新的node也没有更名字,就会自动加到你的集群里面。无论怎么样必定要改你的集群名字。

Master、Data、Client节点不要混用,使用单ES节点;JVM不要allocate超过30G的heap,咱们测试发现30G左右的heap能够达到最好的performance,若是超过30G就没有办法彻底使用;JVM版本的兼容性也是一个超级大的坑,它不是最新的兼容,也不是哪一个版本之后,或者之前兼容,是有几个版本兼容,再几个版本不兼容,再几个版本兼容。有一些兼容性的问题必定要注意。

平常运维之硬件

讲一下刚才已经提到的硬件的选择,要根据数据量,业务的状况,索引和查询速度的要求决定,像咱们的要求是必定要索引快,由于要作实时的故障排查,数据的类型咱们只作两个,一个是访问log,一个是application log,这些决定了咱们使用的硬件是12核/64G/2x1TB的硬盘,有八九百台都是这样的配置。

有一小部分是数据量很是大可是对查询的速度要求不是很高,好比作自动查询的那套,咱们会把数据丢到JBODs里面,索引速度优先考虑的话,会用100台左右的SSD。

平常运维之集群

集群没有magic number,必需要用实际的生产数据,一遍一遍试,才能试出来用什么样的配置能达到最好的效果,这几个是咱们的learning:

  1. 横向扩展,不要纵向扩展,不要试图用更大的memory或者最快的CPU,不会有太大的效果,咱们大概测过四五个版本,基本上没怎么成功;

  2. 每一个shard不要超过50G,只要超过50G咱们的shard就会莫名其妙的失联;

  3. 关闭冗余,咱们把replication关了是为了更快。关了以后若是出现硬件故障,从Kafka那边读,数据很快就能回来;

  4. 天天建新的索引,有一个集群由于数据量很是大,会作每一个小时的索引,二三个数据量比较小的集群每周作一个索引;

  5. 只分析必要字段,IP字段、设备版本,这些字段彻底没有必要作分析,只要能整字段查找就好了,把它关掉,能够省不少的空间,index速度也会快不少。

平常运维之工具

还有就是一些工具,刚刚提到主动扫描敏感信息的就是一个script在后台根据一些关键字扫描敏感信息;结合警报系统,相信每一个公司都有本身的警报系统,ElasticAlert是一个开源的解决方案,咱们本身也有内建的,根据读出来的信息的关键字作警报;循环删除index用的Curator;系统健康状态监控是本身作的监控系统,官方的Marvel也很好用。

提升代码质量

作完这套系统之后,咱们并非彻底被动的状态,只能用这套系统来作故障排查,咱们发现这套系统里面有些指标能够很好的反映开发人员的代码的质量。

  1. 请求数/日志总行数,对于每一个service都不同,可是大概有一个区间,若是出了这个区间,可能这个service就有一些问题;

  2. 请求数量/错误(异常)行数,这个也有一个区间,咱们这边的区间是1000个请求,大概产生2000到5000行的日志,500到3000行的异常数量,这个是咱们能够接受的,常常会有service超出这个范围10倍,经过这个就能发现异常有没有处理。

经过这些发现一些有意思的metric返回给开发人员,帮助他们提升代码的质量,这是一个比较有意思的发现。国外和国内你们作的东西不少很像,遇到的问题也很像,但愿能给你们一些启发。

相关文章
相关标签/搜索