DevOps云翼日志服务实践

10月30日,全球权威数据调研机构IDC正式发布《IDCMarketScape: 中国DevOps云市场2019,厂商评估》报告。京东云凭借丰富的场景和实践能力,以及高质量的服务交付和平台稳定性,取得优异的成绩, 跻身“Major Players”(核心厂商)位置
京东云DevOps能力起源于自身的业务实践,针对京东集团的复杂业务场景打造并经受住屡次61八、11.11电商大促的严峻考验,保证了高效高质的交付和对变化的灵活应对。可以支持复杂场景的自动化运维需求、实现工具链产品与平台化产品结合,帮助客户根据不一样的需求灵活定制方案。

前两次的专题内容中,咱们分别与你们分享了大型企业级监控系统的设计以及监控系统的可观测性与数据存储。今天,咱们将经过介绍京东云DevOps落地实践,和你们继续分享DevOps中另外一个重要内容:日志查询服务。前端

日志查询服务,是构建软件项目的基石之一,是系统稳定运行必不可少的一部分,已然成为DevOps中的标配选项。这里,咱们来聊一聊京东云翼DevOps平台的日志查询服务实践。linux

本着客户为先,全心全意为用户服务的原则,云翼日志查询服务的发展分如下几个阶段解决用户的日志需求:缓存

场景一:用户须要查看本身的应用日志,以此来判断本身的应用程序当前运行是否正常,或者在遇到问题时,须要经过查看应用输出的日志信息来定位问题。

针对用户的这个需求,咱们开发并提供了现场日志查询功能安全

何为现场日志?就是案发现场的日志。案发现场通常在哪里呢?固然是用户应用部署所在的主机了。并发

咱们提供现场日志查询的功能,用于查询用户主机上的应用日志。该功能默认支持规范目录下的日志查询,且支持扩展的自定义路径。app

  • 规范目录/export/Logs/$appName/$instanceName/,在用户主机这个目录下的日志文件,会自动列到页面,用户选择要查询的文件进行查询便可。$appName 表明用户的应用名称;$instanceName 表明应用部署的实例名称。
  • 用户自定义路径举例/export/test.log,因为这个路径对咱们系统来说是“不规范”的,用户若是须要查这个日志信息,就须要本身手动输入该日志路径,而后再执行查询操做。

现场日志查询文件选择示例图运维

如何实现现场日志查询功能ssh

想一想通常咱们本身要查看主机上的日志是怎么作的呢?第一步每每是ssh登陆到主机,而后经过grep命令查询指定内容。是的,咱们的现场日志就是将这一过程进行了平台化,用户在现场日志页面上选择要查询的日志文件,输入要查询的关键字,点查询按钮便可。出于安全性考虑,ssh认证咱们采用密钥认证而非密码认证。固然了,既然经过ssh链接,那就要求用户主机必须开放22端口。分布式

现场日志经过ssh查询遇到的问题工具

好比有的用户的主机是在VPC里的,ssh直接访问不到,怎么办呢?想一想办法这个问题是能够解决的,那就是配置代理,这样就致使渐渐地要维护一堆的代理配置。

改进措施

随着云翼内部新的控制系统zero的出现(zero是一套控制系统,经过给用户主机上的zero-agent下发任务实现对用户主机的一些操做),现场日志查询有了新的实现方式,能够经过调用控制系统API,用控制系统下发任务的方式来实现日志查询,这样采用http的链接方式替代以前的ssh,再也不依赖密钥,也再也不须要再维护一堆的ssh代理配置了。嗯,感受一下清爽了好多。

新的困境

改变实现方式后,发现一个新的问题,就是用户单条日志太大的状况下,查询数据量若是超过zero-agent一次传输数据量的限制会致使查询失败,这里就须要作个权衡了,要么用户调整日志长度,要么减少一页的数据展现条数,再要么能够考虑换一种查询方式,好比用下面将要介绍的历史日志查询,固然了,这只是权宜之计,历史日志功能并非为了解决这个问题才产生的。


场景二:用户的应用部署在多台机器上,用户须要对多台机器上的日志进行集中检索,且作日志检索时不但愿消耗本身机器上的资源(好比带宽、内存、CPU)。

为此,云翼的历史日志查询功能应运而生。咱们指望历史日志支持最近7天的日志检索。

既然要集中检索,那咱们首先须要及时把日志数据采集走,进行集中存储。这里须要用户作一个日志订阅的操做,其实就是告诉日志服务要采集哪一个应用下的哪一个日志文件的数据。

日志数据流向图:

上图反映了用户订阅后,用户日志数据的流向状况。能够看到数据存储涉及两种介质,一种是kafka,一种是ES,数据先缓存到kafka,最终流向ES。ElasticSearch简称ES,是一个开源的分布式搜索引擎,咱们的历史日志查询功能正是借助于ES强大的搜索能力实现的。

下面依次介绍一下上图中的log-agent、fwd和indexer模块。

  • log-agent,是云翼的日志采集客户端,部署在用户的应用主机上。它能够动态发现用户的订阅信息,实时采集日志数据并将数据上报给fwd模块。log-agent内部封装了rsyslog,经过控制rsyslog的配置以及程序的启停来实现对用户日志的采集。rsyslog是linux上一款比较成熟的系统日志采集工具,咱们拿来采集应用级别的日志,固然也是能够的。
  • fwd,这个模块负责接收log-agent上报的数据,并转发至kafka。它的价值在于解耦了log-agent和kafka,避免了成千上万的主机和kafka直连;当kafka有变更的时候,咱们只给有限的几台fwd作修改和升级便可,不须要对全部的log-agent作统一的升级了。
  • indexer,该模块能够被看做一个数据搬运工,负责把日志数据从kafka搬到ES。indexer的本质是rsyslog,它的输入是kafka,输出是ES。是否是发现rsyslog很强大?这个模块虽然简单,但很重要。曾经一度使人特别头疼的是它常常罢工,要么吃内存,要么假死不干活。它不干活,ES就得眼巴巴等数据而不得,ES没数据,历史日志就查不出内容,这个问题简直太严重了。通过反复排查分析,最终发现是因为action队列里的消息出队太慢致使的,在对rsyslog的队列配置反复作了几回调整后,这家伙终于肯乖乖干活了,好开心。有时候并非现成的工具很差用,而是咱们不会用。

ES索引介绍

ES存储离不开索引,最初咱们的索引是按照天的粒度来建立的,一天一个索引,例如:index-log-2019-10-21。可是随着日志量的增长,按天索引,每次查询时,搜索范围太大,会致使一次查询特别慢,用户体验很是很差。为了提高查询效率,后来就把索引改为了小时粒度,例如:index-log-2019-10-21-13

索引时间如何肯定

看完ES索引介绍,有人可能会有疑惑,既然是按时间索引,这个时间具体是怎么取的呢?从用户的日志消息中解析的吗?不是的。用户的日志,时间格式各不相同,从用户日志中解析时间显然是不现实的。

难道是按照当前的搬运时间来肯定索引?这样的话,在数据处理不及时,kafka消息有积压的状况下,用户日志中的时间和索引的时间就极可能不一致了呀,好比15点的数据,可能会放到16点的索引中,这样在搜索15点的数据的时候是搜不到指望的数据的。

这里要说明一下,咱们log-agent采集的每条数据,除了日志内容外,都会带有一些元信息,好比部门名称、应用名、日志文件路径,time时间戳等,这里的时间戳记录的是日志采集时的时间,因为是实时采集,这个时间和用户应用日志中的时间能够看做是几乎相等的。在索引数据前,先解析出time时间戳,经过这个时间戳来肯定具体的索引。这样即便在kafka消息有积压的状况下,也能保证日志数据能够正确存放到指望的索引中。

历史日志查询示例图

历史日志面临的问题

随着日志量的增多,有一个比较尴尬的问题,就是ES存储资源会出现不足的状况。这是一个须要咱们和用户一块儿努力来解决的问题。


场景三:有的用户以为本身应用的日志比较重要,但愿可以长久保留,好比三个月、半年……当忽然须要某天的数据了,能够经过日志服务将数据文件下载下来进行查看。

针对这个用户需求,咱们的作法是将用户的日志按照日期进行存储,而后在前端页面提供日志下载功能,供用户根据须要进行查询和下载指定日期的的日志文件。这里咱们抽象出的功能叫日志下载

日志下载功能的实现思路

日志下载的前提和核心是将零散的日志信息合并到文件进行长久存储。

以前咱们将采集到的数据存放到了kafka,数据源有了,接下来就是把数据拉下来进行合并存储的问题了。对,期初咱们选择的存储介质是HDFS(ES是检索利器,且存储成本过高,用作长久存储显然是不现实的)。

为此,咱们写了一个Spark job的程序,起了一个consumerGroup从kafka消费数据,因为对实时性要求不高,咱们用Spark Streaming的方式,每隔两分钟,进行一次数据拉取,而后进行离线计算。因为一条消息的元数据中包含采集时间戳和日志路径,咱们很容易肯定一条日志该追加到哪一个HDFS文件中。最终经过httpfs从hdfs下载日志文件。

用HDFS做为存储,随着日志量的增长,资源不足的问题便呈现出来了。最终,咱们把存储目标锁定到了京东云的对象存储OSS。固然了,初期的将数据计算后存储到HDFS的工做仍是颇有用的,接下来的工做就是把HDFS上的文件下载导入到OSS,而后生成OSS下载连接提供给用户就行了。这样HDFS至关于中转的做用,文件不须要保留过久,只要肯定数据已经转存到OSS,HDFS上的文件就能够删除了,这样大大缓解了HDFS的存储压力。

日志转存(HDFS->OSS)遇到的问题及解决办法

在作日志转存至OSS的时候,咱们遇到一个问题,好比用户的日志文件比较大,用户可能在本身的主机上作了日志切割,可是因为咱们把数据采集后,变成了kafka中一条条的日志消息,咱们至关于再把这一条条的日志消息从新合并到一个HDFS文件中。把一天的日志合到一个文件进行存储,有的应用日志打印比较频繁的话,最终合成的这个文件就会比较大,有的甚至超过了100G,这样无论是从HDFS进行下载和仍是压缩上传至OSS操做都会比较耗时,并且磁盘空间占用也比较多。对于用户来讲,下载一个大文件进行处理也会是一件比较头疼的事情。

为了解决这个问题,咱们调整了spark job处理逻辑,实现了HDFS文件切割,确保单个HDFS文件大小不超过1G。这样一个大文件就被拆分红了多个小文件。对多个小文件进行并发转存,这样总体效率就大大提高了。压缩后的文件,通常不超过300MB,这样用户下载也会快不少。

日志下载功能示例图

OSS作持久化存储后,有一个缺点,就是因为须要转存,没法实时下载当天的日志,不过这并非一个特别急迫的问题,由于当天的日志彻底能够经过前面介绍的现场日志查询或历史日志查询功能来进行检索查看。


场景四:特定存储需求 - 用户说,个人日志数据不想交给你作集中存储,我想本身保存,而后用来作分析,你帮我收集到指定地方就行了。

这确实是比较典型的用户需求,为了知足用户的这个需求,咱们开发了自定义日志目的地的功能。

自定义日志目的地,顾名思义,就是让用户本身来指定将日志存放到哪里,而后用户在作订阅操做的时候,指定这个目的地名称便可。

目前支持的日志目的地有两种类型:fwd和kafka。

  • fwd类型,要求提供目的地服务的域名和端口号,且目的地服务支持RELP协议,RELP是一种比TCP更可靠的传输协议。
  • kafka类型,须要指定kafka的broker和topic。

从使用状况来看,目前kafka类型的日志目的地占绝大多数。


至此,云翼日志服务的几个主要功能就介绍完了。从整个过程看,日志服务是链接运维和开发之间很好的桥梁,日志中几乎包含了运维和开发所关心的一切,也完整呈现出了应用程序在线上真实的运行状况。云翼的现场日志查询、历史日志查询、日志下载、自定义日志目的地这四个功能互相补充,能够知足用户在不一样场景下的使用诉求。

目前京东云监控提供免费服务,点击【阅读】,了解更多关于京东云监控的内容。

欢迎点击“京东云”了解更多精彩内容

相关文章
相关标签/搜索