前面分享了高并发系统(高并发系统设计)以及高可用系统(高可用系统)的解决方案,今天我们再来看另一个很重要的模块,可扩展系统,系统的可扩展性同样是架构所需要重点考虑的一个设计点。
顾名思义,可扩展即是通过增加相应的机器来达到抗住系统的突然流量激增的目的。所以,今天我们来看看该怎么设计一个可扩展的系统,目的是,在公司运营突然大促或者我们应用曝光量更火爆的时候,我们能够从容的端着咖啡去应对,而不是被产品逼着问服务怎么又停了。
1,增加机器真的简单吗
我们有时在项目架构评审的时候,有些同学提到的最多的就是,我们服务要多部署几台服务器吧,万一扛不住线上并发咋办。提到这个的问题证明出发点是好的,是想将服务后续能支持横向扩展。其实,我们在设计可扩展系统或者服务时不能只靠自己经验和直觉的,而是要站在我们系统的本身以及预估后续系统持续变化点。比如,我们之前有个酒店预订的系统,一直运行的很稳定,有一次的大节假日,流量突然增加到了10倍,我们的MySQL从库达到了读瓶颈,最后通过扩展从库解决查询慢的问题。
之所以提到这个小案例,是想告诉大家,作为架构师的你不要只看应用级别的扩展,要有整个全局的扩展思路。
那么,是不是通过多加机器就一定能解决流量激增的问题呢?答案是否定的,像上面提到的,其实数据库层面也达到了瓶颈,再比如咱们本来一台机器带宽是50Mbps,现在服务扩展了多台后整个集群达到了千兆级别,但是,其实瓶颈是在负载均衡层,因为咱们目前负载均衡层只支持千兆以内的带宽。因此,我们在设计扩展系统时要分析各个瓶颈点,然后再去对应的去扩展,不仅是业务块,应该还有数据库、缓存、负载均衡等等。
2,如何设计
分而治之,是目前设计可扩展系统比较流行也是经过市场检验的一种比较优雅的方式。通过将我们复杂的系统进行合理化拆分成各个小而简单的服务模块,从而对其分析进行各自扩展。
一,存储扩展
还是拿我们之前的酒店预订系统为例,我们在存储层扩展首先是按照基础业务进行拆分的,大体拆为用户库、运营库、权益库、基础数据库、订单库等,具体的酒店这些基础数据就放在基础数据库中,这样拆分还有个好处就是确保了故障的隔离,其中一个挂了不会影响其他的数据,由于业务的高速发展,我们这种基于业务的拆分已经到了部分库的单机瓶颈了,所以,此时要基于数据本身进行扩展,这里假如我们订单库达到瓶颈了,我们可以考虑增加订单库节点来扩展,但是存储层的扩展不能简单的增加节点,而是要考虑长远,一次性分配多个节点点来达到后面的扩展。这里会涉及到分库分表专题,敬请期待。
二、业务层扩展
在考虑业务层扩展这块,我们一般基于三个方向,业务方向、重要性方向、请求来源方向
番外:如果对于底层代码想研究,可以去作者wx号:架构师修炼,发送soa,则会推送soa分布式源码脚手架,拿走不谢
业务方向
我们基于业务进行拆分后行成各种业务池(理解为集群),比如,我们上面的酒店预订被拆为用户池、搜索池、酒店详情池、基础数据服务池、运营池、订单池等等。每个池对应着自己的数据库
从上图可看出,我们针对各个基础业务进行拆分,然后哪个池达到了瓶颈我们就横向扩展哪一个就行了,简单而不粗暴。
重要性方向
重要性是指将一些重要的服务也就是不能影响我们系统主流程服务放在一起,将一些可以妥协的服务放在一起形成非重要性服务池,为什么要这么设计扩展性呢?是因为,当我们系统面临突然流量激增的时候比如秒杀假期大促等,可以适当的去将非重要性的服务进行降级,从而保重主流程的正常运作。比如我们酒店预订中就可以将运营和相关权益政策服务进行降级,不去请求他们,从而让我们整个系统能保证用户能搜到和订到酒店。
请求来源方向
请求来源是指我们系统被哪些端访问,APP端、网页端、小程序或者公众号等,将这些进行归类进行独立提供服务,还得上面酒店预订系统为例,提供了APP端服务、H5端服务、内部调用服务。
总结,今天我分享了可扩展是架构必须要考虑的设计点,以及可扩展设计并不能一味的只考虑服务层的扩展,要全局的把控,同时后面讲到了我们通过拆分的方法论进行如何优雅的进行设计系统的可扩展。