我们在平时的编程学习中,经常会接触到“系统架构设计”这个概念;但是很多小白并不能准确理解这个概念,以及常用系统的架构演进过程,甚至是在查阅了很多资料之后仍然是云山雾罩。通过本文知识,让我们花5分钟时间彻底搞懂它,相信聪明的你,看完一定会有收获!
什么是架构设计模式?我想这个问题,如果有5个人回答,估计能得出6个答案,因为第6个就是大家互相讨论(妥协)的结果(^_^)。
在我看来,设计模式就是设计经验,只有具备了足够多的经验,才能够根据业务自身的具体情况,组合出最适合当前业务的架构设计,从而控制投入成本,提高工作效率。笔者在IT行业深耕十余年,经历过的架构设计(演进)可以说数以百计,今天把一些架构设计模式的一些经验分享给大家,以飨读者。当前业界的架构设计,大体上可以分为5种:1.单库单应用模式
这种模式一般只有一个数据库,一个后台管理系统(当然也可以有前台应用)。这是最简单的架构设计模式,也是所有IT初学者最先(必须)接触到的模式。说一下该模式的优缺点:优点:结构简单、开发速度快、实现简单,可用于产品的第一版原型验证需求、用户少的设计。缺点:性能差、没有解决“高并发,高可用、大数据、易扩展“的问题(所以不能用于正式业务的生产环境)
注1:该架构是其他架构设计模式的基础(再复杂的架构,也都是在这个模式上不断演进的)注2:目前流行的前后端分离模式,只是将前端工程化,但本质上并没有改变应用架构的本质,所以在本文中仍然归类为这一种。
2、内容分发模式
这种模式主要解决”静态资源(网页,图片,js,css等)的访问性能问题”与单库单应用模式相比:多了一个OSS云存储(阿里云,七牛云等)和一个CDN加速网络.
CDN加速原理:1)程序通过调用OSS上传接口,得到图片访问地址U,并把U地址入库2)CDN网络会将真实图片资源,在各个CND节点缓存一份;3)用户访问地址U时,CDN先拿到用户端IP,然后再通过一个DNS智能查询算法,找出与该用户距离最近(或通讯时间最短)的CDN节点服务器,将该服务器的缓存图片下发给用户。
说一下该模式的优缺点:
优点:资源下载快、无需过多的开发与配置,同时也减轻了后端服务器对资源的存储压力,减少带宽的使用。缺点:目前来说OSS,CDN的价格还是稍微有些贵,只适用于中小规模的应用,另外由于网络传输的延迟、CDN同步策略等,会有数据不一致的问题。2、查询分离模式这种模式主要解决“查询性能问题”.这个可以说是单库单应用模式的升级版本,也是架构迭代演进过程中的必经之路。与单库单应用模式相比:进行了业务数据库的主从分离,并引入了ES搜索引擎为什么要这样做呢?下面结合两个业务需求场景进行叙述。场景一:业务读多写少有统计数据表明,一般的业务系统,读(查询)场景跟写(保存)场景的比例在7;3(甚至8:2)以上这就决定了我们的系统中会有大量的查询请求。如果仅仅是因为数据库的写性能遇到了问题,而导致我们的系统80%的读场景不可用,这显然是不能够接受的。针对此问题,业界较为成熟的方案就是对数据库进行”读写分离“,即写的时候入主库,读的时候读从库。这样就把压力分散到不同的数据库了,如果一个读库性能不行,扛不住的话,可以一主多从,横向扩展。
一般的业务流程是这样的:1)服务端把一条业务数据,写到主数据库(mastr)2)主数据库通过”同步策略“将该数据同步到从库中(slav)3)需要数据查询时,直接去从库(slav)读相应的数据
一些聪明的、爱思考、想上进的同学可能发现问题了:就是数据的延迟问题,比如:数据还没有同步到从库,我就马上读,那么肯定是读不到的。对于这个问题,各家公司解决的思路不一样,方法也就不尽相同。比如其中一个解决方案是:先尝试读从库,如果读不到就再尝试读主库。场景二:关键词全文检索业务系统都会有关键字搜索的需求,如果使用传统的数据库技术,基本都会使用lik这种SQL语句。众所周知:当数据量达到一定级别,SQL全表扫描会有严重的性能问题。解决办法就是全文检索场景直接走ES搜索引擎(ES不仅可以替代数据库完成全文检索功能,还可以实现诸如分页、排序、分组等功能)
ES搜索引擎的一般使用流程为,1)服务端把一条业务数据落业务库,同时异步发送给ES2)ES把该条记录按照预定规则、配置放入自己的索引库3)客户端查询时,由服务端把这个请求发送到ES,ES根据需求拼装、组合数据,返回给客户端
说完了两个场景,该总结一下这种设计模式的优缺点的了:优点:减少数据库的压力,理论上提供无限高的读性能,间接提高业务(写)的性能,专用的查询、索引、全文(分词)解决方案。缺点:数据延迟,数据一致性的保证和解决。3、分库分表模式这种模式主要解决"单表写入压力过大的问题",这个模式也是架构迭代演进过程中的必经之路。
对于单个业务表,一般有水平切分和垂直切分两种,这里主要介绍水平切分。理论上:一台主机可以有多个实例,一个实例中可以有多个库,一个库可以有多个表。实践中:一台主机上只有一个实例,一个实例中只有一个库,库==实例==主机,所以才有了分库分表这个简称。接下来以一个例子来讲解一下分表流程:假设用户表(usr),数据量有1亿用户,查询、插入、存储都出现了问题,怎么分呢?首先,分析问题,这个明显是由于数据量太大了而导致的问题。其次,设计方案,可以分为10个库,这样每个库的数据量就降到了1KW,单表1KW数据量还是有些大,而且不利于以后量的增长,所以每个库再分个表,这个每个单表数据量就为10W了,对于查询、索引更新、单表文件大小、打开速度,都有益处。再次,给IT运维部门打电话,要10台物理机,扩展数据库......最后,逻辑实现,这里是最有学问的地方。首先是写入数据,需要知道写到哪个分库分表中,读也是一样的,所以,需要有个请求路由层,负责把请求分发、转换到不同的库表中,说说这个模式的问题:1)事务问题因为分库分表,传统事务完成不了,而分布式事务又太笨太重,所以这里需要有一定的策略,保证在这种情况下事务能够完成。常用的策略如:最终一致性、复制、特殊设计等。2)关联和分组查询改造该模式下,传统的join,ordrby,grouby都不能再用了,需要在业务代码层进行改造。(如何解决这些副作用不是一句两句能说清楚的,以后会单独开篇,敬请及时