什么是建筑
我想这个问题十个人有十一个答案,因为另外一个是大家妥协的结果,哈哈,我明白了,架构就是骨架。
人体的支撑主要由骨骼提供,其次是其上的肌肉、神经和皮肤。 架构对于软件来说就像骨骼对于人体一样重要。
什么是设计模式
这个问题我已经向受访者问过几十次了,得到的答案五花八门。 在我看来,模式就是经验,涉及模式就意味着涉及经验。 有了这些经验,我们就可以在特定的情况下使用特定的设计和组合设计。 。 这样可以大大节省我们的设计时间,提高工作效率。
经理作为一名老码农,做过很多系统架构设计。 接下来我给大家分享一下我工作中用到的一些架构设计模式,希望大家少走弯路。 总体来说,有八种类型,分别是:
1、单数据库单应用模式:最简单的,可能大家都见过
2.内容分发模式:目前用得较多
3.查询分类模式:针对大并发查询和业务
4、微服务模式:适合拆解复杂的业务模型
5.多级缓存模式:可以很好的玩缓存
6、分库分表模式:解决单机数据库瓶颈
7、弹性伸缩模式:解决峰谷业务流量不均的方法之一
8、多机房模式:解决高可用和高性能的方法
单数据库单应用模式
这是最简单的设计模式。 我们大部分的本科毕业项目和一些小型应用基本上都是这种模式。 该模式的总体设计如下图所示:
如上图所示,这种模式一般只有1个数据库、1个业务应用层、1个后端管理系统。 所有业务均通过业务层完成,所有数据都存储在一个数据库中。 最好有数据库同步,虽然简单,但也不是没有优点。
优点:结构简单,开发速度快,实现简单,可用于首版产品等原型验证需求。
缺点:性能差,基本没有高可用性,扩展性差,不适合大规模部署、应用等生产环境。
内容分发模型
基本上所有的大型网站都或多或少的采用了这种设计模式。 一个常见的应用场景是利用CDN技术将网页、图片、CSS、JS等静态资源分发到距离用户最近的服务器。 该模式的总体设计如下图所示:
如上图所示,该模型比单数据库、单应用模型多了1个CDN和1个云存储OSS(类似七牛、优拍等)。 一个经典的应用流程(以用户上传和查看图片的需求为例:)
1. 上传时,用户选择本地机器上的图片进行上传。
2. 程序会将图片上传到云存储OSS,并返回图片的URL。
3、程序将URL字符串存入业务数据库,上传完成。
4、查看时,程序从业务数据库中获取图片的URL
5、程序通过DNS查询该URL的图片服务器。
6. Smart DNS会解析该URL并获取距离用户最近的服务器(或集群)的地址A。
7.然后将服务器A上的图片返回给程序
8、程序显示图片,查看完成。
从上面可以看出,该模型的关键是智能DNS,它可以解析距离用户最近的服务器。 其工作原理大致是:根据请求者的IP获得请求位置B,然后通过计算或配置服务器C获得到B最近或最短的通信时间,然后将C的IP地址返回给请求者。 该模型的优缺点如下:
优点:资源下载速度快,无需过多的开发和配置。 也减轻了后端服务器对资源的存储压力,减少了带宽的占用。
缺点:目前OSS和CDN的价格还是有点贵,只适合中小型应用。 另外,由于网络传输延迟、CDN同步策略等原因,会存在一些一致性和更新慢的问题。
查询分离模式
该模型主要解决单机数据库压力过大,导致业务缓慢甚至超时,查询影响时间较长的问题。 它还包括需要大量数据库服务器计算资源的查询请求。 这可以说是单数据库应用模型的升级版本。 也是技术架构迭代演进过程中的必由之路。
该模式的总体设计如下:
如上图所示,该模型比单数据库多了几个部分,而是应用模型和内容分发模型。 一是业务数据库主从分离,二是ES的引入。 为什么是这样? 下面根据业务需求场景详细描述解决哪些痛点。
场景一:全文关键词搜索
我想大部分的应用都会有这个需求。 如果使用传统的数据库技术,大部分可能会使用类似SQL语句。 更高级的是先对词进行切分,然后记录切分词的索引相关的记录。 SQL语句的性能问题和全表扫描机制导致了非常严重的性能问题,现在基本上已经很少见了。
ES比Solr配置更简单,使用更方便,所以这里选择ES。 另外,ES支持水平扩展,理论上不存在性能瓶颈。 同时还支持各种插件、自定义分词器等,具有很强的扩展性。 这里,使用ES不仅可以代替数据库完成完整的搜索功能,还可以实现分页、排序、分组、分面等功能。 具体来说,要求学生自学。 如何使用它? 一个大概的流程是这样的:
1、服务器在数据库中存储一条业务数据
2.服务器异步发送数据到ES
3、ES根据规则和配置将记录放入自己的索引数据库中。
4. 当客户端查询时,服务器将请求发送给ES。 获取数据后,根据需要对数据进行组装、组合,返回给客户端。
实际中如何使用呢? 还要求学生根据实际情况进行组合和选择。
场景2:大量普通查询
这个场景指的是我们业务中大部分的辅助查询,比如提款时查看余额、根据用户ID查询用户的记录、获取用户最新的提款记录等,我们必须是需要的每天都会用到,而且用得很多。 同时我们也有大量的写入请求,导致对同一个数据库进行大量的写入和查询操作。 然后,数据库挂了,系统挂了,领导生气了,被解雇了,再也付不起房贷了。 我睡在街上,我的妻子跟别人跑了......
我不敢想,所以要求我们分散数据库的压力。 业界比较成熟的解决方案之一就是数据库的读写分离。 写的时候进入主库,读的时候读到子库。 这将压力分散到不同的数据库。 如果一个读数据库性能不好,无法承受,可以一主多从,水平扩展。 可以说是一剂良药! 那么如何使用呢? 一个大概的流程是这样的:
1.服务器将一条数据放入数据库
2、数据库同步或异步或半同步将此数据复制到从库。
3、服务器读取数据时,直接从库中读取对应的数据。
这相对简单。 一些聪明、有思想、有上进心的同学可能已经发现了问题,包括上面介绍的场景一,就是延迟问题。 比如:如果从库数据还没到,我就立即读取,所以读不到。 如果你到达了,就会出现问题。 对于这个问题,每个公司都有不同的解决思路和方法。 常见的解决办法是:读主库而不读。 当然,这么说是有前提的,但具体解决办法不在这里。 我可能会在接下来的分享中一一详细讲解各种解决方案。
另外,要求学生自行研究数据库复制模式。 这里要解释的东西太多了。 是时候总结一下这种模式的优缺点了,如下:
优点:减轻数据库压力,理论上提供无限高的读性能,间接提升业务(写)性能,提供专用的查询、索引、全文(分词)解决方案。
缺点:数据延迟,数据一致性保证。
微服务模式
上面的模型看起来不错,解决了性能问题。 我不能再用鲁肃街了,我老婆还是我的,哈哈。 然而软件系统固有的复杂性决定了除了性能之外,还有高可用性、健壮性等其他因素。 还有很多问题等待我们解决,而各个部门之间的争吵和争吵更是让我们程序员雪上加霜,所以我们继续吧……
微服务模型可以说是最近的热门话题。 国内外各种规模的企业都在倡导和实践这一模式。 然而,他们中的大多数人还没有弄清楚为什么要这样做,也不知道这样做的好处。 ,缺点,在这里,我从我自己的个人实践谈一下我对这个模式的看法。 如果你不喜欢它,就不要批评它。 随着业务和人员的增加,遇到的问题如下:
1、单机数据库写请求数量大幅增加,导致数据库压力增大。
2.一旦数据库宕机,整个业务就宕机了。
3、业务代码越来越多,都在一个GIT中,维护起来越来越困难。
4、代码严重损坏,气味越来越浓。
5、线上发布越来越频繁,往往一个小功能的修改就需要整个大项目重新编译。
6、部门越来越多。 大项目中哪个部门应该改哪些东西? 有很多分歧。
7、其他一些外围系统是直接与数据库相连的,所以一旦数据库结构发生变化,就必须通知所有相关的系统,甚至对修改不敏感的系统也必须通知。
8、每台应用服务器需要开放所有权限、网络、FTP等,因为每台服务器部署的应用都是一样的。
9. 作为一名架构师,我已经失去了对这个系统的控制......
为了解决上述问题,我们公司采用了微服务模式。 该模型的总体设计如下:
如上图所示,我将业务进行了垂直细分,划分为独立的系统。 每个系统都是独立演化的,都有自己的库、缓存、ES等辅助系统。 系统之间通过RPC进行实时交互,通过MQ进行异步交互,通过这种组合,共同完成整个系统的功能。
那么,这真的能解决上述问题吗? 别废话了,一一说吧。
关于问题一,由于拆分为多个子系统,所以系统的压力分散了,而且每个子系统都有自己的数据库实例,所以数据库的压力就变小了。
关于问题二,如果子系统A的数据库宕机,只会影响系统A以及使用系统A的功能,不会导致所有功能不可用,从而解决了数据库宕机且所有功能不可用的情况。 。
对于问题三和问题四,分裂已经解决。 每个子系统都有自己独立的GIT代码库,不会互相影响。 通用模块可以通过库、服务、平台的形式来解决。
对于问题五,如果子系统A发生变化,需要上线,那么我们只需要编译A然后上线即可。 不需要其他系统来做主导的事情。
关于问题六,按照康威定律,我们部门应该做什么、输出什么,也应该以服务的形式暴露出来。 我们部门只要做好自己的职责和软件功能就可以了。
关于问题七,我们部门数据的所有要求都是通过接口发布的。 客户通过接口获取数据,从而屏蔽了底层数据库结构甚至数据源。 我们部门只需要保证我们部门的接口契约没有改变就可以了。 就是这样,会根据新的需求添加新的接口,老的接口不受影响。
关于问题八,不同的子系统需要不同的权限,这个问题也被优雅地解决了。
对于第九个问题,要暂时控制复杂性,我只需要控制大的方面,定义系统边界、接口、大流程,然后分而治之,一一击败,纵横组合。
至此,所有的问题都已经解决了! 答对了!
但随之而来的还有很多其他的副作用,比如RPC和MQ的超高稳定性和超高性能、网络延迟、数据一致性等问题。 我不会详细讨论这一点。 这本书要涵盖的内容太多了。 书是无穷无尽的。
另外,对于这个模型来说,最难把握的就是程度。 切记不要划分得太细。 我见过一个函数一个子系统,数百个方法分为数百个子系统。 实在是太多了。 在实践中,比较可行的方法是:能不分开就不要分开,除非有非常必要的理由!
优点:性能比较高,可扩展性强,可用性高,适合中型及以上公司架构。
缺点:复杂,难以掌握。 意味着不仅需要能够高水平掌控大方向、大流程、整体技术,而且需要能够对各个子系统进行针对性的开发。 如果控制不当或者滥用的话,这种模式将会适得其反!
多级缓存模式
这种模式可以说是应对超高查询压力常用的策略。 基本思路是对所有可以添加缓存的链接都添加缓存,如下图:
如上图所示,缓存一般加在三个地方,一是客户端,一是API网关,一是具体的后端业务处。 现将其介绍如下:
客户端缓存:这里缓存可以说效果最好——无延迟。 因为不需要经过很长的网络链条来从后端业务获取数据,这会导致加载时间长、客户流失等损失。 虽然有CDN支持,但是从客户端到CDN仍然存在网络延迟,虽然不大。 具体技术取决于不同的客户。 对于WEB来说,有浏览器本地缓存、缓存策略等技术; 对于APP来说,有本地数据库、本地文件、本地内存、进程内缓存支持等等。 对提到的各种技术感兴趣的同学可以继续学习。 如果客户端缓存没有命中,那么就会去后端业务去获取数据。 一般来说都会有一个API网关。 这里添加缓存也是非常重要的。 。
后端业务处理:这个不用我多说了。 Redis、Jvm等大家应该都差不多知道了,就不赘述了。
在实践中,需要结合具体的实际情况,综合利用各级缓存技术,使各种请求在到达后端业务之前得到最大程度的解决,从而减轻后端服务器压力,减少带宽占用,并增强用户体验。 至于是否只有这三个地方可以添加缓存,我认为需要我们去学习并灵活运用。 心技比剑技更重要! 总结一下这个模型的优缺点:
优点:承受大量读请求,减少后端压力。
缺点:数据一致性问题比较突出,容易出现雪崩。 也就是说,如果客户端缓存和API网关缓存出现故障,那么大量请求将瞬间全部压在后端业务系统上,后果可想而知。
分库分表模式
该模型主要解决单表写入、读取、存储压力过大,导致业务缓慢甚至超时、事务失败、容量不足的问题。 一般有两种:水平分割和垂直分割。 这里主要介绍水平分割。 这种模式也是技术架构迭代演进的必由之路。
该模式的总体设计如下图所示:
如上图红色部分所示,一个表被分成几个不同的库来分担压力。 是不是很一般? 哈哈,接下来我们详细解释一下。 首先澄清几个概念,如下:
主机:硬件是指物理机或虚拟机,拥有自己的CPU、内存、硬盘等。
:数据库实例,例如MySql服务进程。 一个主机可以有多个实例。 不同的实例有不同的进程并监听不同的端口。
图书馆:指的是表格的集合,比如学校图书馆,可能包括教师表、学生表、食堂表等,这些表都在一个图书馆中。 一个实例中可以有多个库,库之间通过库名进行区分。
表:库里的表就不用多说了。 如果你不明白,请不要往下读。 没有解释。
那么如何分散单表呢? 它是什么样的分布? 分发到哪里? 以下是工作中的一些做法,请大家分享:
主持人:这是最主要的也是最重要的一点。 分库分表本质上是计算和存储资源不足造成的,而这些资源主要由物理机和主机提供。 毕竟,没有可用的计算资源。 怎么可能结果不太好。
实例:实例控制连接数,受操作系统限制。 CPU、内存、硬盘、网络IO也会间接受到影响。 会出现实例热的现象,即有的实例很忙,有的实例很空闲。 典型的现象是:由于单表响应慢,导致连接池被占满,从而影响其他业务。 这时候,将表划分到不同的实例就有了一些作用。
数据库:由于单库最大单表数限制,一般采用分库。
表:单表压力太大,索引大小大,容量大,需要单表锁。 基于以上,将单个表水平划分为不同的表。
在大型应用中,一台主机上只有一个实例,一个实例中也只有一个库。 库==实例==主机,所以就有了分库分表的缩写。
既然知道了这个基本理论,那具体怎么做呢? 逻辑如何运作? 接下来我们通过一个例子来解释一下。
这个要求很简单。 用户表(user)数据量为1亿。 查询、插入、存储都存在问题。 我应该怎么办?
首先,分析问题。 这显然是数据量大导致的问题。
其次,设计方案可分为10个库,使每个库的数据量降低至1KW。 单表1KW的数据量还是有点大,不利于以后的体量增长,所以每个库分为100张表。 ,所以每个单表的数据量为10W,在查询、索引更新、单表文件大小、打开速度等方面都存在一些溢出。 接下来打电话给IT部门,要求10台物理机来扩展数据库……
最后是逻辑实现,这应该是最有学问的地方了。 首先是写入数据。 你需要知道要写入哪个子数据库和子表。 读书也是如此。 因此,需要一个请求路由层,负责将请求分发并转换到不同的数据库表。 一般都有路由规则的概念。 。
怎么样,简单吗? 哈哈。 我们来谈谈这个模型的问题。 主要带来交易问题。 因为数据库是分表的,事务是无法完成的,而分布式事务又过于繁琐,所以这里需要有一定的策略来保证这种情况下事务能够完成。 可以做到。 采用的策略包括:最终一致性、复制、特殊设计等。然后是业务代码的改造,一些相关的查询需要改造,一些单表问题需要特殊处理,包括语句。 如何解决这些副作用不是一两句话就能说清楚的。 这些我以后有时间再单独说。
是时候总结一下这个模型的优缺点了,如下:
优点:减少单个数据库表的压力。
缺点:交易难以保障,业务逻辑需要大量修改。
弹性伸缩模式
这种模式主要解决流量突然进来,导致无法横向扩展或者横向扩展太慢,从而影响业务,导致整个站点崩溃的问题。 这种模式是一项比较先进的技术,也是目前各大公司都在研究和尝试的技术。 到今天为止,有这种思维的架构师已经很优秀了,可以拿到更高的薪水,更何况那些已经实践过甚至实现了底层系统的架构师,所以你懂的……
该模式的总体设计如下:
如上图所示,多了一个弹性伸缩服务,用于动态增减实例。 原理很简单,但是这个模型解决什么问题呢? 我们先来说说起源和意义。
每年双11、618或者一些大促销之前,我们都会做以下工作,为大流量的到来做好准备:提前准备好10次或更多的机器,即使不使用也保留在那里。 以防万一,这会浪费大量资源。 对每台机器进行配置、调试、引流,让所有机器都可用,浪费大量的人力物力,而且更容易出错。如果机器准备不充分,那么就得加班,重复上述工作。 这样特别容易出错,会引起老板的不满。 你就没有时间回家陪老婆了,然后你老婆就……哈哈
双十一之后,我们仍然要手动缩小尺寸,这是非常辛苦的。 通常一年有多次升职,所以我们就一直这样,真是烦人!
最严重的是,突然的大流量爆发会让我们措手不及。 半夜起床扩容是正常现象。 为此,我们偷懒,需要准备更多的机器,这就导致大量1%的机器的CPU利用率。
相信我,如果你是老板,你一定会震惊的!
哈哈,那么如何改变这种情况呢?请继续阅读
为此,首先将所有的计算资源整合到资源池的概念中,然后通过一些策略、监控、服务动态地从资源池中获取资源,使用完之后再放回池中供其他系统使用。 从具体实现上来说比较成熟的两种资源池解决方案是VM和VM,各自都有自己强大的生态。 监控点包括CPU、内存、硬盘、网络IO、服务质量等,基于这些,再配合一些预留、扩容、收缩策略,就可以轻松实现自动收缩。 这个怎么样? 是不是很神奇呢? 深入的内容我会在后面的文章中详细介绍。 是时候总结一下这个模型的优缺点了。 如下:
优点:灵活、按需计算,充分优化企业计算资源。
缺点:应用需要从架构层横向扩展,依赖大量底层配套设施,对技术水平、实力、应用规模要求较高。
多机房模式
该模型主要解决不同地域的高性能、高可用问题。
随着应用用户数量不断增加,用户群体分布在全球各地。 如果服务器部署在一个地方,比如北京,那么美国的用户在使用应用时会特别慢,因为每个请求都需要经过海底。 光缆运行时间约为一秒,这对用户的健康危害极大。 我应该怎么办? 采用多机房部署。 该模式的总体设计如下图所示:
如上图所示,一个典型的用户请求流程如下:
用户请求连接A
通过DNS智能解析到距离用户最近的B机房
使用B机房服务连接A
是不是觉得很简单,没什么? 事实上,这里的问题并不像看上去那么简单。 让我们一一分析一下。
首先是数据同步的问题。 中国产生的数据必须同步到美国,美国也是如此。 数据同步会涉及数据版本、一致性、更新丢弃、删除等问题。
二是一处多个机房的请求路由问题。 典型的如上图所示。 中国的北京机房和杭州机房。 如果北京机房宕机了,那么所有发送到北京机房的请求都必须通过路由转发到杭州机房。 这个问题也存在。
所以,多机房模式,即异地多活动,并不是那么简单。 这只是一个起点。 具体的陷阱将在后续文章中介绍。
是时候总结一下这个模型的优缺点了,如下:
优点:高可用性、高性能、可在远程位置进行多种活动。
缺点:数据同步、数据一致性、请求路由。
版权声明:本文为CSDN博主“程序员Tony”原创文章,遵循CC 4.0 BY-SA版权协议。 转载时请附上原文出处链接及本声明。
原文链接:
☞无代码来了,还要程序员吗?
☞董明珠回应直播带货刷单;腾讯五年 5000 亿发力新基建;Python 3.9 新特性 | 极客头条
☞芯片供应被掐断,华为能否安全渡劫?
☞来了来了!趋势预测算法大PK!
☞Python开发之:Django基于Docker实现Mysql数据库读写分离、集群、主从同步详解 | 原力计划
☞15 岁黑进系统,发挑衅邮件意外获 Offer,不惑之年捐出全部财产,Twitter CEO 太牛了!