如需转载请联系听云College团队成员小尹 邮箱:yinhy#tingyun.com
去哪儿网运维开发工程师张悦于中国应用性能管理大会发表了题为《去哪儿监控系统实践》的演讲,现场解读去哪儿网运维团队基于开源项目Graphite+Grafana+Nagios二次开发了监控系统Watcher,用来支撑去哪儿百万级别的监控指标,全自动化感知、部署万级别规模机器监控,半自动化处理业务监控。
一、背景
首先来看一下背景。我们应该都知道,系统或者说服务,通过开发、测试、发布,成功上线之后,并不是就大功告成了,可能你觉得可以保证代码正确,但是万一你服务器挂了呢?再比如更惨一点,像左上角这个图,万一机房失火没了,这可能比较极端但至少能证明我们并不能保证它完全没有问题。
再比如像左下角的这个图,这是我拿告警的系统举的例子,假如说通过压测事先知道告警系统能够支撑的告警量最大是10万,假如说就是红色的位置我们通过一个告警数这样一个指标的趋势就可以提前的发现,然后提前做扩充或者优化,可以明显看到它优化前后效果的对比。
综上说的这些,正是我们为什么监控的原因,归纳一下,就是以下四点:
第一个是实时告警,比如说像服务器挂了,服务访问不了,网络不通了,第一时间通过告警发现问题,并通知相关人员处理,这个是实时告警。
第二个是提前预警,通过监控指标,当前或者是历史的一个数据,去提前的规避一些隐患。
第三个是追查问题,像日志监控。
第四个是容量规划,比如说做扩充前后或者优化前后的对比。
我们曾经用过一些工具,比如Cacti Nagios,但是因为Cacti存在一些问题:首先最致命的是它是单点的,一旦出了什么故障恢复起来时间比较长,这段时间之内,我们监控系统是不可用的。打一个不恰当的比方这个时候我们其他的系统就相当于是裸奔一样。
再就是无法横向扩展,单机的磁盘容量有限,随着指标越来越多,我们就不得不通过压缩ARD文件换取空间,查看历史数据的时候就不够准确。监控可视化做得比较弱,没有对外提供API,很难基于它做二次开发。
我们各个业务线,每个业务线都各自维护一套Cacti,一方面原因是因为它们需要独立的空间,另外一方面还是无法独立扩展,所以说一台Cacti无法满足所有业务线的需求。
二、选型
所以我们基于Cacti使用中的问题以及实际需求,设定了以下的目标:首先监控系统必须高可用、易扩充,不能像Cacti一样去查看历史数据的时候,数据就不精准了,所以数据的准确性一定要高。再就是加强监控可视化部分,希望可以想怎么看就怎么看。然后开始进入到选型,主要还是放眼开源社区,对比了Open TSDB 和Influx data,还有 graphite。
Open TSDB的话我们的需求再就是支持Tags同时还需要HBase的运维,相对来说比较复杂,而且函数有限,只支持比较基本的简单的函数计算。
我们后来又看Influx data,当时不稳定所以这个也Pass掉了。
后面我师傅找豆瓣的黄教授咨询了一下,他们推荐graphite,我们基于它做了测试,RRD,存储上是基于文件,相对来说运维就比较容易,比较简单。当然最重要的一点还是因为它的设计每一层都是可以横向扩展的,是完全分布式的。
当然也有问题,指标多的话,会导致存储空间的骤增,因为它跟RRD一样,事先指标空间是固定好的。我们在实际过程中,通过提前预警,提前的扩容来保证这个。还有频繁的IO,随机的读写,所以需要SSD的支持,虽然说需要成本,相对来说我们还是可以接受的,所以最终选定了graphite。
所以Watcher就是基于graphite,还有它周边非常活跃的可视化的工具Grafana Nagios完成的。
三、Watcher架构演进
下面详细介绍一下Watcher的设计,还有架构的演进。
最初一开始这样的架构就是V0.1版本,这块是多台的Carbon relay做一个冗余,即使有一台机器有问题,也不会影响服务,可以正常提供服务。对这个指标的名称做hashing,可以保证指标每次进来的时候保证落在相同的两台机器上。
下层的Carbon relay收到指标,再转给Carbon cache然后是whisper,如果你的容量不足,就继续往这边加机器就可以了,同时每一台Carbon 上需要布一个graphite-web的服务。这个就是第一个版本,上线后我们开始收集监控数据。
上线一段时间之后,随着指标越来越多我们就发现了一些问题,图渲染的非常慢,可以看到上图这里列的,这个区域指定了很多个,当时每个机房搞一个,需要指定多个集群。
为什么会慢?我们仔细看了graphite-web的时线,在配置里面有一个地方需要在这里配置上所有集群中Carbon 地址,下面是这一块时线的代码,就是一个简单的循环,找你对应的指标数据返回过来。如果指标越来越多,指定的位置也越来越多就会非常慢。
所以首先我们直接干掉了graphite-web,重写了graphiteApI替代掉它,一方面是因为慢,另外一方面是因为graphite-web提供一个Web页面也没有存在的必要,所以第二个版本是这样做了一个调整。
红色的区域就是第二个版本做的一些变化,首先可以看到,在Carbon relay发给下一层的同时我们做了一个relayindex出来,通过查询DB找到指标所在的Carbon机器,直接到上面取数据就可以了。
这样改动后性能上明显提高,速度明显加快了。但是第二个版本上线之后,又遇到了新的问题。
偶尔的会丢数、断点,看上面的监控图经常是这样断的。其实通过抓包的时候去看,已经看到数据到了下层的Carbon 上面,但是就是没有写入到whisper里面。查看日志看到发送队列满了,归根结底就是因为建轨的GIL问题,CPU达到100%就会对新来指标做一个丢弃,就会导致前面丢数,周期性断点。
所以在此基础上我们又进化到第三个版本。
在这个区域的问题可以看到这块只起了一个单个的事例,之所以选择这样是因为我们在上一层往下分发的时候,需要在这个位置给它指定一个分发的地址,因为我们是要想打两份数据,你如果在这个位置Carbon relay起多个实例,在本机上起一个HAPROXY就可以了,目前跑了有大半年时间,暂时没有什么问题,还是蛮稳定的,这个就是整个架构的演进版。
四、监控可视化
下面说一下监控可视化的部分。前面也提到了Dashboard是基于Grafana的特点二次开发的:
丰富的图形和样式
很好的适配 Graphite Functions
Templating、Annotations…
除了丰富的图形和样式以外还很好的适配了graphite的函数,操作函数的时候非常方便。它的模板变量可以在你的监控图上设置一些事件,这是它本身自带的一些我们看中的特性。
当然我们基于它还做了很大的改造,扩展了很多功能,这里列了一些主要的:
树形组织结构
用户&公共空间
版本记录&回滚
复制粘贴
多维度展示
分页
接下来看一下多纬度展示,首先是机器纬度的展示。
在这里通过一个表达式列了两台机器查看CPU的监控数据,可以通过表达式输入多个机器,或者在应用的纬度看一个应用节点下多台机器的系统级别的监控。我们也在这边列了很多模板,像CPU、Load等等这些,还可以查看宿主里面所有虚机的状态。
再就是应用纬度,从应用节点的纬度检索指标。
再就是自定义纬度,对于可以抽象出来的东西我们都会定制一些模板,但是对于一些变化的,不同的我们也支持自由定制,可以通过一些函数对原始的指标做一些计算或者是聚合,或者其他的渲染,然后放在你的自定义的Dashboard里面。
这个就是监控可视化的部分,同时我们也在不断完善监控指标,从不类别区分,像系统级别、中间键,还有业务指标。系统级别涵盖了最基本的CPU、Load这些,中间键像QPS、MysQL等等这些。我们收集了越来越多的指标,有什么用?目标还是要结合起来去更好的定位、去发现问题。
这里举前两天的一个现成的例子,看下图。
当时有一个需求把一些接收到的指标分发给另外一个系统,想要拿到这些指标再做一些处理,但是发现两边数据不一致,我发送的很多他那边是没有的,通过我记录一个指标发送的量和记录的指标接收的量,周期性有差异,第一个图就属于业务逻辑层的监控。追查服务的日志并没有看出来什么问题,但是结合机器的系统级别的监控指标,发现它的内存只要是在它丢数的不一致的时间点都是因为内存吃满了,所以说这个是系统级别的监控,我们收集这么多更全面的监控指标,就是为了快速的排查和定位问题。
五、告警
最后说一下告警,告警这块我们有很多的指标,它可能在工作日周一到周五的时候阈值是一个样,周末的时候偏低。比如网站的访问量或者订单量,可能白天相对比较高,夜里凌晨的时候比较低,很难设定恒定的阈值对它做告警,所以需要不同时间段设置不同告警规则的功能。
再就是告警联系人,可能一个小的组内需要做一个排班,可能按一天排班或者按一周轮班,所以提供了支持排班轮巡的功能。通知方式上也是尽可能多,像电话、邮件、短信,尽量保证告警一定要送达,不会漏掉。
再就是升级策略问题,以及告警回调,做一些基础的可以自动处理的功能,包括临时规则,在发布的时候或者下线的时候,告警规则是有一个时效性的,区别于你平时的告警规则,所以需要这样的功能。
这里列举了一下告警的特点,举两个比较常用,也比较好用的告警的策略。
第一种就是通过环比上周或者是昨天预测一个阈值,像这个图里面,这个蓝色的线,就是当前这个指标的一个值,红色的就是通过环比上周,或者是更久之前的数据,去计算出来的一个最大的值。黄色是最小的值,这样的区间,如果这个指标在正常区间内,就认为它是没有问题的,如果超出区间就及时的告警。这个是很常见的需求,比如说一些很周期性的监控但是又不能够用一个恒定的阈值设置的时候,就可以通过这种方式设置告警。
还有一个就是对于骤增、骤减的告警。上面绿色的线就是一个监控指标,可以看到这个位置突然间骤增了,我们通过下面的方式,实现上非常简单,现成的函数就可以了。这个比较常见的我们会给机房流量加上这样的告警,避免被攻击突然间流量骤增。
刚才说了这些以后再从大的块上看一下Watcher整个数据的走向。首先在数据采集上,对于系统级别的,我们会给区分,比如说collectd收集监控数据,Windows的话会部署SSC Serv来收集监控数据主动上报,这部分都是做到自动发现自动部署,全自动上报监控数据。
我们使用自己开发的Qmonitor Server,在收集数据这块的门槛比较低,一个简单的NC命令也是可以把监控指标打进去的。第二个部分,用一个graphite代表着整个Watcher后端集群,用来收集监控数据做一个存储。最右侧就是通过从graphite里面去读取数据,做数据的展示以及告警,这是数据的走向。
六、总结
最后来总结一下,首先看一个我们现在的现状:
基础监控指标500+
600w+系统级别监控指标 (24T)
200w+业务监控指标 (24T)
每分钟1600w指标上报
基础的监控指标这个是单机的,单机的种类是500到1000,系统级别监控指标远远超过600万的数据,存储上大约有24T的数据,业务监控指标有200多万,存储上也是24T,因为力度不同,所以大小一样。每分钟会支持1600万指标数据,这个数据会不断增大,因为后面架构可以横向拓展,如果撑不住了继续加进去就可以了。
我们的监控系统从用户的角度无非就是告警和可视化,告警就是为了提升服务可用性,还有减少故障的损失。在可视化的部分,通过各种详实的监控数据,为他做分析以及决策做依据。
从运维角度第一点容量上一定是可以水平扩展的,因为监控数据很庞大,而且会与日俱增,一定要能够水平拓展,而且扩容的时候是不能停机的,必须在线扩容,不能在扩容的过程中去影响它正常的提供服务。
监控系统的稳定性一定要高于任何其他的系统,所以在稳定性上不能有单点。选择成熟社区的经过考验的方案,但是不一定选择graphite,在选择的时候尽量是周边工具链比较丰富的方案。
在效率上一方面是对我们自己来说,有丰富的运维工具,比如说在迁移、扩容的时候,能够更加的快速不需要手动,包括在减少人工的干预,只要能够自己去处理的我们尽量让它自动化起来。这一部分,我们还有很大的提升空间,也是我们正在做,就是更智能的告警。
Q&A
Q1:请问你们如何动态的调整告警预警?另外是每分钟处理1600W条数据,通过环比和同比不断分析,针对这么大的数据量怎么处理?
张悦:先说一下环比,就是graphite自带的函数就可以实现,就是一个平移跟当前的值做一个差值,给这个值设置一个告警就可以了。现在是1600万指标的上报,并不是所有的指标都会设置告警,告警上面能够批量操作的就批量操作,但是还有很多没有办法抽象出来,普遍就是需要自动设置的这些,并不能完全在业务上面做到完全自动化。
Q2:我刚才看咱们架构的时候有没有考虑两个东西,第一个有可能要补采,假如没有采过来怎么补采?第二个问题,咱们在指标收到跟输出有差值,这是怎么串起来的?
A:假如说它在打指标的时候因为一些原因网络什么问题没有打进来,他是可以再去覆盖一组数据。graphite本身支持对历史数据的补采就像之前遇到的场景,我们有一个日志解析的系统,运算的速度非常慢,后来导致很多数据堆积没有发出来,可能不是在当前时间段发出来的,通过后面计算才可以把数据再覆盖出去,这个也是可以的。
关于APMCon2016:
中国应用性能管理行业盛宴——2016中国应用性能管理大会(简称APMCon 2016)于8月18日至19日在北京新云南皇冠假日酒店隆重召开。APMCon由听云、极客邦和InfoQ联合主办的作为国内APM领域最具影响力的技术大会,首次举办的APMCon以“驱动应用架构优化与创新”为主题,致力于推动APM在国内的成长与发展。