架构设计的真正目的:是为了解决软件系统复杂度带来的问题,一个解决方案。
系统复杂度,如何入手:
1、通过熟悉和理解需求,识别系统复杂性所在的地方,然后针对这些复杂点进行架构设计。
2、架构设计并不是要面面俱到,不需要每个架构都具备高性能、高可用、高扩展等特点,而 是要识
别出复杂点然后有针对性地解决问题。
3、理解每个架构方案背后所需要解决的复杂点,然后才能对比自己的业务复杂点,参考复杂 点相似
的方案。
架构即(重要)决策:是 在一个有约束的盒子里去求解或接近最合适的解。这个有约束的盒子是团队经验、成本、资 源、进度、业务所处阶段等所编织、掺杂在一起的综合体(人,财,物,时间,事等)。架构无优劣,但是存在恰当的架构用在合适的软件系统中,而这些就是决策的结果。需求驱动架构,如下几点:
1、架构是为了应对软件系统复杂度而提出的一个解决方案;
2、架构即(重要)决策 ;
3、需求驱动架构,架起分析与设计实现的桥梁 ;
4、架构与开发成本的关系。
在分析设计阶段,需要考虑一定的人力与时间去"跳出代码,总揽全局",为 业务和IT技术之间搭建一座"桥梁"。
架构设计处于软件研制的前期,一方面,越是前期,如有问题,就能够越早发现,修改的代价也就越低;另外一方面,也意味着,软件实施后期若有架构上的修改,也需要付出更多的价。
复杂度来源:高性能
1、单机复杂度-单台计算机内部为了高性能带来的复杂度;
2、集群的复杂度-多台计算机集群为了高性能带来的复杂度。
单机复杂度
计算机内部复杂度有个重要关键点:操作系统。硬件是操作系统的保证
操作系统和性能最相关的就是进程和线程,
进程是操作系统分配资源最小单位,与其他进程资源互相独立。
线程是操作系统调度的最小单位,共用进程内的资源。
集群的复杂度
主要是通过大量机器来提升性能,并不仅仅是增加机器这么简单,让多台机器配合起来达到高性能的目 的,是一个复杂的任务,针对常见的几种方式简单分析一下。
1、任务分配
任务分配的意思是指每台机器都可以处理完整的业务任务,不同的任务分配到不同的机器上执行。
如图1 台服务器演变为 2 台服务器后,架构上明显要复杂多了,主要体现在:
1、需要增加一个任务分配器,这个分配器可能是硬件网络设备(例如,F5、交换机等),可能 是软件网络设备(例如,LVS),也可能是负载均衡软件(例如,Nginx、HAProxy),还可 能是自己开发的系统。选择合适的任务分配器也是一件复杂的事情,需要综合考虑性能、成 本、可维护性、可用性等各方面的因素。
2、任务分配器和真正的业务服务器之间有连接和交互(即图中任务分配器到业务服务器的连接 线),需要选择合适的连接方式,并且对连接进行管理。例如,连接建立、连接检测、连接 中断后如何处理等。
3、任务分配器需要增加分配算法。例如,是采用轮询算法,还是按权重分配,又或者按照负载 进行分配。如果按照服务器的负载进行分配,则业务服务器还要能够上报自己的状态给任务 分配器。
假如继续提高性能,那么任务分配器由于瓶颈问题也需要增多,如图:
1、任务分配器从 1 台变成了多台(对应图中的任务分配器 1 到任务分配器 M),这个变化带来 的复杂度就是需要将不同的用户分配到不同的任务分配器上(即图中的虚线“用户分配”部 分),常见的方法包括 DNS 轮询、智能 DNS、CDN(Content Delivery Network,内容 分发网络)、GSLB 设备(Global Server Load Balance,全局负载均衡)等。
2、任务分配器和业务服务器的连接从简单的“1 对多”(1 台任务分配器连接多台业务服务 器)变成了“多对多”(多台任务分配器连接多台业务服务器)的网状结构。
3、 机器数量从 3 台扩展到 30 台(一般任务分配器数量比业务服务器要少,这里我们假设业务 服务器为 25 台,任务分配器为 5 台),状态管理、故障处理复杂度也大大增加。
上面这两个例子都是以业务处理为例,实际上“任务”涵盖的范围很广,可以指完整的业务处 理,也可以单指某个具体的任务。例如,“存储”“运算”“缓存”等都可以作为一项任务,因 此存储系统、运算系统、缓存系统都可以按照任务分配的方式来搭建架构。此外,“任务分配 器”也并不一定只能是物理上存在的机器或者一个独立运行的程序,也可以是嵌入在其他程序中 的算法,例如 Memcache 的集群架构。
2、任务分解
通过任务分配的方式,我们能够突破单台机器处理性能的瓶颈,通过增加更多的机器来满足业务 的性能需求,但如果业务本身也越来越复杂,单纯只通过任务分配的方式来扩展性能,收益会越 来越低。
1、提升任务性能关键点:
简单的系统更加容易做到高性能
系统的功能越简单,影响性能的点就越少,就更加容易进行有针对性的优化。而系统很复杂的情 况下,首先是比较难以找到关键性能点,因为需要考虑和验证的点太多;其次是即使花费很大力 气找到了,修改起来也不容易,因为可能将 A 关键性能点提升了,但却无意中将 B 点的性能降 低了,整个系统的性能不但没有提升,还有可能会下降。
2、可以针对单个任务进行扩展
当各个逻辑任务分解到独立的子系统后,整个系统的性能瓶颈更加容易发现,而且发现后只需要 针对有瓶颈的子系统进行性能优化或者提升,不需要改动整个系统,风险会小很多。以微信的后 台架构为例,如果用户数增长太快,注册登录子系统性能出现瓶颈的时候,只需要优化登录注册 子系统的性能(可以是代码优化,也可以简单粗暴地加机器),消息逻辑、LBS 逻辑等其他子系 统完全不需要改动。
总结:
硬件角度-垂直维度可包括以下措施:
增大内存减少I/O操作
更换为固态硬盘(SSD)提升I/O访问速度
使用RAID增加I/O吞吐能力
置换服务器获得更多的处理器或分配更多的虚拟核
升级网络接口或增加网络接口
操作系统-水平维度可包括以下措施:
功能分解:基于功能将系统分解为更小的子系统
多实例副本:同一组件重复部署到多台不同的服务器
数据分割:在每台机器上都只部署一部分数据
垂直维度方案比较适合业务阶段早期和成本可接受的阶段,该方案是提升性能最简单直接的 方式,但是受成本与硬件能力天花板的限制。
水平维度方案所带来的好处要在业务发展的后期才能体现出来。起初,该方案会花费更多的 硬件成本,另外一方面对技术团队也提出了更高的要求;但是,没有垂直方案的天花板问 题。一旦达到一定的业务阶段,水平维度是技术发展的必由之路。