欢迎大家加入运维开发讨论交流群来交流,群号 365534424
关于扩展性的定义
可伸缩性(可扩展性)是一种对软件系统计算处理能力的设计指标,高可伸缩性代表一种弹性,在系统扩展成长过程中,软件能够保证旺盛的生命力,通过很少的改动甚至只是硬件设备的添置,就能实现整个系统处理能力的线性增长,实现高吞吐量和低延迟高性能。
可伸缩性和纯粹性能调优有本质区别, 可伸缩性是高性能、低成本和可维护性等诸多因素的综合考量和平衡,可伸缩性讲究平滑线性的性能提升,更侧重于系统的水平伸缩,通过廉价的服务器实现分布式 计算;而普通性能优化只是单台机器的性能指标优化。他们共同点都是根据应用系统特点在吞吐量和延迟之间进行一个侧重选择,当然水平伸缩分区后会带来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这种比较奇葩的。因为写入的能力不是很好。虽然它后来又有一些改进方案来缓解这个问题,但注意,只是缓解。
综上,对于可扩展性,我们的思路是:分布式、无状态。
未完待续