V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
TencentCOC
V2EX  ›  推广

腾讯 SNG 监控数据的创新应用

  •  
  •   TencentCOC · 2018-08-14 16:39:05 +08:00 · 1815 次点击
    这是一个创建于 2054 天前的主题,其中的信息可能已经有所发展或是发生改变。

    作者 | 吴树生 : 腾讯高级工程师,负责腾讯 SNG 大数据监控平台建设以及织云多为监控,近十年监控系统开发经验,具有构建基于大数据平台的海量高可用分布式监控系统研发经验。

    监控是运维领域的重要组成部分,我们把监控形容为运维的眼睛、耳朵和嘴巴。整个运行的质量状况要靠监控来发现异常,通过告警来通知大家。在这里,我将向大家分享 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 的每一个维度。

    算法是可以模拟人的操作,但是怎么去判断成功率的这个权重呢?我们是参考了微软的一篇论文。分析完异常之后,我们可看到空间点播业务异常,找到一些访问码,需要客户端的同学去查相关代码,拿到这些信息还是不够的,还需要日志。

    在这个异常的点相关的信息上,我们跟日志挂钩,跳转到日志的节点来看,这时候就有足够多的信息来支持开发去定位和快速恢复问题。

    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2736 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 12:42 · PVG 20:42 · LAX 05:42 · JFK 08:42
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.