"但人类都环绕星球,我更愿追随彗星漂流~"
在正式引入架构演进之前,本小节会对一些比较重要、常见的概念进行介绍。
基本概念:
(1)应用(application)/系统(system)
为了完成一整套服务的一个程序或者一组相互配合的程序群。生活例子类比:为了完成一项任务,而搭建的由一个人或者一群相互配的人组成的团队。
(2) 模块(Module) / 组件 (Component)
应用较复杂时,为了分离职责,将其中具有清晰职责的、内聚性强的部分,抽象出概念,便于理解。生活例子类比:军队中为了进行某据点的攻克,将人员分为突击小组、爆破小组、掩护小组、通信小组等。
(3) 分布式(Distributed)
系统中的多个模块被部署于不同服务器之上,即可以将该系统称为分布式系统。生活例子类比:为了更好的满足现实需要,一个在同一个办公场地的工作小组被分散到多个城市的不同工作场地中进行远程配合工作完成目标。跨主机之间的模块之间的通信基本要借助网络支撑完成。
(4) 集群(Cluster)
被部署于多台服务器上的、为了实现特定目标的一个/组特定的组件,整个整体被称为集群。
比如多个 MySQL 工作在不同服务器上,共同提供数据库服务目标,可以被称为一组数据库集群。生活例子类比:为了解决军队攻克防守坚固的大城市的作战目标,指挥部将大批炮兵部队集中起来形成一个炮兵打击集群。
(5) 主(Master) / 从(Slave)
集群中,通常有一个程序需要承担更多的职责,被称为主;其他承担附属职责的被称为从。比如 MySQL 集群中,只有其中一台服务器上数据库允许进行数据的写入(增/删/改),其他数据库的数据修改全部要从这台数据库同步而来,则把那台数据库称为主库,其他数据库称为从库。
(6) 中间件(Middleware)
一类提供不同应用程序用于相互通信的软件,即处于不同技术、工具和数据库之间的桥梁。生活例子类比:一家饭店开始时,会每天去市场挑选买菜,但随着饭店业务量变大,成立一个采购部,由采购部专职于采买业务,称为厨房和菜市场之间的桥梁。
(7) 容器(Docker)
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux 或 Windows 操作系统的机器上,也可以实现虚拟化。可以理解为一个集装箱,集装箱里面是每个用户的货物,整体打包。
(8) 容器编排(K8S)
kubernetes是一个开源的,用于管理云平台中多个主机上的容器化的应用, Kubernetes 的目标是让部署容器化的应用简单并且高效。可以理解为一个货船,安装集装箱的大小,货物情况合理的来组织集装箱完成整体货物的搬运。
评价指标(Metric):
(1) 可用性(Availability)
考察单位时间段内,系统可以正常提供服务的概率/期望。我们平时只是用高可用(HighAvailability HA)这个非量化目标简要表达我们系统的追求。
(2) 响应时长(Response Time RT)
指用户完成输入到系统给出用户反应的时长。例如点外卖业务的响应时长 = 拿到
外卖的时刻 - 完成点单的时刻。
通常我们需要衡量的是最长响应时长、平均响应时长和中位数响应时长。
(3) 吞吐(Throughput) vs 并发(Concurrent)
吞吐考察单位时间段内,系统可以成功处理的请求的数量。并发指系统同一时刻支持的请求最高量。例如一条 2 车道高速公路,一分钟可以通过 20 辆车,则并发是 2,一分钟的吞吐量是 20。我们平时用高并发(Hight Concurrnet)这个非量化目标简要表达系统的追求。
架构演进:
(1) 单机架构
简介:
所谓单机,顾名思义,应用服务和数据库服务共用一台服务器。
出现原因:
在一个产品研发的初期,我们需要利用我们精干的技术团队,快速将业务系统投入市场进行检验,并且可以迅速响应变化要求。因为前期的用户访问量很少,没有对我们的性能、安全
等提出很高的要求,而且系统架构简单,无需专业的运维团队。所以选择单机架构是合适的。
架构原理:
可以看到通过应用(划分了多个模块)和数据库在单个服务器上协作完成业务运行。
我们以"电子商城"为例:
模拟请求:
用户在浏览器中输入常见域名例如;www.taobao.com,首先经过 DNS 服务将域名解析成 IP 地址。随后浏览器访问该 IP 对应的应用服务。
常见的Web 服务器软件有:Tomat/Netty/Nginx等
数据库软件: Mysql/Oracle/SQL Server等
架构优缺点:
优点:
● 部署简单
● 成本低
缺点:
● 存在严重的性能瓶颈
● 数据库和应用互相竞争资源
(2) 应用数据分离架构
简介:
把业务处理(数据处理)和数据存储分离开来,分别在两个不同的服务器上部署。
出现原因:
假设用户量持续增多,系统访问量增加。单机情况下,存在严重的资源竞争,导致站点变慢,逐渐逼近了硬件资源的极限。为提升系统的承载能力,我们不得不进行系统重构、架构挑战,以最小代价的提升系统的承载能力。
架构原理:
应用和数据库在各自的服务器上通过网络协作完成业务运行。
架构优缺点:
优点:
● 性能上比单机有所提升
● 数据库单独隔离,不会因为误操作搞坏数据库
缺点:
● 性能有瓶颈,无法应对海量并发● 硬件成本变高
(3) 应用服务集群架构
简介:
引入了负载均衡,"应用以集群"方式运作。
出现原因:
受制于单个应用不足以支持海量的并发请求,单台应用服务器已经无法满足需求。我们的单机应用服务器首先遇到了瓶颈,此时有两大策略可为我们解决难题:
● 垂直扩展 / 纵向扩展 Scale Up:
过购买性能更优、价格更高的应用服务器来应对更多的流量。该策略很直接明了,完全不需要对系统软件做任何的调整。但劣势也很明显,付出的硬件成本代价并不小,其次硬件性能提升是有明显上限的。
● 水平扩展 / 横向扩展 Scale Out
通过调整软件架构,增加应用层硬件,将用户流量分担到不同的应用层服务器上,来提升系统的承载能力。这种方案的优势在于成本相对较低,并且提升的上限空间也很大,反之,因为需要重构软件系统以及结构,所以该系统会带来更多的复杂性,对技术团队的要求更高。
架构原理:
可以看到应用不再是一个,而是变成了多个,通过负载均衡来支持海量的并发。
这里引入一个新的组件 —— 负载均衡:为了解决用户流量向哪台应用服务器分发的问题,
需要一个专门的系统组件做流量分发。如何进行流量的分发呢?这又和使用的负载均衡的策略有关系,比如: Round-Robin 轮询算法/Weight-Round-Robin 轮询算法等等。
负载均衡软件有: Nginx、 HAProxy、 LVS、 F5 等
模拟请求:
架构优缺点:
优点:
● 提供应用服务进程增多,高可用:应用满足高可用,不会一个服务出问题整个站点挂掉。
● 应用服务有一定高性能:如果不访问数据库,应用相关处理通过扩展可以支持海量请求快速响应。
● 应用服务有一定扩展能力:支持横向扩展。
缺点:
● 数据库成为性能瓶颈,无法应对数据库的海量查询。
● 数据库是单点,没有高可用。
● 运维工作增多,扩展后部署运维工作增多,需要开发对应的工具应对快速部署。
(4) 读写分离/主从分离架构
简介:
将数据库读写操作分散到不同的节点上,数据库服务器搭建主从集群,一主一从、一主多从都可以,数据库主机负责写操作,从机只负责读操作。
出现原因:
在应用服务集群的架构下,我们把用户的请求,通过负载均衡打在不同服务器上的不同进程中,可以并行进行处理了,同时随着业务的增长,也可以通过动态扩张服务器的数量来缓解压力。可是在现有的架构里,无论扩展多少台服务器,这些请求最终都会从"数据库"读写数据,到一定程度之后,数据的压力反而成为系统承载能力的瓶颈点。我们可以像扩展应用服务器一样扩展数据库服务器么?答案是否定的,因为数据库服务有其特殊性:如果将数据分散到各台服务器之后,数据的一致性将无法得到保障。
架构原理:
数据库成为瓶颈,而互联网应用一般读多写少,数据库承载压力大,主要是由这些读的请求造成的,那么我们可以把读操作和写操作分开。可以看到数据库服务器不再是一个,而是变成了多个,数据库主机负责写操作,从机负责读操作。为了保障数据的一致性,数据库主机通过复制将数据同步到从机(当然这是有时间成本的)。
架构优缺点:
优点:
● 数据库的读取性能提升。
● 读取被其他服务器分担,写的性能间接提升。
● 数据库有从库,数据库的可用性提高了。
缺点:
● "热点数据的频繁" 读取导致数据库负载很高。
● 当同步挂掉,或者同步延迟比较大时,写库和读库的数据不一致。
● 服务器成本需要进一步增加。
(5) 冷热分离架构 —— 引入缓存
简介:
引入缓存,实行冷热分离,将热点数据放到缓存中快速响应。
出现原因:
海量的请求导致数据库负载过高,站点响应再度变慢。发现业务中一些数据的读取频率远大于其他数据的读取频率。我们把这部分数据称为热点数据,与之相对应的是冷数据。通过缓存能把绝大多数请求在读写数据库前拦截掉,大大降低数据库压力。
架构原理:
可以看到多了"缓存服务器",对于"热点数据"全部放到缓存中,不常用数据再去查询我们的数据库。
其中涉及的技术包括:使用 memcached 作为本地缓存,使用Redis 作为分布式缓存,还会涉及缓存一致性、缓存穿透/击穿、缓存雪崩、热点数据集中失效等问题。
相关软件Memcached、 Redis 等缓存软件。
架构优缺点:
优点:
● 大幅降低对数据库的访问请求,性能提升非常明显。
缺点:
● 带来了缓存一致性,缓存击穿,缓存失效,缓存雪崩等问题。
● 服务器成本需要进一步增加。
● 业务体量支持变大后,数据不断增加,数据库单库太大,单个表体量也太大,数据查询会很慢,导致数据库再度成为系统瓶颈。
(6) 垂直分库
简介:
数据库的数据被拆分,数据库数据分布式存储,分布式处理,分布式查询,也可以理解为分布式数据库架构。
出现原因:
单机的写库会逐渐会达到性能瓶颈,需要拆分数据库,数据表的数据量太大,处理压力太大,需要进行分表。为降低运维难度,业界逐渐研发了分布式数据库,库表天然支持分布式。
架构原理:
数据库是由多个主从库或者存储集群构成,支持分布式大规模并行处理。只要实时操作的表数据量足够小,请求能够足够均匀的分发到多台服务器上的小表,那数据库就能通过水平扩展的方式来提高性能。
分库分表:
架构优缺点:
优点:
● 数据库吞吐量大幅提升,不再是瓶颈
缺点:
● 跨库join、分布式事务等问题,这些需要对应的去进行解决,目前的mpp都有对应的解决方案。
● 数据库和缓存结合目前能够抗住海量的请求,但是应用的代码整体耦合在一起,修改一行代码需要整体重新发布
(7) 微服务——业务拆分
简介:
微服务是一种架构风格,按照业务板块来划分应用代码,使单个应用的职责更清晰,相互之间可以做到独立升级迭代。
出现原因:
● 扩展性差:应用程序无法轻松扩展,一旦需要更新应用程序时,都必须重新构建整个系统。
● 持续开发困难:一个很小的代码改动,上下层代码耦合度高,也需要重新部署整个应用,无法频繁并轻松的发布版本。
● 不可靠:即使系统的一个功能不起作用,可能导致整个系统无法工作。
● 不灵活:无法使用不同的技术构建单体应用程序。
● 代码维护难:所有功能耦合在一起,新人不知道何从下手
架构原理:
以电子商城为例,随着人员增加,业务发展,我们将业务分给不同的开发团队去维护。每个团队独立实现自己的微服务,然后互相之间对数据的直接访问进行隔离。我们把商城应用拆分成了多个微服务,如用户服务、交易服务和商品服务,相互之间协作支持整个商城的应用。甚至可以把一些类似用户管理等业务提供成公共服务。
模拟请求:
架构优缺点:
优点:
● 灵活性高:服务独立测试、部署、升级、发布。
● 独立扩展:每个服务可以各自进行扩展。
● 提高容错性:一个服务问题并不会让整个系统瘫痪。
● 新技术的应用容易:支持多种编程语言。
缺点:
● 资源使用变多:所有这些独立运行的微服务都需要需要占用内存和 CPU。
● 处理故障困难:一个请求跨多个服务调用,需要查看不同服务的日志完成问题定位。
● 运维复杂度高:业务不断发展,应用和服务都会不断变多,应用和服务的部署变得复杂。 同一台服务器上部署多个服务还要解决运行环境冲突的问题,此外,对于如大促这类需要动态扩缩容的场景,需要水平扩展服务的性能,就需要在新增的服务上准备运行环境,部署服务等,运维将变得十分困难。
(8) 容器编排 —— 容器化引入
简介:
借助容器化技术(如docker)将应用/服务可以打包为镜像,通过容器编排工具(如k8s)来动态分发和部署镜像,服务以容器化方式运行。
出现原因:
随着业务增长,然后发现系统的资源利用率不高,很多资源用来应对短时高并发,平
时又闲置,需要动态扩缩容,还没有办法直接下线服务器。同时,开发、测试、生产每套环境都要隔离的环境,运维的工作量变的非常大。
● 微服务拆分细,服务多部署工作量大,而且配置复杂,容易出错。
● 微服务数量多扩缩容麻烦,而且容易出错,每次缩容后再扩容又需要重新配置服务对应的环境参数信息。
● 微服务之间运行环境可能冲突,需要更多的资源来进行部署或者通过修改配置来解决冲突。
架构原理:
目前最流行的容器化技术是 Docker,最流行的容器管理服务是 Kubernetes(K8S),应
用/服务可以打包为 Docker 镜像,通过 K8S 来动态分发和部署镜像。
可以这样理解一个Docker:
Docker 镜像可理解为一个能运行你的应用/服务的最小的操作系统,里面放着应用/服务的运行代码,运行环境根据实际的需要设置好。把整个“操作系统”打包为一个镜像后,就可以分发到需
要部署相关服务的机器上,直接启动 Docker 镜像就可以把服务起起来,使服务的部署和运维变得简单。
以电子商城为例,一个商城应用拆分成了多个微服务,如用户服务、交易服务和商品服务,每一个微服务打包到容器之中,相互协作来完成系统功能,通过容器编排工具完成部署运维。
架构优缺点:
优点:
● 部署、运维简单快速:一条命令就可以完成几百个服务的部署或者扩缩容。
● 隔离性好:容器与容器之间文件系统、网络等互相隔离,不会产生环境冲突。
● 轻松支持滚动更新:版本间切换都可以通过一个命令完成升级或者回滚。
缺点:
● 技术栈变多,对研发团队要求高。
● 机器还是需要公司自身来管理,可能会造成闲置资源的浪费。这需要公司自身去管理好服务器资源,假如遇到 需要处理大量请求的段时刻时,可以通过在云厂商购置服务器满足场景需求。
注:以上的所有优缺点,仅仅是站在某一个点上看待,而不是绝对的完全和准确。
总结
架构服务的演进,无非是这样一条路线:
一个架构不能很好解决的问题,不断通过引入新的技术、新的策略更好地支持服务器请求处理的能力。但是,新技术的引进,往往也会带来新的问题。实际中,也不会单独引用某一种架构,而是可能会在某种架构的基础上单独改进。例如,抢票系统,不会涉及到多么复杂度业务场景,就只是时间、价位选择,此时"高并发"才是重点。政务系统,并发量可能不大,但是会涉及到复杂的、丰富的业务场景,此时优先需要的可能会是丰富需求的解决方案。
本篇到此结束,感谢你的阅读。
祝你好运,向阳而生~