前言
都说监控系统是运维的第三只眼睛,因此一旦线上出问题,业务方第一反应是,监控系统有没有提前告警?是不是告警太多被淹没了?为啥没有把根因报出来?上面的三个质疑,相信做过监控的同学都会深有体会。我做了10年的监控,背锅不少,在2021年的第一天,我想跟你聊一聊我的一些心得。
什么是监控
做监控前,先问自己一个问题。监控的本质是什么?我的理解是监测并实施控制,监测并告警只是第一步,有效的控制才是根本。
- 数据采集:采集的方式有很多种,包括日志埋点进行采集(通过Logstash、Filebeat等进行上报和解析),JMX标准接口输出监控指标,被监控对象提供RESTAPI进行数据采集(如Hadoop、ES),系统命令行,统一的SDK进行侵入式的埋点和上报等。
- 数据传输:将采集的数据以TCP、UDP或者HTTP协议的形式上报给监控系统,有主动Push模式,也有被动Pull模式。
- 数据存储:有使用MySQL、Oracle等RDBMS存储的,也有使用时序数据库RRDTool、OpentTSDB、InfluxDB存储的,还有使用HBase存储的。
- 数据展示:数据指标的图形化展示。
- 监控告警:灵活的告警设置,以及支持邮件、短信、IM等多种通知通道。
所以做监控的最终目的是先于用户发现问题,提供有价值的告警,并闭环解决。
监控1.0
08年刚到WS的时候,CDN业务规模还很小,公司就几百台机器,监控项不到20种。当时过去的时候,阿贤已经把监控系统都搭得差不多了,基本能满足业务初期的监控需求,监测服务器的死活,服务状态异常squid/lighttpd/rsync/snmp。
架构说明:
- pingServer服务端部署在内网,它从CDN平台获取监控组及组对应的监控机,为监控机分配监控测试任务
- wsPoller对测试任务进行远程测试,并根据测试结果产生报警发送至告警平台
- 通过SNMPOID扩展增加监控的采集项
存在的问题:
- 单点策告警,容易误报
- wsPoller无法根据自身的网络、负载自动踢除
- 机器性能监控缺失
- 不支持本地采集
监控2.0
随着客户对服务质量的要求变高,监控1.0的弊端开始显露。09年初,我们决定开发监控2.0。
团队在研究完Nagios、Cacti、Zabbix开源系统后,发现这些系统在扩展性方面,告警运维值班便捷性上满足不了我司的运维需求。
苗辉是当时的leader,这家伙就喜欢自己折腾个东西出来,而我当时心里挺犹豫,有开源的不用,为啥要从0到1自己搞。只是这个家伙"吹牛"还是可以的,把老板说服了,带着4~5个应届生,我们就开干了。单单设计文档我们就整了100多页,方案来回讨论了有1个月,团队苦逼的搞了大半年,alpha版本终于上线了。
架构说明:
- wsmsagent——wsMS的数据收集接口;
- MI——wsMS的数据中转加工站;
- AL——wsMS的告警分析;
- RRDS——wsMS的监控数据绘图引擎;
- SCHEDULER——wsMS自动均衡的决策中心;
- SCADA——wsMS的通用采集监测组件;
- UI——展示界面。
监控3.0
这个系统线上运营了2年,2011年随着机器规模迅速增加到7K+,平台开始爆发出各种问题:
- 机器增加到2万的时候,监控数据单表1天超过5亿条数据,复杂的SQL告警规则查询耗时太长;
- 原始告警移到历史告警通过Insert和Delete,性能太低;
- 通过数据持久化再分析生成告警,已经满足不了实时性的要求;
- 复杂的告警规则通过SQL已经无法支持;
- 新增一种采集类型的数据,都需要二次开发,成本较高;
- 每天有2W+的告警,运维根本处理不过来;
- 监控和告警数据很多,为什么还是有不少故障监控没有发现?
这个时候苗辉跑去百度了,我一个人压力山大。当时外部对监控不是很满意,告警刷屏时有发生。
2015年底我决定搞监控3.0,以构建立体化的监控体系为目标,将告警分层,覆盖从基础设施->组件->产品服务->客户业务的四层告警。自上而下做告警定位,由下而上确定告警影响范围。建立告警间的相互关联关系,当出现一个严重级别的告警时,能展示告警的影响范围。
架构图
调度系统
UI层:提供任务类型配置、任务分配结果查询,任务状态查询,组件状态查。2)由UI-master,UI-slave组成,利用LVS或NGNIX做主从。
任务调度层:根据原始任务状态,监控机状态,任务配置状态决策是否进行任务分配,通过zeroMQ向任务分配层发送分配任务2)同时定时向任务加载层发送任务加载任务3)有core-master,core-slave组成,利用zk或hzelcast做主从。
任务加载层:负责接收Core-master的加载任务,向外部系统获取原始任务,写入mysql
任务分配层:负责接收Core-master的分配任务,执行分配策略,将数据写入memcache
数据缓存层:memcahe缓存任务分配结果,cachedump定时将分配结果快照写入mysql
任务分发层:负责接收scada或其他采集客户端的请求,将任务分发给采集端
ZeroMQ:zeroMQ,消息队列,可自动实现负载均衡
Monitor:负责调度平台可视化数据维护,包含各组件的运行状态,任务加载,调度,分配,分发状态
ZK/hazelcast:分布式协调系统,用于core组件进行主备选举,机房内部署集群,设置iptable只允许同机房访问。
告警决策
NodeCluster
消息生产集群,接入不同的数据源类型,生产待计算的原始消息。如接收sdn推送的监控采集数据,以每一行为一条计算数据提交。
MessageCluster
使用kafka消息中间件,暂存计算消息。实现数据的流式输入。
JstormCluster
核心计算集群,基于storm的java版本,改进HA问题和计算性能优化。
MonitorCluster
集群状态监控,负责进行集群内部的组件状态、topology计算状态的监控报警
ThorUI
UI作为实时计算平台的运营界面,主要任务是各个组件的运行状态收集、消息任务配置、监控报警展示、系统配置等。
数据库性能调优
在监控2.0阶段,监控数据是存储在MySQL,监控数据每天达到750G+,单表每天数据量10亿条,数据查询非常慢。我们对监控表做读写分离和水平分表看下测试的效果,但测试的结果让我们大失所望。
- 读写分离和单实例的查询和更新响应时间没有太大的区别;
- 通过mycat的水平分表,在大量数据下有优势,但小量数据则无优势。所谓大量数据,表内数据最好在千万级别以上,插入量最好在百万级别以上。
上述两个方案行不通,我们决定采用第3种方案,表分区方案。即以5分钟为一分区,根据每个监控对象实际需求创建分区数,由crontab脚本定时执行,执行时根据总时长、监控数据保留时长、当前时间,数据计算出要删除的分区,truncate分区数据。表分区方案将delete和load、select隔离在不同分区,减少delete对load、select的影响。通过一段时间的测试,发现测试效果还是不错的,比之前有一定幅度的提升。
如何基于开源快速搭建一个监控系统
1.zabbix
如果你的公司机器规模少于1000台,没有用到K8S,告警逻辑也不复杂,那推荐你用zabbix,基本能满足企业内部普通的IT运维。
2.Prometheus+Clickhouse
如果你的公司机器规模大于5000台,并且是通过容器化编排部署,告警逻辑也较为复杂,推荐Prometheus+Clickhouse。可参考之前的文章。
3.Prometheus+Telegraf+influxdb
Telegraf是实现数据采集的工具。Telegraf 具有内存占用小的特点,通过插件系统开发人员可轻松添加支持其他服务的扩展。在平台监控系统中,可以使用 Telegraf 采集多种组件的运行信息,而不需要自己手写脚本定时采集,大大降低数据获取的难度。
总结
最后,我总结出来做好监控很重要的4个点:
- 一定要建立体系化的监控告警平台,确定监控scope,避免成为“背锅侠”。
- 监控不只是运维的事,研发设计要把组件监控纳入进来。
- 监控越往前做越有效,等到组件上线运营后再补充的代价是极高的。
- 监控发展的必经之路,少->全->精,要避免告警风暴,做到精准。