【引自Reboot运维开发的博客】 写在前面
我从事运维自动化相关的工作,也已经8年了。当初刚开始做的时候,运维开发(devops)这词还不火,很少人知道。国内对运维的理解,也就是机房、服务器、苦逼的7*24小时值班。甚至当时还流传着段子,招运维要人高马大,扛得动服务器。
很幸运的主导了两个一线互联网公司的公司级的运维自动化。这俩公司的服务器,都是几十万台级的,IDC都是几十个。很多事情都是摸索着来。一路走来也形成了一些对运维自动化的理解。第一家公司好容易做的七七八八的时候,到第二家实施发现原有的很多理解都被打烂了重新来。但这种经历反而凝练了一些经验。我个人性格原因,不喜欢到外面去讲。偶尔实在没法推辞过去的,也诚惶诚恐的准备,到最后发现很多干货还是没办法一言以蔽之。最后留在外面的都是一些只言片语,不成系统,更不敢说能指导多少。
终于下定决心要把我个人的一些理解,通过系列文章来写一写。文笔有限,可能写的不尽人意。也欢迎大家加入运维开发讨论交流群来交流,群号:365534424
废话少说,直接上文。
我始终认为监控对于运维来说,犹如眼睛对人来说一样重要。不管说的多么高大上,运维工作里面很大一部分还是响应型的工作。来自于架构调整、服务变更或者来自于监控。说监控是整个运维或者服务生命周期里面最重要的一环都不为过。从事前发现,预警或者故障报警,到事后提供监控现场供回溯追查,监控系统贯穿了运维整个环节。怎么才能有一副好视力,今天我们就来稍微谈谈。
正因为监控系统如此重要和通用,所以业内最成熟、最多的产品也是监控系统。商用的、开源的监控系统比比皆是。也有一些很优秀的开源系统应用很广泛。比如Zabbix、cacti、nagios、ganglia等。对于使用开源系统,还是自己开发(相信看这个文章的,应该都不会有购买监控系统的打算),是使用者自己决定的。业务和团队规模都不足够的时候,直接拿来主义,开源的系统能解决基本问题,性价比高。业务如果后期发展的好,规模快速扩大,复杂度迅速增加的情况下,开源系统就难以为继了。具体表现在时效性、扩展性、二次开发、支持的服务规模(或者叫系统容量)、良好的权限控制等各方面。
从上面几点来看,一个监控系统需要具备的是数据采集、扩展性、告警管理、高可用、历史数据存储与展示、权限管理等几个方面。
监控本质上就是对被监控对象的状态进行判定。这个监控对象可以是服务器、交换机,也可以是一个几千台服务器的集群,还可以是带宽、CPU利用率,甚至深入到服务内部,监控服务内部的进程、线程、cache命中率等。
监控对象多种多样,既有实体的,也有虚拟的。 对被监控对象的状态进行判定,这句话里面有三个要素。被监控对象、状态、判定。所以监控系统要能够适配足够多的监控对象类型、收集并能转换为可衡量的状态值,才能支持下一步的判定动作。例如,一台服务器上的nginx服务的连接数。服务器上的nginx服务,就是被监控的对象;连接数就是被监控对象的指标,那么状态呢?我们可以定义为,超过1万就是不正常,否则是正常。
从这个角度做框,我们来看看监控系统的核心指标都有哪些。首先是能监控的对象范围要越多越好(当然你可以说小而精的也挺美。但维护多套监控系统也是代价)。也就是数据采集,能采集的渠道、支持的方式、采集的指标越多越好。
可伸缩性(可扩展性)是一种对软件系统计算处理能力的设计指标,高可伸缩性代表一种弹性,在系统扩展成长过程中,软件能够保证旺盛的生命力,通过很少的改动甚至只是硬件设备的添置,就能实现整个系统处理能力的线性增长,实现高吞吐量和低延迟高性能。
可伸缩性和纯粹性能调优有本质区别, 可伸缩性是高性能、低成本和可维护性等诸多因素的综合考量和平衡,可伸缩性讲究平滑线性的性能提升,更侧重于系统的水平伸缩,通过廉价的服务器实现分布式计算;而普通性能优化只是单台机器的性能指标优化。他们共同点都是根据应用系统特点在吞吐量和延迟之间进行一个侧重选择,当然水平伸缩分区后会带来CAP 定理约束。
具体讨论到监控系统的可扩展性,我们这里特指系统可以随着被监控对象的规模扩大而无需对架构做大的变更修改。一千台服务器的时候,是这个架构,一万台服务器的时候还是这个架构,最好十万台的时候只需要增加服务器就可以,架构还是那个架构。听起来很棒吧!这也是每个系统架构设计者的梦想。但现实照进理想的时候,发现理想很残酷。首先是对于设计者来说,当他在一家只有几百台服务器规模的公司时,很难去想到自己的系统可能有一天会在跑在几万台的服务器规模上。这里面也有一个架构设计的原则,就是要尽量避免过度设计。如果一个几百台服务器规模的公司的运维开发,对他的老板说要做一个系统可以支撑几万台服务器,但因此要多花了多少时间去架构和重构,我想老板会认为自己的运维开发一定是疯了。架构原则之一也是要尽量避免过度设计。
但软件设计依然还是推崇良好的架构、良好的可扩展性。否则架构设计的价值就会打很大的折扣,代码复用和系统实现成本会随着规模的扩大而线性增长。良好的架构可以通过迭代得出之后,反过来指导低阶的系统设计。但低阶的无法预测高阶的。这就是架构的用处之一。所以这里稍后我会介绍一下,我对于监控系统架构的一些经验和心得。
一个称职的设计者,是可以站在几百台服务器的规模时,考虑到几千台的情况的。但他考虑几万台的话就有点过度了。这里并非说能支撑几万台的系统架构不优秀。只是如果他不知道,那也没必要过度考虑。如果能提前知道,甄嬛就会说,那显然是极好的。
但很显然需要考虑的内容会越来越多。几十台的时候,你可能只需要考虑一个机房了,几百台的时候会有2、3个机房,当几千台的时候可能依然在10个IDC以内,但当几万台的时候很可能已经超过15个IDC了。而且,地理位置的分布会更广泛,由此而带来的运营商的覆盖、网络的复杂度、业务的复杂度也会完全不同。非逼着一个运维开发去完全臆想着来做是不现实的。他没有经历过实际的这种需求场景,是没有办法考虑到这样那样的各种问题的。所以我完全理解一些大公司对于开源项目的态度。好一点的可能拿来改改用,进一步可能单独拉一个分支开始改,更甚的就改的完全和主干不一样了 ,其实还有就是自己造轮子的。但有时候就是这样,自己不造轮子,开源的轮子用着的确不好使。
具体到监控系统,可扩展性体现在哪些方面呢?我们从头捋一下。监控系统的输入是监控到的各项监控数据。这些数据经过一系列的处理,最终存储下来用于事后分析和离线分析,同时更主要的作用是要实时的报警。整个过程我们可以视为是一个流式计算的过程。说到流式计算其实大家想到的是storm这些。这倒是另外一个我曾经想过的思路,就是把所有处理过程放到strom上去。balabalabala.... 说远了。但我们仔细去看,strom也好,流式计算平台也罢,都是分布式的。分布式架构的一个特性就是良好的扩展性。随着服务器规模的扩大,对于中间的数据处理层的可扩展性要求,就是计算能力要能具备扩展性。简单来说就是数据多了,通过加服务器或者升级服务器就能搞定。
还有几个边界的地方需要把扩展性支持好。第一个就是入口。或者叫做数据的接收口。外面的数据源源不断的进入,如果要想做到扩展性良好,第一个需要考虑的就是接收环节。数据可以走TCP、UDP、SNMP、HTTP等多种协议进入到监控系统。考虑到数万服务器的规模,这个地方比较考验技术底子。如果走SNMP、HTTP当然可以,但这两个协议都走在应用层,必然会带来额外的开销。拿HTTP举例子,我们拿Nginx或者apache做server,其实天然带有可扩展性。数据收到以后,存到一个存储即可(不管这个存储是缓存还是永久存储)。这个过程,不带有状态,所以天然具有可扩展性。一个Nginx 实例扛不住了,再来一个,再来一个,再来十个。这样就解决了接口的可扩展问题。
另外一个可扩展是存储环节。这个存储主要是监控数据的持久化存储。前面我们说,数据接收、计算环节都可以通过一些方式支持可扩展。那存储必然会成为一个瓶颈。这个在很多系统里面都是这样,前端可以通过Web Server实现可扩展,但最终大家都跑到一个数据库上读写。哪怕是读写分离的,还是一个主库。主库压力山大。
这个地方我推荐用一些分布式存储来解决这个问题。但不是很推荐mango这种比较奇葩的。因为写入的能力不是很好。虽然它后来又有一些改进方案来缓解这个问题,但注意,只是缓解。
综上,对于可扩展性,我们的思路是:分布式、无状态。(未完待续)