十年前我到腾讯的时候,运营部刚成立,正好开始做 DO 分离这件事情,研发和运维开始分离了,由专门的团队来做运维这件事情,但当时没有太好的运维解决方案和思路,所有的东西都需要靠自己摸索,监控就是其中最大的一个困难点。当时我们主要还在做“补功课”,补齐各种基础的监控指标和能力。直到 12 年之后业务开始面临到了很多新的挑战,高速发展的业务和移动化的进展加快,让我们面临的监控难度也越来越大,所以开始有了很多监控相关的新的尝试。
我们的运维说简单一点,主要在做三件事情。第一个就是控制业务架构:空间、QQ、QQ 音乐这些服务架构是怎么部署的。第二个,自动化能力:各个团队,各个公司在自动化运维,智能化运营,精细化运营,包括现在很火的 DevOps,都算是自动化能力的体现。第三部分就是监控能力。这也是运维三个不变的主题之一,也是今天主要讲的,聚焦在这里和大家一起来探讨一下。
先抛几个数据。我们现在有将近 20 套监控系统,指标有将近 300 多个,监控的实例超过 900 万,最可怕的是我们每天有近 5 万条短信告警,人均 500 条。去年收告警最多的运维,一天能收 1500 条短信,收告警比较多的研发同学,每天也有 1200 条短信。不知道大家有没有体验过这种感受,手机里面一天有 1000 条短信过来,这是很让人崩溃的一件事情。
首先要先简单介绍一下我们正在做的监控,从 06 年开始到 14 年,我们的监控围绕着三个目标:“快”,“准”,“全”。大部分建设基本都是围绕这三个目标去做事情的。首先要求我们的告警能够覆盖很全,能主动发现用户的各种犄角旮旯的异常,为此衍生了各种各样的监控手段,这就是为什么目前我们会有 20 套监控体系。其次我们希望告警非常快,一出问题马上发出来,同时希望告警准,误告警少。目前每天有将近 5 万条告警,人均几百条,说明当前告警是不准的。能不能解决好这件事情?可能就成为了在监控领域运维的一种技术和一种艺术。后面分享的几个比较有意思的小创新,就是它融入了很多老运维同学的运营艺术在里面。
这是我最近刚刚更新的数据,可以看得到我们每天的监控实例非常的庞大。从 09 年开始,当时只有几套监控,随后每年都在增长,在 14 年后开始有一些减少,主要是 14 年开始,我们自己也开始在检讨了,发现为了完成快、准、全这三个目标,去建各种各样的监控系统其实不持久,很多建设都只是在解决“点”上的问题,并没有体系化解决“面”上的问题,并没有深层次挖掘其中的关系。所以开始有计划的去做减法,适当裁减了一些系统。
快速进入到今天的重点,最近我们又做了哪些不一样的“新”事情。说到创新,这么多的监控系统,存在必有它的合理性,我们去建设新的创新并不是要否定过去监控系统的存在,主要还是希望通过解决历史中一些不合理的架构演进,用一些创新的方法,让我们的监控能够朝真正的快、准、全这个方向去发展,而不是局部优化或者推翻重做这样子的一个思路。所以下面的一些创新的方法,可能大家会发现运用的技术并不是特别牛逼,可能不是特别了不起的算法。
第一个就是代号 Root 的项目,意在找到造成告警的故障根源。这个项目从 12 年我们就开始做,在 14 年的时候在业界分享过。这个是基于业务架构,结合数据流,通过一些算法,能够将告警进行分析、筛选,从中发现出有价值的告警,推断出造成告警的故障根源。
因为我们刚才提过,我们有 5 万条告警,其实腾讯的业务总体服务体验还是很好的,至少没有让人感觉有特别多故障,为什么出现一方面有 5 万条告警,另一方面好像服务质量还行?可以肯定的有大量的告警是重复和无效的。我们启动建设 Root 智能分析的目的是希望能够解决这个问题。
第一,我们需要能够了解业务架构,这也是运营上的一种思路,“基于业务架构去运营”。在我们的内部里面,是会对一些核心服务架构进行梳理,比如绘制出架构图来,维护并运营起来。
第二,有了架构图,我们可以比较方便地去获取架构之间的访问关系,有很多手段。同时 20 套监控系统中有大量的数据是带有一定的逻辑访问关系的,从中做一些简单的筛选,就能够获取架构中的访问关系。这个图是实际的系统截图,红线就代表里面有大流量,灰线代表里面流量比较低,是非常容易做得到的。但是这里也有个问题,架构是网状的,人肉眼来看是很难去区分这里面到底和谁有真正直接的关系,或者说告警发生的服务,和告警的故障根源服务到底是怎么样的关系。
我们用一些简单的算法进行“降维”,比如上面的网状业务访问关系,可以通过有向的穷举的方式抽取成链条状,形成服务访问关系链。然后将各种告警往上叠加。我们将各种各样的告警叠加在这个业务架构的链路上面去,比如说当某一种告警产生的时候,就往链路上去叠加,其他的告警类似处理,循环着继续这样去处理,最后你会发现访问关系链路上面已经叠满了各种告警。在同一个时间片范围内就可以开始去分析,根据运维的检验,可以推测出架构中哪一条链路或者多条链路的故障现象和故障根源最有可能发生。
我们假设告警和故障根源的关联在数据上是有一定的关系,这个关系可能是一种相近性,我们认为两个服务之间的告警隔的非常近,那么互相产生影响可能性会非常的大,把我们全部业务进行这种降维处理后,大概有四百多万条链路进行计算,当告警发生的时候,就很容易通过一些算法浮现出最有可能的告警根源是哪里?
过去我们很苦恼,每个新的告警对我们的工作都会造成骚扰,但基于 ROOT 这样的方法论上,我们发现告警越多越好,告警越多越能够帮我们去把这个关联做得更精确。
这张图是我们的系统展现,比如说从这里把告警进行一些叠加,中间可能隔开了,也许它自己没有接入告警,或者自己的告警并没有和这个问题现象相关,这是很常见的一种形态。那我们开始算,首先这个算法就会在一定的时间片范围内,它有一定的范围,大概前 15 分钟,后 5 分钟,因为告警本身自己就会有发送和接收的延时,我们在这里会取前 15 分钟,后 5 分钟的时间片,认为这个时间片范围内的告警才有关联度。第二个部分就是时间相关性,底下这个服务它每天都在告警,那么其实它的时间相关度是非常低的,它和这条告警产生根源故障的关联也非常的低,属于脏数据应该剔除掉。这个算法里面会把这部分的数据作为一个垃圾剔除掉,这个垃圾就是我们刚说的 5 万条告警。
也有人挑战过这个问题,你们为什么不去把它梳理一下?把这个梳理干净了不就很准了吗?我们也想做这个事情,但是那个包袱实在是太重了。当前我们已经没有办法去把所有的脏数据通过人工梳理的方式去掉了,只能够通过一些额外的算法分析出这些脏数据存在的干扰,能够把它过滤掉。这个里面就是通过一些时间相关性和时间片的范围,然后通过链路关系和时间关系,一起来决定准确性,这也是我们在寻求告警关联分析准确度上的一个探索。
我们将告警分成了原因告警和现象告警,原因告警才是造成那个故障的根源,现象告警可能只是故障的结果,其实看不出来故障根源在哪里。
举例说,用户 QQ 里面不能发消息了,往往不一定是 QQ 有问题,很有可能后面数据库宕掉了。在一个多运维团队协同分工运营体系下,前端负责人很多时候不知道后面那台数据库宕掉了,所以现象和结果往往是关联不起来的,我们这个方法是希望能够做到这一点。
第二个部分,我们将告警分成持续性告警,波动性告警,关联性告警。“持续性告警”属于脏数据,往往是不重要也不紧急的,我们认为不需要立刻去处理。“波动性告警”也是处理起来比较纠结的一点,很多告警会被监控发现,但故障一下子恢复,指标很快恢复,这种告警应该去区别对待,可以根据业务的重要性去做处理,服务如果重要那么可能就要处理分析一下;如果不重要,站在我的立场,我觉得可以不处理。
我们会更加去关注“关联性告警”,它是有因有果,就应该立刻去处理。有一个简单的数据,这是最后的结果,我们发现那 5 万条告警里面,有 65% 属于持续性告警,不是那么重要,可能不一定真的要把它清理掉,但是对于告警分析来说没有那么重要。波动告警又占到了 24%,也就说我们有将近 1/4 的告警,只是发生了一下故障很快就恢复了,无论是作为运维,还是作为研发,还是作为技术化团队里边的 QA,都没有必要在这里面去投入过多的人力或者精力,这种波动告警是我们这个体系里面应该过滤掉的。最后一部分,只有不到 10% 的告警才是真正能够去关联出原因的,有现象有原因的,这部分告警才是最重要的,我们需要重点去关注的一部分告警。
后面是简单的一个算法,这种链路怎么去判断权重,哪个应该告警,哪个应该不告警,这里有个简单的面积算法。简单解释一下,根据告警连续,如果一连续它的长度就加,如果不连续它的纵向就减,最后算出一个简单的面积来。
比较典型的例子,就像这种,同样是 7 个节点的一条链路,同样是有四个告警叠加的,最后算下来面积它们的面积是不一样的,算出来会发现很有意思,非常准确能够分析出关联性,关联性越大的,它的面积一定是最大的。最新的基于AI的新算法已经落地,具有更高的准确性。
代码很简单,分享给大家。
16 年初我们开始做 DLP,很有意思,它的英文就是 Dead Live Point,有人很难理解,这个和监控有什么关系?当然前面提到,我们有 5 万条告警,每个运维都要收好几百条,到底运维应该收哪些,到底研发应该收哪些?怎么分工才合理?
我作为运维团队的负责人经常会参加一些故障的复盘会,故障复盘里面会要求写改进措施,基本上第一条就是告警太多,告警被忽略掉了。大家常常会问:这个故障有没有告警?一般来说,我们 20 多套监控系统在观测故障,大多数情况下告警都可以发现,但往往告警都被忽略掉了,没有人看的过来。说明一个现象,就是我们的告警泛滥已经成为我们发现和解决故障的一种致命的骚扰,所以在这里面,我们很迫切能够去区分出到底哪些是最重要的。DLP 是我们能够去区分哪些告警应该去立刻处理,哪些告警可以缓一缓,或者有分工的处理。
DLP 这衡量业务生死的指标,它有几个要求:
第一,这套告警体系里面是不允许有阀值这个概念的,比如说你告诉我告警超过三次,你就要告警,No,在我们这里面是不允许,比如说业务访问量正常情况下大概每天 1000 万量,跌下来了,比如跌到 800 万,你就得有告警,No,在我们这里也不支持。在我们这里面不允许用阀值,在我们这里面只有一个指标,就是成功率。
第二,一个服务只能有一个生死指标,为什么会有这么样一个奇怪的要求?我们服务只有几万个,为什么会有 900 万个监控点?举个例子,我们有的服务会有超过 400 个监控点来监控这个服务的各种纬度运行状况,比如说它打开 Linux 文件句柄数,内存使用量要监控,磁盘 IO 也要监控,还包括很多业务纬度监控,比如业务成功率,失败率,各种访问量、购买量、在线数等等这些监控造就了一个服务可能会超过 400 的监控点,那么当这 400 个监控点有 20 个人关注这个服务,一旦发生告警,这个告警量自然就会很多,这就是为什么会有 5 万个告警出来。所以在这里面,我们“粗暴”的假设,一个服务只能有一个生死指标,就好像一个人死了还是活着,就只有 0 和 1 的选择。
第三,是不建议用业务指标做生死指标,这个也很难理解。互联网产品业务第一,什么东西都是以业务为主的,业务必须第一保障,看指标当然看业务指标,在线数跌了一定是有问题,购买量跌了一定是有问题,这的确是事实,但是作为技术运营线,作为运维,或者说作为最前沿的技术研发,这些指标的一些涨和跌是不是应该马上去处理的?事实是这个指标的涨跌,可能和很多非技术因素有关系,比如说发布原因造成的,比如活动造成的,这些大家都见过,做一个活动,购买量一定会涨,活动一结束一定会跌,但这些指标是不是我们技术运营线要去第一关注的?在我们这个体系里面也是假设应该由产品人员关注而不是技术人员,我需要知道的是这个业务是死还是活着。所以这在里面,我们不太建议用业务指标作为 DLP,业务指标会被我们人为转化成为成功率,比如我们会把购买量和购买失败量两个指标折算购买成功率,用 DLP 来监控这个购买成功率。
有了前面的三个假设,就可以采取一些简单的统计学算法帮助我们发现异常指标,比如我们用的的 3 西格玛算法,拿到环比同比,昨天上周的数据,用 3 西格玛一算就能获得一个波峰区间来,你的业务指标只要在这个波峰区间之内变动的,我们基本上就能够知道这个业务要不要告警了。
上面截图中的每一段文字就是一个监控点,而此截图仅仅来自一个服务。仅仅织云 monitor 监控就有 125 万个指标。这就是为什么我们的告警会有那么多的原因了。所以我们会从这些监控服务中抽出一些关键的指标生成 DLP。
当然我们会对告警做各种各样的数据分析,比如多维数据汇聚。把主调,被调 IP 的聚集度,主调、备调的失败率,错误码、返回码、访问码的聚集度等数据,并结合 ROOT 做的根源故障推荐,给用户一个全新的故障定位分析体验。
这个系统在我们这边目前使用情况相当的不错,都有点出乎我的意料,正式推动这件事情大半年,准确率基本上在 95% 以上,一旦这个告警告出来,基本上就一定有问题,漏告的情况下极少。现在有一些技术团队基本上开始以 DLP 告警为主了,其他的告警为辅。团队开始由尴尬的监控陷阱中脱身出来,故障处理更有节奏了,从突发故障数量的下降就可以明显感觉到。
DLP,Root 虽然不算是个技术上很难的创新,但是对于解决监控告警数量的问题特别有帮助。
最后一个也是我们最近在做新的一个事情,全链路监控。除前面提到 20 多套运维监控系统,我们还有很多其他的数据源,比如有很多产品指标数据,服务器日志数据,用户日志数据等等各种各样的数据源。这些数据以前对我们运维来说是负担,但是现在随着大数据的兴起,我们发现这个数据也是一个宝藏,蕴藏着大量有价值的信息。我们现在在做全链路监控建设,是希望能够去帮助我们数据的生产者、消费者去合理地把数据用起来,能够帮助我们的生产者有办法去消费这些数据,过去是做不到的。
要举个例子大家才能理解什么叫全链路,这个图是 QQ 业务的一个局部服务的架构图,标记 QQ 里面好朋友见发消息的时序,消息在整个腾讯的体系里会经过 51 个步骤,这里面任何一个地方出问题了,都可能会造成丢消息。过去为了监控丢消息这个情况,整个系统中的这 51 个状态点都会去埋点,就是做染色,故障发生时可以很快知道消息到底在 51 个系统中的哪个地方丢掉的,这就是早期的染色监控方式。但随着时间服务架构越来越复杂,产品越来越多,这种方式已经很难推行,特别是站在运维的角度,希望通过这种方式去完成各种业务架构的监控,做不到了,因此“织云全链路监控方式”就诞生了。
我们会把基础监控、特性监控,现网的各种日志,各大系统中的文本类数据等灌到我们的日志中心里去。经过一系列的筛选,提取一些特征,计算一些中间值,形成全连路数据。现在我们也用到一些很多的一些开源组件比如 Elasticsearch 再做一些展现,然后全链路监控平台大概的结构就是这个样子,最终我们希望能够帮助用户去做很多分析。
比如说用户的数据在我们这边,这里一列代表了各种数据源,这个案例是个用户在空间玩直播的案例,它的数据在我们这边由各种不同的数据源上报上来。这里会把所有的数据列出来,把公共特性的值抽象出来做个对比,如果发现用户的一些值出现了异常,就可以去做告警了,可以产生一些新的运维事件,就能驱动产品和研发去改进。
这个事情一开始做的时候觉得也挺困难的,各种各样的日志格式也不一样,数据形式也不同,甚至都有怀疑说这个方式做不做的下去,但是发现不断深入去做,这里面发掘出来的一些有价值的数据反倒是越来越多,举个例子,原来我们都说用户直播的时候卡顿,我们也不知道是为什么,但现在好了,只要这个用户一上来,通过所有的数据汇聚就可以知道他用的什么机型,我们还会收集用户的 CPU,CPU 一直是 100%,很有可能这个机器不是特别高效,比如说它的网络,有的可能在用 3G 玩直播,可能在一些特殊的场景下,比如电梯里面。
我们一个同事在北京机场玩直播玩不了,终端没有任何提示的案例。通过全链路系统我们技术人员一看,很快发现它的 IP 发生了变化,由 4G 变成了北京机场 wifi,故障发生在 ip 切换后。原来他过去有去过北京机场,所以再次进北京机场的时候他的手机就自动连 WiFi,北京机场 WiFi 是要登陆的,但是他自己没意识到,APP 也没有提示,直播自然会失败。
过去这类个案的投诉只能请研发捞取用户的日志来分析定位,而现在运维就能快速定位。整个过程很流畅,比以前快太多了。全链路的数据对于我们运维和技术人员去定位故障非常有帮助,这个项目在我们现在也是主推的一个项目。
后面分享的是一些我们也在探索的部分(201712 月最新的进展已经在织云 AIOps 里面落地,请参考最新分享),所以写的是践行,我相信同行们都在做这件事情,跟大家交流一下,包括几个部分,主要是机器学习相关的。
我们自己总是给自己树一个愿景:咖啡运维,希望我们做运维的坐在那里喝咖啡就行了,花了十年时间还没有到这个目标。
这是我们以前的做法,对数据进行各种各样的分析,大家都用过,各种曲线图对比,这都是老套路,汇聚、对比、阀值、分布、聚类,这个我们都用过,但是帮助有限。
践行机器学习 AI 运维,我们首先试水了文本处理领域,比如说这是“织云舆情监控”,就用了机器学习 NLP 处理。
这个项目还要从一个有趣的例子说起,早年我接触过一个老板,他抱怨说我们的服务质量不好。他的理由很简单,他每天上百度上去搜,有负面反馈,“空间打不开”这几个字,搜索排名第一。因此得到结论,我们的服务质量不行。他不管我们自己的监控数据质量多好,认定外面的舆情是负面的,就认为我们的服务质量不行,所以当时我也很苦恼,这个事情我怎么解决?现在我们有了高雅的解决方法,“织云舆情监控”。我们用了一些机器学习中的自然语言处理 (NLP) 方法,通过对各种渠道收集到的用户的反馈内容进行文本分析,找出异常。
语义分析首先要分词,然后做情感分析,发现到底是表扬我们的还是批评我们的,如果是批评我们的,它的量会不会有波动,正常每天 20 几 30 几,如果突然短暂时间内各种渠道有很多人反馈有问题了,基本上就会有故障,这个语义分析就是我们对机器学习文本这边的尝试,效果还蛮好的,这个现在我们所有的产品团队都在用。
第二部分就是机器图像学习,前面有一个有滚动条的图,大家会发现一个模块下将近有 400 属性,当一旦有问题的时候,它的监控曲线有很多图都是类似的,所以我们也在做图像之间的相似性学习,有 400 个属性没关系,也不判断阀值,就看你曲线长的像不像,我们人很容易判断,机器也能判断出来,这也是个挺好的思路,这对完全告警收敛有一定的帮助。
第三个部分是告诉 AI 规则是什么,通过一些有监督学习的方式,让机器首先去做一些粗判,人工去做一些监督,训练机器,对曲线的形态有准确的判断,对我们的告警检测会相当有帮助。(201712 月最新的进展已经在织云 AIOps 里面落地,请参考最新分享)
前面提到“全链路数据”项目里蕴含着大量的数据宝藏,但这些宝藏目前想要分析出来还相当的困难,这里面全是大量的无规则文本,人肉去做分析难度非常大,机器可以做的到,我们能够做舆情分析,那么对于日志上下文的分析也是有可能实现的。
最后对于监控,除了技术和创新,还有其他值得关注的地方。
过去为了实现快、准、全,我们在监控平台上做了很多的技术优化,但真正运用的比较好的监控还需要持续的“运营”。如何去运营监控有很多的方法论。比如说我们的指标怎么建立,我们的闭环怎么形成,如何建立监控生态,把相关的团队,各个团队全部能够卷进,比如 QA、研发、运维的角色是什么,怎么去定义,包括这些产品的服务质量考核怎么和监控结合起来,并通过运维指标的变化来反推产品质量优化,这都是我们运维团队需要思考的。
最后是一些小的运维经验分享,看着小但对运维效率提升很有益处,值得参考。
比如舆情监控相当建议有能力的团队去尝试一下,相当的准,对于产品的体验来说,产品体验好不好,看数据是一方面,看反馈比看数据还要有效,这是我们切身体会,如果有能力的团队可以考虑一下舆情的监控。
机器的自动处理(服务自愈),运维人力一般不可能有研发和业务增长快速,有很多事情一定要尽早开始实现自动化处理,比如有些基础的告警能够让机器去处理的就应该让机器尽早处理,方法也很简单。
移动运维,还有就是借助方便的手机端处理运维工作,微信还有 QQ 这些工具非常方便,我们现在很多的故障都是在微信里面处理的,在微信可以打开自己的工具,直接就把故障给处理掉了,也很方便。
最后想提一下“告警的分级”。站在运维的角度怎么去做告警分级,和站在研发或产品的角度并不相同,在告警分级这里面有个简单的规则:合适的人处理合适的告警。
第一个是告警它本身就要级别。第二个,时间上一定要分级,比如该什么时间发的,该什么时间不发的,什么时间应该让大家去休息和睡觉的,还有范围也要分级,升级机制也要分级。前面我们之所以有 5 万条告警,在于之前没做好规划,比如一个告警有 20 个关注人,一旦发生问题,这 20 个人都会收到告警,这 20 个人都认为别人在处理,自己都不处理,继续睡觉,结果带来的坏处就是,这个告警没有真正指定到人。所以在告警的一个范围上应该去做些思考的,告警刚刚发生的时候应该发给谁,告警如果一直没有被恢复应该发给谁,告警产生了严重的质量问题后,或者对一些指标数据产生了影响之后,应该升级到什么规模,这些应该在运维体系里面应该去做。
去年 7 月我在 ArchSummit 深圳站上与大家分享了《腾讯海量监控包袱与创新》,当时大会设置的运维专题仍聚焦在 运维新挑战 上,去年 12 月北京站则设置的是 新一代 DevOps,可以看出大家关注的运维技术热点已经快速变化。
今年的 ArchSummit 深圳站策划已经出来了,与运维架构有关的是:不可阻挡的 AIOps。
Gartner 在 2016 年时便提出了 AIOps 的概念,简单来说,AIOps 就是希望基于已有的运维数据(日志、监控信息、应用信息等)并通过机器学习的方式来进一步解决自动化运维没办法解决的问题,同时 Gartner 也预测,到 2020 年,AIOps 的采用率将会达到 50%。
到时候会有哪些新实践?ArchSummit 深圳站的内容,可以点击 阅读原文 进行了解,敬请期待。
点击下方图片即可阅读
容器技术圈已迈入后 Kubernetes 时代