大型互联网公司海量监控系统设计

"鹅厂网事"由深圳市腾讯计算机系统有限公司技术工程事业群网络平台部运营,我们希望与业界各位志同道合的伙伴交流切磋最新的网络、服务器行业动态信息,同时分享腾讯在网络与服务器领域,规划、运营、研发、服务等层面的实战干货,期待与您的共同成长。

网络平台部以构建敏捷、弹性、低成本的业界领先海量互联网云计算服务平台,为支撑腾讯公司业务持续发展,为业务建立竞争优势、构建行业健康生态而持续贡献价值!

(一)背景

近些年来,随着互联网的迅猛发展,各大互联网公司的服务器数量不断膨胀,如今十万级别的服务器规模,已经不再罕见。再加上虚拟化技术的成熟,每台物理服务器可以虚拟出多台虚拟子机,虚拟子机也会当成物理服务器进行监控,因此监控的机器数将是一个更庞大的数字。海量运营,监控先行,设计一个能支撑百万级海量服务器监控的系统,提升每人运营机器数,将成为海量服务器运营的关键。

(二)需求

2.1基础性能数据采集

如同厨师做菜必须有食材一样,监控系统首先也需要拿到原材料——基础性能数据。服务器的基础性能数据包括如CPU使用率、CPU负载、内存、磁盘容量、网络IO、磁盘IO、ping探测状态等周期性上报数据,还包括在服务器上检测进程端口存活性、系统重启、硬盘只读等产生的原始告警数据。采集到的数据,汇聚到中央,进行数据的存储与告警分析,再通过多种维度的图形化界面展示,让运维人员可以对服务器的基本运行情况了如指掌。

2.2自定义监控项上报通道

基础性能数据可以覆盖常见的监控场景,但对于业务运维人员来说,经常需要进行一些自定义监控项的采集。一种是数值型数据,例如运维人员想监控某个进程的一个内部变量值,如用户在线数。作为公司统一的基础架构监控系统,显然无法直接支持这种自定义监控项的采集,但可以向业务开放自定义监控项的上报通道。业务侧可以在进程里调用上报通道的接口,把用户在线数上报到监控系统,这样监控系统就可以对用户在线数进行图形化展示以及告警检测。另一种是字符型数据,例如有时业务运维人员会写脚本进行一些异常监控,当出现异常时可以调用上报通道的接口直接上报告警。

监控系统的上报通道屏蔽上报细节、屏蔽与短信网关、自动语音系统等的交互细节,把简单的接口提供给业务人员实现上报。运维人员首先在监控系统为上报的数据申请一个唯一的ID,然后在进程或监控脚本中调用接口,使用这个ID来上报数据。这样,业务运维就可以在监控系统查看该ID的曲线图或字符型数据。同时,还可以为这个ID设置一些告警策略,当符合某个告警规则时发出告警通知。

2.3告警

假设我们需要对某个进程的存活性进行监控告警,如何实现呢?运维人员可以写一个脚本,定期扫描进程,一旦某个进程不存在,则调用短信接口进行通知。但这种刀耕火种的方式,存在很多问题:

1、一旦进程不存在,每个扫描周期都会产生告警短信,大量的短信降低了告警短信的价值,而且可能淹没其它重要告警。

2、如果需要临时停止监控,只能逐台机器停掉脚本;继续启用监控时,又需要逐台机器启动脚本。

3、有时需要过滤掉抖动类的告警,例如希望在进程持续一段时间不存在的情况下才告警,对进程停止但很快又自拉起成功的告警希望忽略。

……

如果服务器数量少,这种方式可能还扛得住,但对于海量服务器,是无法接受的。因此海量服务器的监控,需要有一个统一的告警平台,可以根据各种告警策略进行检测,对原始的告警进行屏蔽、去重、合并、收敛等处理后,最终只发出最有价值的根因告警。

2.4数据分析

作为海量服务器的监控系统,每天可以收到大量的基础运营数据,这些数据蕴含着巨大的商业价值,对这些数据深度挖掘,可作为一些决策的参考依据,如机型选型、资源匹配、故障预判、流量计费等,这对于降低成本、提升可靠性有着重要意义。

监控系统的基础运营数据,也会通过数据转发、API调用等方式开放给公司各个业务的运营团队,结合业务自身工具与运维体系,将能最大程度发挥数据价值。

(三)实现难点与解决方案

3.1采集层

3.1.1 实现难点

采集层是整个监控系统的根基。为支持数据采集,并向业务开放上报通道,保持最大的灵活性,我们通过开发一个运行在服务器上的agent来实现。而海量的服务器带来的海量agent,使采集层面临如下挑战:1.稳定与安全agent运行于公司赖以生存的海量服务器之上,若因agent异常而导致大量业务服务器故障,将造成严重事故。因此稳定与安全永远是第一优先级2.海量agent接入对于百万级的agent,显然无法通过一台服务器来支撑所有agent的接入。一方面,我们希望能利用尽可能少的服务器完成海量agent的接入,另一方面,接入层需要可以支持平行扩展,即使支撑千万级agent,只需要扩容接入点即可,无须对整个架构做大的修改3.海量agent管理海量的agent显然不能依靠人工来进行管理。需要有一套完善的系统来实现海量agent的自动化管理4.非扁平网络理想的网络世界是扁平的,但现实中,经常会出现因为某些网络限制,或是安全上的考虑,或是业务的特殊需求等,导致网络不可能扁平。采集层需要适应各种特殊情况来支撑监控。

下面来看看如何应对这些挑战3.1.2

agent设计

如何设计一个稳定安全的agent?Unix的一个哲学,便是一个程序只做一件事,保持简单。当程序保持简单,足够的内聚,便可将复杂度降至最低,易于维护,最大可能地避免BUG。基于这个原则,我们对agent基于功能进行拆分,把agent拆分成一组高内聚,低耦合的进程,包括:

1、主控进程:提供上报通道,负责数据上报,升级管理。

2、采集进程:负责性能数据采集与原始告警检测。

3、调度进程:负责对agent插件的调度。

进程之间通过共享内存解除耦合。主控进程生成一块共享内存,并提供共享内存操作接口,采集进程采集到数据后,只需要调用共享内存操作接口,把数据扔到共享内存即可,无须理解数据上报到服务端的细节。数据的上报完全交给主控进程来完成。通过共享内存操作接口,实际上也是向业务开放了数据上报通道。业务进程需要上报一个性能数据,或是上报一个告警,只需要调用共享内存操作接口即可。有时候运维人员需要自己写脚本,实现一些自定义监控项的采集。但这会涉及到一个脚本部署的问题。如果这个脚本需要部署在大量服务器上,没有自动化运维工具支持的话,将是一个繁琐的过程。因此agent还实现了插件机制,运维人员的自定义监控项采集脚本可以作为agent的一个插件来实现,提供了良好的可扩展性。

3.1.3 agent接入

为实现大量agent的接入,服务端进程接入collector尽可能保持简单,只做数据转发,不负责数据处理。而agent只是周期性做数据上报,连接大多数时间是空闲的,因此这种场景非常适合使用epoll来实现。接入collector内部使用内存消息队列将数据接收和数据转发解耦,可达极高的吞吐量。单台接入collector可支撑10W agent的接入。

尽管接入collector性能极高,但对于百万级的agent,需要实现分布式接入。一般会按地域搭建接入点,每个地域的接入点负责收集该地域所有agent的数据,再转发到下一级模块。这种分而治之的思想,使得agent接入可以平行扩展,任何时需要扩容,搭建新的接入点即可。

因为接入collector只做数据转发,不做数据处理,使得collector支持级联。通过级联,可以适应非扁平化网络。假设某个网络区域出于安全性的考虑,只允许少量机器对外通讯,这种限制会导致大多数机器的agent无法连接collector。针对这种场景,可以在允许对外通讯的机器上搭建collector,让该网络区域所有agent都上报到这个collector,再利用collector的级联能力,把数据转发到普通网络区域的collector,达到数据上报穿透的目的。

3.1.4 agent管理

程序总是需要增加新功能,或是修复BUG,agent也一样不可避免需要发布新版本。而对于百万级的agent,显然不可能人工进行版本发布,必须有一套自动、高效、安全的方法来实现agent版本的管理。agent的版本管理需要具备如下功能:

1.版本记录记录每个agent的版本,知道哪台服务器运行着哪个版本的agent,这是我们进行版本升级的决策基础

2.自动升级需要进行升级的时候,只需要配置升级规则,就可以在短时间内无须人工介入地自动完成版本更新

3. 灰度部署agent运行在至关重要的服务器上,每次发布都必须严格控制风险,因此必须具备灰度能力。升级时,支持先小范围对非重要服务器进行更新,稳定运行后再逐步更新到其它服务器

4. 版本回退如灰度过程发现BUG,需要很方便地支持agent版本的回退

5. 安全性为保证下发文件的完整性与安全性,升级进程和agent需要对版本文件进行严格的校验

3.2存储层

agent上报的数据分两种,一种是数值型数据,如当前的CPU使用率、流量值等,这是一种时间序列的数据;另一种是字符型数据,即异常时上报的告警。字符型数据会经过告警平台的去重、合并等,最终存储下来的数据量并不大,直接使用关系数据库存储即可。而数值型的数据则会大得多。agent会周期性上报服务器的各种基础性能数据,再加上业务自定义监控项的采集,平均每个agent上报的指标个数可达50-100左右,上报频率在1分钟-5分钟之间,每秒需存储的指标个数在50W以上,百万级的agent每天可以产生的100G以上的数据。告警系统、各个业务系统会频繁访问agent最新上报的数据,进行大量的告警分析和统计,因此还需要提供高性能的查询能力。

传统关系数据库如MySQL很难支撑如此大量的数据的读写。因此,我们需要设计一个分布式的时间序列数据存储系统。在存储机上,使用共享内存+文件的方式来保存数据,共享内存提供热点数据的快速查询、更新能力,文件则提供数据的持久化。文件的存储上,基于时间序列数据的访问特点,合理设计索引,并将索引数据内存化,使得能以最少的随机读盘读写次数来得到数据。分布式设计上,设计了高效、分布均匀,易于扩容,具备容灾能力的路由规则,数据写入和查询时,根据路由规则命中到对应的存储机上。这样设计的分布式时间序列数据存储系统,达到了高可用、高性能,并具备良好的平行扩展能力的要求,得以支撑海量agent数据存储。

3.3告警层

3.3.1 实现难点

告警平台作为整个监控系统最核心的部分,直接关系到监控的可靠性、稳定性。如何对海量告警进行去重、合并、相关性收敛,做到不误告警,不漏告警,还不能多告警,并具备高可用、易扩容、易扩展特点,是一个巨大的挑战。

在功能需求上,告警平台需要具备如下功能:首先,告警平台需要支持各种各样不同类型的告警,例如针对服务器的Ping不可达告警、磁盘容量告警、流量告警、进程端口告警等,针对业务的自定义监控项的告警,还有针对网络的各种流量、质量告警等。告警平台需要进行这些告警检测,产生原始告警。

其次,海量的服务器每时每刻都有大量原始告警产生,显然不能每出来一条告警就发出一次通知。因此除了原始告警检测,告警平台至少还需要具备下面的功能:

1) 屏蔽:日常运营中不可避免需要对某些可预知的告警进行屏蔽。

2) 去重:当一个告警通知负责人后,在这个告警恢复之前,负责人不会希望继续收到相同的告警。

3) 抑制:为了减少由于系统抖动带来的骚扰,还需要实现抑制,例如服务器瞬间高负载,可能是正常的,我们可以不关注,只有持续一段时间的高负载才需要重视。

4) 恢复:运营人员不仅需要知道告警的产生,还需要知道告警什么时候恢复。

5) 合并:有时需要对同一时刻产生的多条告警进行合并,例如某个服务器同一时刻出现多个不同进程的告警,需要把这多个进程告警合并成为一条进程告警。

6) 相关性收敛:有时某个告警产生时,往往会伴随着其它告警。例如某个服务端进程不存在而产生进程告警时,会伴随着一些端口告警,对于一个智能的告警系统,应该只需要通知进程告警,而剩下的端口告警则会被收敛,作为该进程告警的子告警。当某个机架所有服务器都Ping不可达时,应该只需要发出一个机架掉电告警,机架上服务器的Ping不可达告警作为该机架掉电告警的子告警。

在质量需求如下,告警平台还需要具备如下特点1)高可用:作为海量服务器监控的核心,告警平台的关键功能必须达到5个9的可用性,做到不误告警、不漏告警,不多告警,只有这样,才能让运维人员对告警平台产生信心,保持对告警的警惕性。因此,告警平台每个子模块都必须有完备的容灾、容错能力,单机故障时可平滑切换到备机。甚至当出现地震、海啸等不可抗拒自然灾害时,也可平滑实现异地容灾。

2) 易扩容:告警系统每时每刻都会有大量的原始告警产生,还需要进行各种屏蔽、去重、恢复等的判断,单机无法支撑如此海量的告警分析,支持平行扩展的分布式系统是必经之路。

3)易扩展: 随运营精细化需求,随时都可能需要支持新的告警类型,因此当有新的告警类型时,需要能非常快速方便地接入,复用整个告警屏蔽、收敛、去重、合并的通道。

3.3.2 架构设计

在架构上如何设计整个告警系统呢?因为整个告警环节多,链条长,为降低系统复杂度,提升可维护性,可以将整个告警流程进行多个维度的拆分:

1) 对告警流程纵向拆分,形成流水线。每个告警子模块接收上一个流程过来的数据,处理后,发送给下一个流程的告警子模块处理。

2)对每个流程环节的告警子模块横向拆分,每个流程环节都可以运行多个告警子模块,模块之间互相负载均衡。

3)对告警逻辑的拆分,每个告警子模块只做一件事,单一职责。例如,告警屏蔽模块,只处理屏蔽的处理,告警恢复模块,只做恢复的判断。

同时,引入消息队列,使告警子模块之间的通讯异步化,解除告警子模块之间的耦合。

最后,引入全局高可用Cache,所有内存数据均放到全局Cache,使每个告警子模块不带状态,形成无共享架构(Share Nothing Architecture)。

这样的设计带来很多好处:首先,每个告警子模块高内聚,低耦合,非常方便维护。其次,这种搭积木式构建的系统,功能易扩展,即使需要在告警流程中增加一个环节,只需要增加新的告警子模块,整个系统架构无须改造。而且,带个告警子模块都是无状态、负载均衡,可平行扩展的。某个环节出现性能瓶颈,多运行几个告警子模块即可,达到了监控海量服务器的能力。

3.3.3 相关性收敛设计

告警平台设计的另一个难点是告警的相关性收敛。假设某个机房掉电,必定出现大量的Ping不可达告警。相关性收敛需要对这种情况做出识别,收敛成一条大规模故障告警,而所有的Ping告警则作为该大规模故障告警的子告警。如果没有相关性收敛逻辑,运维人员将被淹没在大量告警中,根本无从判断故障。相关性收敛对于快速得到根因告警,提升告警处理效率具有重要意义。

实际运营中存在大量的相关性收敛逻辑,如端口告警可以被进程告警收敛,交换机下服务器Ping不可达告警可以被交换机Ping不可达告警收敛等。如果直接把这些收敛逻辑加入到告警流程,告警流程将非常复杂庞大,且难以维护。因此,告警相关性收敛可以采用“旁路反馈机制”,它的原理是由单独的模块分析相关性,再将结果反馈给收敛模块。收敛模块仅仅是一个收敛处理引擎,不负责分析相关性。这样避免了收敛分析串行化的性能和功能扩展的难题。要增加新的相关性规则,只需开发和平行部署新的分析模块即可,不会影响到当前的收敛策略。随运营经验的沉淀积累,以及业务的发展、监控手段的增加,可以逐渐加入新的相关性分析模块,使告警平台更加智能化。

(四)腾讯实践

基于上面的思路,腾讯网络平台部实现了针对海量服务器监控的系统Tencent Monitor Platform(简称TMP),具备支撑百万级服务器运营监控的能力。

采集层,通过Agent进行数据采集,打造跨越非扁平网络的数据上报通道,实现百万级Agent的自动化运营管理。

存储层,通过自研的分布式时间序列数据存储系统,实现海量监控数据的存储与快速查询。

告警层,基于无共享架构,纵向拆分告警流水线,使用消息队列异步通信,逻辑链解耦,实现了各种告警的合并、去重、相关性收敛,打造出一个高可用、易扩容、易扩展的告警平台。

注1:凡注明来自“鹅厂网事”的文字和图片等作品,版权均属于“深圳市腾讯计算机系统有限公司”所有,未经官方授权,不得使用,如有违反,一经查实,将保留追究权利;

注2:本文图片部分来至互联网,如涉及相关版权问题,请联系judithliu@tencent.com。

原文发布于微信公众号 - 鹅厂网事(tencent_network)

原文发表时间:2015-09-18

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏腾讯移动品质中心TMQ的专栏

腾讯TMQ在线沙龙回顾|Android App质量监控及工具应用实战

42750
来自专栏Python专栏

不要在问Linux优化从何入手了,好好看看

作为一个程序员,性能优化是无法避开的事情,不管是桌面应用还是web应用,不管是前端还是后端,不管是单点应用还是分布式系统,并且性能优化也是软件系统中最有挑战的工...

18540
来自专栏北京马哥教育

十分钟看懂时序数据库(I)-存储

2017年时序数据库忽然火了起来。开年2月Facebook开源了beringei时序数据库;到了4月基于PostgreSQL打造的时序数据库TimeScaleD...

678120
来自专栏SDNLAB

SDN世界里,网工需要哪些技能?

网络工程师需要学习新技能和使用自动化工具才能适应软件定义网络(SDN)的工作环境。 听起来似乎很难,但是网络工程师都很聪明。我们往往必须处理一些大型复杂网络,它...

36480
来自专栏北京马哥教育

面向容器技术资源调度关键技术对比

摘要:本文以资源分配理念:拍卖、预算、抢占出发,引出Borg、Omega、Mesos、Kubernetes架构、数据、API的特点比较。然后梳理资源共享各种不同...

43470
来自专栏哲学驱动设计

《架构师》反思:系统可靠性

最近系统学习了一个系统可靠性及其相关知识,今天在这总结一下。 首先,什么是系统的可靠性呢?系统的可靠性是指在规定的时间内及规定的环境下完成规定功能的能力,也...

38250
来自专栏测试开发架构之路

程序员面试之软件测试面试问答

1、问:你在测试中发现了一个bug,但是开发经理认为这不是一个bug,你应该怎样解决? 首先,将问题提交到缺陷管理库里面进行备案。 然后,要获取判断的依据和标准...

604140
来自专栏web前端教室

实际演示,怎么搞一个demo的业务逻辑、需求分析?

今天是周日,今天晚上20:00的时候,咱们进行了每周日都会有的先行者视频直播课程,主要内容是,通过一个实例,怎么去分析它的需求、设计它的js的结构。

26520
来自专栏SDNLAB

基于OpenFlow架构的IaaS云安全

编者按:云计算技术的服务型基础设施即服务(IaaS),以其可扩展性、高效性及弹性等特点正在成为资源利用的主导方式。在从云计算的IaaS应用获得便捷的同时,安全漏...

31730
来自专栏云计算D1net

云技术如何改变业务灾难恢复计划?

尽管业务灾难恢复计划转向云计算,但传统灾难恢复(DR)的关键要素,如位置和测试仍然很重要。 在过去几年中,人们已经逐渐放弃了一种被动的业务恢复计划,那就是采用...

29960

扫码关注云+社区

领取腾讯云代金券