监控是运维领域的重要组成部分,我们把监控形容为运维的眼睛、耳朵和嘴巴。整个运行的质量状况要靠监控来发现异常,通过告警来通知大家。
在这里,我将向大家分享SNG 监控十年来变革背后的驱动因素和立体化的监控方案,最后给大家展示最新的智能监控的应用场景。
1. IDC异常案例
给大家分享一个最近的真实案例,2018年春节前的最后一个周末2月10号凌晨6点29分,已有同学休假回家,大部分人还在被窝里熟睡的时候,深圳某个机房的机架掉电。
直到7点20分,负责机房的同学才告诉我们机房的温度异常升高。
26分的时候反馈温度异常原因是空调故障,需要几个小时的恢复时间。
来看一下我们的业务监控。6月21分业务视图告警通知到业务运维同学,6点30分,在10分钟之内把相关业务的运维同学召集起来,启动了大范围故障处理流程。
虽然业务在天津、上海和深圳这三地有容灾策略,为了保障业务的有效运行,在6点50我们评估出影响的范围,决定启动业务迁移。7点40分受影响的业务全量恢复。
可见,告警的及时性和数据的准确性,对保障业务质量发挥了重要的作用。
一开始我做网络管理系统OSS,当时管理1万个节点的网元和交换机,就觉得这是很牛的事情。
当进入到互联网的监控领域,管理的服务器的数量和节点数量达6万个节点,系统已经不堪重负,经常出现误判的情况。
我们花了大量时间做服务器监控的优化,对架构进行重构升级,到现在已经管理了20万个节点。
在做完升级后,又踏上了移动化的浪潮,因此基于大数据体系做了应用层的监控。
当做完这部分,发现应用层监控能最快、最直接反应业务质量的,它是从应用层的角度去发现问题,触达用户,是最全面的用户体验,比下面两层的准确性更高。
现在的业务场景都会做相关的容灾设备,服务器挂一个其实不会影响业务,但是到底有没有影响业务,从下面两层很难判断。由
此我们建立了从整体到局部的立体化全链路的监控体系。
监控在DevOps里面的应用,随着我们运维理念的变化而变化。一开始监控主要为运维服务,对运维的质量负责。同时也关注业务质量的变化,监控开始触及产品发布这个环节。对业务质量负责的同学不仅仅是业务运维,一个产品的好坏,开发同样承担了重要的责任。
产品如果失败了,整个开发团队也就失败了。因此开发也开始来关注业务质量的监控数据,并且通过监控数据,对线上的业务架构进行优化。
从设计到开发的流程,我们监控贯穿了整个的DevOps流程体系。
2. 三大驱动力
跟大家谈一下背后升级的三个因素。一开始,我们的服务节点跑在腾讯自研的IDC环境,机器大部分是实体机器,做的监控主要是网络监控、服务器监控以及DNS、http,对我们的业务来说,机器量已经足够多了。
当我们走入到“云”环境的时候,需要管理的节点数量量突然剧增到20万,仅仅一年时间服务节点从6万到20万。
以前在独立的IDC的类似私有云环境运行的时候,管理的对象的标识可以用IP作为唯一标识,当我们进入到私有云环境,还涉及到海外的机房,也会去采购其他厂商的云服务,用IP已经不能唯一的标识一个服务节点了,这时候就涉及到混合云如何标识一个服务节点的问题,这就促进了整个监控背后数据模型的变化。
另外,在这么多服务器节点里面,如何去准确的定位出问题,做一个集中化的操控,这个因素驱动了整个服务监控的架构升级。
这张图是监控系统的微服务架构,对顶层提供了单机和视图两个存储服务,对外提供了数据查询的接口,在这个基础上构建了画图服务、告警服务、统计服务。
这个架构里面表现出来的问题在哪些地方呢?我们的底层服务要考虑到容灾和背后的特性,至少要准备这个情况,下面的各服务节点的服务实例和量非常庞大,我们必须通过事务流的角度来看,来明确获知某一个请求是否异常。
右下角是UGC流程,从博客的发送到Web接收、到数据存储,经历了3个节点,这里面涉及到多台服务器,要查一个问题变得非常困难。
2010年移动化开始出现,到现在已经完成了移动化的改造,大家使用的频率已经从PC和Web时代转向手机,体验发生了根本的变化,打开一个APP超过10秒时间基本上就会放弃。打开一个APP看视频,如果频繁的出现卡顿,会造成用户剧烈的流失。
对我们来说,关注的指标从当时的成功率到了用户体验,采集的数据量也发生了巨大变化。
我们对服务器进行监控管理20万个节点,数据量还可控。当我们要处理2亿用户的数据的时候,监控系统架构需要做相关升级和改造了。
另外,国内的移动化环境造成了我们需要有多维度的场景。
国内的网络至少有移动、电信和联通这三大运营商,他们的网络是割裂开来的,并且各自的网络质量不一样,需要关注运营商的质量,还要关注我们发布的版本对机型的要求,这对多维度提出了更高的要求。
3. 立体化监控方案
这张图是我们建立的立体化覆盖体系。最下面是传统监控使用的OS服务器网络的监控。
在它之上是对数据层进行相关的数据访问性能的采集。中间是逻辑处理和Web层,都可以纳入到服务器体系来。
新增的是用户端监控,包括卡、慢、多维和舆情监控。舆情监控做的事情是:对于腾讯的QQ体系来说,有一些用户可能会打腾讯的投诉电话,会对用户的反馈进行记录并做相关的文本分析,建立异常的指标,发出业务告警。
立体化监控数据如何采集,需要注意哪些地方?对于用户端监控来说,关注最多的是H5、http的响应,DNS查询耗时、TCP链接耗时等等。有很多开源的方案,把指标采集上报到接入端,也做了一个插件去采集CGI的响应情况。
上面是靠用户数据来驱动,另外还有拨测,是我们业务主动的行为。在每个厂商的IDC机房都部署了拨测的服务,对这些CGI建立拨测任务,通过拨测的方式采集CGI的响应时间和不同厂商机房的CGI响应时间,这样就可以在第一时间知道上线的服务是否正常。
服务端监控有两种方式,被动采集和主动探测。对于主机通过主动探测SNMP和IPMI的方式探测是否正常。
主机运行的服务用了侵入式API上报方式,类似于业务埋点,只需要上报一个特性,经过这个行数的次数或者处理分支的次数。API上报会对业务性能产生影响,本来代码能跑10几万qps,监控上报之后降到5万,相应的成本就增加。
这要怎么解决呢?我们在上面做了共享内存,上报的时候直接写内存,数据采集使用原子操作,定时10秒一次的采集数据,报到后端的接入机,这样API的调用次数可以达到7000万。也就是说,这种方式对程序性能的影响是最微弱的。
右上角是是单属性的上报,这里我们看到只上报了一个特征值,可以用10多台服务器扛住20万台服务器的上报量。对于多维度的上报,如右下角,是用多个key来组成一个维来上报。
这对后端带来了新的挑战,这里key的组合数比上面单属性成倍的增加,还用10多台服务器就扛不住了。对于多维的上报,key和指标的聚合计算放在上报端的机器去做,API上面会按1分钟的维度做聚合,聚合之后通过Agent传出去,流量降了接近一半,性能可达80万/秒。
对于数据层的监控,我们最担心的问题是数据存储不均匀,也就是解决数据倾斜的问题。这一块的数据采集没有啥办法,只能依靠存储自身内置的特性来采集。
上面说了下数据采集,接下来总结一下织云监控的理念,最核心的是建立数据银行。数据银行要做到普适性,因此数据银行的模型就必须要足够抽象。我们建立了三类数据模型:
- 第一类模型是海量KPI指标的TSDB存储引擎,可以达到每秒万级别请求的毫秒级响应;
- 第二类模型是海量多维的OLAP-TSDB存储引擎,它的复杂度比前面要求高很多,只能做到秒级的响应;
- 第三类模型是海量日志存储引擎。
我们在内部做完预研和应用,把场景提炼出来,然后再传递出去。接下来跟大家介绍一下我们的数据银行是怎么做的。
KPI型的TSDB,所有的数据都可以抽象几个特性,一是时间,二是监控对象是什么,这个对象可以有很多个指标来表达,所以我们把指标称作特性。对象的值通过四个属性来表达,就是KPI的对象数据存储模型。
当我们把这个场景用于服务端监控的时候,业务模型监控的对象是单机或者单个虚拟节点。我们的业务是分布式的服务,所以在单机上面还要再聚合成业务视图。整个存储数据上报之后,会先把数据写到单机的内存里面,只保留2天的数据,做热查询。据我们统计,80%的数据应用查询都是查询2天内的数据,因此每天会定时的存储到文件上。
另外,我们还建立了对象和特性的存储结构。数据层和数据应用层分离,提供proxy和worker的架构,数据计算层使用了类MR的方案来提供高效率的数据查询,也就是万并发下面的毫秒级查询。内存的数据存储采用了多阶hash的共享内存结构。
OLAP的数据模型关的时间、对象拓展,拓展成一个维度的概念。举个例子,某一个运营商的客户端IP,可以被认为是运营商的维度,客户端的请求还带有相关的版本信息,以及对应接收段IDC的信息,这些信息都是维度。
指标就是客户端的请求和请求的响应时间。由对象扩充到维度,前面一天百万级的对象可以存储,现在有30亿的维度组合的数据怎么存呢?这时我们选的是druid查询。采用druid做存储,有以下几方面考虑:一是存储成本低。
更重要的一点是,我们监控系统的维护对象的减少,druid只有5个组件维护对象,而基于Hadoop体系,涉及到维护对象成倍的增加,对于监控系统开发人员来说,这些组件的学习成本也是不可承受的痛。对于这一块,我们不仅仅是用,还做了相关的优化,一是压测之后的druid调优,二是容灾优化,三是控制成本。
我们做LOG的时候是采用相关的开源组件来存储业务上报日志,当业务渐渐上线的时候,发现开源的方案扛不住。
大家知道,开源一开始用的时候很爽,但是深入去用的时候,需要不断的去改它的BUG,这会导致投入到开源里面的时间比自己写的时间还要多,成本高。假如说数据量是100T,用了开源的方案,加上索引的数据,数据量至少要乘上1.5。
为了解决性能和成本的问题,我们自研了一个LOG的查询存储服务。数据进来之后,它会按照key做查询的分片,先放到数据缓存。如果直接写入磁盘,磁盘也存不住,所以加了数据缓存,先把数据按照1M大小缓存成一个块,然后放到服务器上,相关的块的分段和数据放到这里面来记录。
数据读取的时候,怎样做到秒级的数据响应和低延迟的数据查询呢?延迟是在数据缓存这一块,因为要缓存1M的数据大小,如果上报的数据量小,需要等待很长时间到文件存储。
为了解决这两个问题,一方面数据会从文件服务器上拿过来,另一方面会从缓存模块提取数据。建一个数据过滤模块,专门负责数据的解压和查询。
对于这种方案,首先做到技术上的把控。二是架构上面维护对象和模块要足够少,毕竟一个团队的精力有限。三是成本,经过这样处理存储成本降低了,查询性能也有提升。
我们的数据如何处理呢?在SNG里面有各种考验,上报的数据格式多样,大多不是规范化、标准化的,毕竟前面有十多年的技术架构发展,相关的方案也不能够统一。
除了监控成本,还要考虑效率,我们对整个过程做了数据的抽象,也就是数据的翻译、过滤、统计、告警等功能,通过配置化的方式去实现,再转化成页面的配置化方式,提高效率。
也就是说,我们对一个业务的支持,之前需要专业的开发大数据开发同学一周时间完成开发,现在减少到产品开发同学半小时完成业务监控的数据处理配置。
这里有几个比较有特色的点:一个是消息队列,我们之前用Kafka,由于磁盘和机器不稳定,消息队列变得不稳定。
后端数据处理流程如果异常了,若消息队列在,会把之前挤压的数据重新消费,要重新启动,系统恢复时间需要三十分钟。
现在我们采用的方案是建设稳定的后端,如果后端异常,以前积累的数据都是可以抛弃的,我们要保证后面的数据。数据落地存储之后,数据银行提供一个查询的API网关。
刚才提到,对数据模型处理进行抽象。它的数据模型是如何建立的?所有的数据都可以表达为原子数据列表,比如一行数据的第几个字段,数据名称是什么、数据值是什么,把这个成为原始单元,然后去过滤、聚合和转发,对这四类操作进行抽样处理,最终依赖的其实是Storm数据传输能力。
这里有一个好处,假如哪一天Storm不再维护了,我们开发的这一块代码还可以用新的框架去跑,因为它并不强依赖Storm的特性,仅仅用了Storm的传输特性。
我们几大平台有monitor特性监控、哈勃多维监控、全链路日志和告警平台,其上都建立了统一的API层。在这个基础上,各个业务运维团队去构建场景化的监控。
统一API之上的东西是大有可为的,运维的经验沉淀就是最上面的这部分,并不需要掌握下面那么专业的大数据处理的工具,把上面的场景开发构建起来。
4. 智能监控应用场景
谈AIOps,数据是前提,先得把数据银行构建起来。有了数据该怎么用、可以怎么用?我们对监控目标进行全新的定义和阐释。
- 全。要做到无盲点的覆盖,刚才我列举的立体化监控体系里面,每一层都要有监控。现在新的监控需求来了,要求的是全链路的监控,每一个请求、每一个处理节点都需要链路的状态信息。
- 准。我们一直在强调怎么做到无误告警,监控系统误告太多是有原因的。这时候我们除了做到无误告之外,还要把异常根源给推导出来。
- 快。我们追求的是数据的低延时,告警发现的速度快,分析也要足够快。
告警检测传统的做法是通过阈值检测。阈值检测有什么问题呢?
- 第一,告警不准。我们统计了,告警的业务故障自动发现率40%。大家通常是敲着代码再看监控系统有没有异常,还会出现漏告警或者误告警,阈值告警无法解决这个问题。
- 第二,维护困难。业务的发展,需要持续开发代码,业务发生变化,配置得不到变更,必然会导致大量告警出现。
- 第三,告警量大。我们曾经人均一天收100条告警。有部分同学个人的告警量达到1000条,一天有1440分钟,每一分钟都是在收告警,手机的耗电量和流量是很大的。
这里涉及到无监督算法,我们的张戎博士会给大家分享下的。
告警里面如果带上根源,此异常是根据某个数据服务异常导致的,处理效率会更快。从这张图上看,告警异常的出现一定有时间相关性。
发生告警之后,异常的曲线和状态也是出现的时间点,各种监控系统处理的告警密度和时延不一样,但是这个持续的时间是相近的,因为有时间相关性。不仅如此,还要知道链路的调用关系。
这个调用关系怎么去做的呢?刚刚提到的微服务理念有模块的调用关系和路由调用关系,我们有配置信息。
没有微服务的系统怎么办?通过定时抓包的方式,也能获取到网络的流量关系,再加上业务经验和人工清洗的功能,以及一些AI算法,整理出一个带圈中的调用关系对,里面会叠加时间相关的告警,然后推荐出告警根源。
异常根因分析这个案例应用在多维监控的场景。之前我们对成功率进行判断,因为大家标准一样。
我想说为什么运维的AI那么难做?
图片的AI和语音的AI有一个特点,就是标准是一样的,与我们人眼的视觉评判标准是类似的。而业务运维的AI难做,因为每个业务的异常业务特性是不一样的,也就是标准是各异的。
成功率的好处是成功率的标准是一致的,所以可以找出异常维度的组合。
但是,不能只满足于这个反馈,会出现请求量卡顿数的异常,我们要扩展到累计量的指标。异常分析推荐出来的准确率,要考虑到总量的权重和异常的权重。
还有一点是性能,我们通过算法去计算出某个异常,没法像广告系统那样做离线计算,跑一个算法,等着晚上出结果,对运维来说,我们希望能做到秒级的响应。
因此,对于异常根源的分析挑战,一是通用性,二是准确率,三是性能。
上面介绍了三类应用场景,已经能够覆盖我们大部分运维监控的应用。接下来给大家讲一下我们运维智能监控的具体案例。
上面这张图是我们经常看到的一个KPI的曲线,也就是成功率的曲线。
在这里8月31号21点发生了一个异常,如果这个数据的基点不是从97%看,而是从0开始看的话,是看不出这里有异常的,它仅仅掉了2个百分点。
这是非常棒的,即使2个百分点或者零点几个百分点的下降,我们也能够识别出来,并且还能识别出微小下降的原因。
上面的是如何做到的呢?靠人工的办法,首先由全局从大到小的概念去看,先选一个最少的维度来看,看下面的成功率哪个掉了。手机QQ的成功率在这个时间点最低,同时总的请求数占比最大,毫无疑问,先分析手机QQ的每一个维度。
算法是可以模拟人的操作,但是怎么去判断成功率的这个权重呢?我们是参考了微软的一篇论文。分析完异常之后,我们可看到空间点播业务异常,找到一些访问码,需要客户端的同学去查相关代码,拿到这些信息还是不够的,还需要日志。
在这个异常的点相关的信息上,我们跟日志挂钩,跳转到日志的节点来看,这时候就有足够多的信息来支持开发去定位和快速恢复问题。谢谢大家。
原文发布时间为:2018-08-02
本文作者:吴树生
本文来自云栖社区合作伙伴“高效运维”,了解相关信息可以关注“高效运维”