分布式系统(distributed system)是建立在网络之上的软件系统,它有两个特性:
在分布式数据库系统中,用户感觉不到数据是分布的,即用户不须知道关系是否分割、有无副本、数据存于哪个站点以及事务在哪个站点上执行等。
简单来讲:在一个分布式系统中,一组独立的计算机展现给用户的是一个统一的整体,就好像是一个系统似的
在上图中,提到了一个SOA架构,那么这个SOA是什么呢?
这是一个主流的架构模型,与其功能类似也是我们经常听到用到的是微服务架构
SOA全称(Service Oriented Architecture) 中文意思为 面相服务的架构,他是一种设计方法,包含多个服务,服务之间通过相互依赖最终提供一系列的功能, 一个服务通常以独立的形式存在与操作系统进程中,各个服务之间通过网络调用
跟SOA相提并论的还有ESB(企业服务总线),简单来说ESB就是管道,链接各个服务节点,为了集成不同系统和不同协议,ESB做消息的转化解释和路由的工作。让不同的服务连通。
在未使用SOA架构时,系统初期:
看起来是不是很糟糕,此时SOA架构应运而生,有了SOA之后就变成这个样子:
是不是看起来好多啦
分布式架构的设计思路就是当业务发展到一定程度后,需要对服务进行解耦,进而把一个单一的大系统按逻辑拆分成不同的子系统,通过服务接口来通讯。
面向服务的设计模式,最终需要总线集成服务,而且大部分时候还共享数据库,出现单点故障时会导致总线层面的故障,更进一步可能会把数据库拖垮,所以才有了更加独立的设计方案的出现。
所以SOA解决了:
微服务是真正意义上的独立服务,从服务入口到数据持久层,逻辑上都是独立隔离的,无需服务总线来接入,但同时也增加了整个分布式系统的搭建和管理难度,需要对服务进行编排和管理,所以伴随着微服务的兴起,微服务生态的整套技术栈也需要无缝接入,才能支撑起微服务的治理理念。
微服务架构和SOA架构类似,微服务架构是在SOA上做的升华,微服务架构强调的一个重点是“业务需要彻底的组件化和服务化”,原有的单个业务系统会拆分为多个可以独立开发设计运行的小应用。这些小应用之间通过服务完成交互和集成。
组件表示一个可以独立更换和升级的单元,像 PC机中的 CPU 内存,显卡 等 独立且可以更换升级而不影响其他单元,如果我们把PC机作为组件以服务的方式构建,那么这台PC只需要维护主板和一些必要的外部设备,CPU ,内存,硬盘 都是以组件方式提供服务,PC需要调用CPU做计算机处理,只需要知道CPU这个组件的地址即可。
如果一个分布式系统具备如下特点,则可以称之为“微服务架构”:
提到分布式,就不得不说一下节点的概念
传统的节点也就是一台单体的物理机,所有的服务都揉进去包括服务和数据库;
随着虚拟化的发展,单台物理机往往可以分成多台虚拟机,实现资源利用的最大化,节点的概念也变成单台虚拟机上面服务;
近几年容器技术逐渐成熟后,服务已经彻底容器化,也就是节点只是轻量级的容器服务。
总体来说,节点就是能提供单位服务的逻辑计算资源的集合。
分布式架构的根基就是网络,不管是局域网还是公网,没有网络就无法把计算机联合在一起工作,但是网络也带来了一系列的问题。
网络消息的传播有先后,消息丢失和延迟是经常发生的事情,我们定义了三种网络工作模式:
同步网络
半同步网络
异步网络
常用网络传输层有两大协议的特点简介:
初始阶段 的小型系统 应用程序、数据库、文件等所有的资源都在一台服务器上通俗称为LAMP
应用程序、数据库、文件分别部署在独立的资源上
好景不长,发现随着系统访问量的再度增加,webserver机器的压力在高峰期会上升到比较高,这个时候开始考虑增加一台webserver
缓存是分布式系统中的重要组件,主要解决高并发,大数据场景下,热点数据访问的性能问题。
提供高性能的数据快速访问。你可以理解为从磁盘里取出来数据,暂时存放在内存,以待后面处理来读取。而能存放在缓存的数据,通常是频繁访问的,不会经常修改的数据。
系统访问特点遵循二八定律,即80%的业务访问集中在20%的数据上。缓存分为本地缓存和远程分布式缓存,本地缓存访问速度更快但缓存数据量有限,同时存在与应用程序争用内存的情况。
数据库中访问较集中的一小部分数据存储在缓存服务器中,减少数据库的访问次数,降低数据库的访问压力
对于不熟悉业务代码或算法的优化者,显然加一层缓存的复杂度和风险更低,而这一层看似简单的缓存,它给系统带来的性能优化有可能大大超过前者)
在WebServer和DB之间加一层cache,这层cache一般选取的介质是内存,因为我们都知道存入数据库的数据都具有持久化的特点,那么读写会有磁盘IO的操作,内存的读写速度远比磁盘快得多。(选用存储介质,提高访问速度:内存>>磁盘;减少磁盘IO的操作,减少重复查询,提高吞吐量)
常见的缓存有:
缓存系统常用的缓存淘汰策略:
分布式缓存都采用Hash算法进行数据分片,将数量庞大的缓存项均匀分布到集群中的每个节点上,比如Redis3.0开始实现的分布式集群功能就采用了Hash算法,将缓存项均匀分布到16384个Slot上去。
以Redis2.x为基础改造的Codis是国内分布式缓存开源的一个典范,出自豆瓣网。
Memcache本身并没有提供集群功能,但很多客户端Driver实现了Hash算法分配逻辑,因此也可以看成是一种分布式缓存的解决方案。
内存计算产品:商业的SAP Hana、开源的VoltDB等。VoltDB是一种开源的高性能的内存关系型数据库,提供社区版和商业版,是一种NewSql,是一个借鉴并基于HSQL的分配内存数据库集群。
更多分布式缓存信息点击此处查看
使用集群是系统解决高并发、海量数据问题的常用手段。通过向集群中追加资源,提升系统的并发处理能力,使得服务器的负载压力不再成为整个系统的瓶颈。
同时多台服务器通过负载均衡同时向外部提供服务,解决单台服务器处理能力和存储空间上限的问题。
享受了一段时间的系统访问量高速增长的幸福后,发现系统又开始变慢了,这次又是什么状况呢,经过查找,发现数据库写入、更新的这些操作的部分数据库连接的资源竞争非常激烈,导致了系统变慢,至此我们可以通过设计数据集群,以及数据库的主从库,主负责写入,从库负责读取
为了应付复杂的网络环境和不同地区用户的访问,通过CDN和反向代理加快用户访问的速度,同时减轻后端服务器的负载压力。CDN与反向代理的基本原理都是缓存。
不知道CDN是啥的,可以参考博文秒杀系统面试-2.1小节
任何强大的单一服务器都满足不了大型系统持续增长的业务需求,数据库读写分离随着业务的发展最终也将无法满足需求,需要使用分布式数据库及分布式文件系统来支撑。
分布式数据库是系统数据库拆分的最后方法,只有在单表数据规模非常庞大的时候才使用,更常用的数据库拆分手段是业务分库,将不同的业务数据库部署在不同的物理服务器上。
常见的分布式缓存,数据库,文件系统如下:
在DNS服务器中可配置一个域名对应多个IP地址,每个IP地址对应到不同的机房里的虚拟IP。当用户访问www.taobao.com时,DNS服务器会使用轮询策略或其他策略,来选择某个IP供用户访问。此方式能实现机房间的负载均衡,至此,系统可做到机房级别的水平扩展,千万级到亿级的并发量都可通过增加机房来解决,系统入口处的请求并发量不再是问题。
当数据库中的数据多到一定规模时,数据库就不适用于复杂的查询了,往往只能满足普通查询的场景。对于统计报表场景,在数据量大时不一定能跑出结果,而且在跑复杂查询时会导致其他查询变慢,对于全文检索、可变数据结构等场景,数据库天生不适用。因此需要针对特定的场景,引入合适的解决方案。
如对于海量文件存储,可通过分布式文件系统HDFS解决,对于key value类型的数据,可通过HBase和Redis等方案解决,对于全文检索场景,可通过搜索引擎如ElasticSearch解决,对于多维分析场景,可通过Kylin或Druid等方案解决。
下面我重点讲解一下nosql
概念:
两者的区别:
系统上按照业务进行拆分改造,应用服务器按照业务区分进行分别部署。
如用户管理、订单、支付、鉴权等功能在多个应用中都存在,那么可以把这些功能的代码单独抽取出来形成一个单独的服务来管理,这样的服务就是所谓的微服务,应用和服务之间通过HTTP、TCP或RPC请求等多种方式来访问公共服务,每个单独的服务都可以由单独的团队来管理。
此外,可以通过Dubbo、SpringCloud等框架实现服务治理、限流、熔断、降级等功能,提高服务的稳定性和可用性。
通过ESB统一进行访问协议转换,应用统一通过ESB来访问后端服务,服务与服务之间也通过ESB来相互调用,以此降低系统的耦合程度。
这种单个应用拆分为多个应用,公共服务单独抽取出来来管理,并使用企业消息总线来解除服务之间耦合问题的架构,就是所谓的SOA(面向服务)架构,这种架构与微服务架构容易混淆,因为表现形式十分相似。
微服务架构更多是指把系统里的公共服务抽取出来单独运维管理的思想,而SOA架构则是指一种拆分服务并使服务接口访问变得统一的架构思想,SOA架构中包含了微服务的思想。
业务不断发展,应用和服务都会不断变多,应用和服务的部署变得复杂,同一台服务器上部署多个服务还要解决运行环境冲突的问题,此外,对于如大促这类需要动态扩缩容的场景,需要水平扩展服务的性能,就需要在新增的服务上准备运行环境,部署服务等,运维将变得十分困难
目前最流行的容器化技术是Docker,最流行的容器管理服务是Kubernetes(K8S),应用/服务可以打包为Docker镜像,通过K8S来动态分发和部署镜像。
Docker镜像可理解为一个能运行你的应用/服务的最小的操作系统,里面放着应用/服务的运行代码,运行环境根据实际的需要设置好。
把整个“操作系统”打包为一个镜像后,就可以分发到需要部署相关服务的机器上,直接启动Docker镜像就可以把服务起起来,使服务的部署和运维变得简单。
在大促的之前,可以在现有的机器集群上划分出服务器来启动Docker镜像,增强服务的性能,大促过后就可以关闭镜像,对机器上的其他服务不造成影响。
系统可部署到公有云上,利用公有云的海量机器资源,解决动态硬件资源的问题,在大促的时间段里,在云平台中临时申请更多的资源,结合Docker和K8S来快速部署服务,在大促结束后释放资源,真正做到按需付费,资源利用率大大提高,同时大大降低了运维成本。
所谓的云平台,就是把海量机器资源,通过统一的资源管理,抽象为一个资源整体,在之上可按需动态申请硬件资源(如CPU、内存、网络等),并且之上提供通用的操作系统,提供常用的技术组件(如Hadoop技术栈,MPP数据库等)供用户使用,甚至提供开发好的应用,用户不需要关系应用内部使用了什么技术,就能够解决需求(如音视频转码服务、邮件服务、个人博客等)。在云平台中会涉及如下几个概念:
至此,以上所提到的从高并发访问问题,到服务的架构和系统实施的层面都有了各自的解决方案,但同时也应该意识到,在上面的介绍中,其实是有意忽略了诸如跨机房数据同步、分布式事务实现等等的实际问题。
在了解分布式事务之前,我先引入一个概念:时间与顺序
对于串行的事务来说,很简单的就是跟着时间的脚步走就可以,先来后到的发生。而后我们发明了时钟来刻画以往发生的时间点,时钟让这个世界井然有序。但是对于分布式世界来说,跟时间打交道着实是一件痛苦的事情。
分布式世界里面,我们要协调不同节点之间的先来后到关系,不同节点本身承认的时间又各执己见,于是我们创造了**网络时间协议(NTP)**试图来解决不同节点之间的标准时间,但是 NTP 本身表现并不尽如人意,所以我们又构造出了逻辑时钟,最后改进为向量时钟:
有了衡量时间的工具,解决顺序问题自然就是水到渠成了。
因为整个分布式的理论基础就是如何协商不同节点的一致性问题,而顺序则是一致性理论的基本概念。
有了上面信息的一些基础认知之后,我们开始正式描述分布式的事务理论
主要通过三个非常重要的理论来进行刻画
首先我们先看一下ACID理论
单机环境下我们对传统关系型数据库有苛刻的要求,由于存在网络的延迟和消息丢失,ACID 便是保证事务的原则,这四大原则便是:
请大家务必牢记
ACID是数据库的本地事务,而事务的ACID是通过InnoDB日志和锁来保证
分布式系统理论上不可能选择 CA (一致性 + 可用性)架构,只能选择 CP(一致性 + 分区容忍性) 或者 AP (可用性 + 分区容忍性)架构,在一致性和可用性做折中选择。
另外,只能选择CP或者AP是指系统发生分区现象时无法同时保证C(一致性)和A(可用性),但不是意味着什么都不做,当分区故障解决后,系统还是要保持保证CA
多数情况下,其实我们也并非一定要求强一致性,部分业务可以容忍一定程度的延迟一致,所以为了兼顾效率,发展出来了最终一致性理论 BASE。BASE 是指
CAP 理论是忽略延时的,而实际应用中延时是无法避免的,这一点就意味着完美的 CP 场景是不存在的,即使是几毫秒的数据复制延迟,在这几毫秒时间间隔内,系统是不符合 CP 要求的。因此 CAP 中的 CP 方案,实际上也是实现了最终一致性,只是“一定时间”是指几毫秒而已。
同时方案中牺牲一致性只是指发生分区故障期间,而不是永远放弃一致性,这一点其实就是 BASE 理论延伸的地方,分区期间牺牲一致性,但分区故障恢复后,系统应该达到最终一致性。
总结: BASE解决了CAP中理论没有网络延迟,在BASE中用软状态和最终一致,保证了延迟后的一致性。BASE和 ACID 是相反的,它完全不同于ACID的强一致性模型,而是通过牺牲强一致性来获得可用性,并允许数据在一段时间内是不一致的,但最终达到一致状态。
有了这些分布式事务的理论,我们再接着聊聊分布式事务解决方案
二阶段提交协议(Two-phase Commit,即2PC)是常用的分布式事务解决方案,即将事务的提交过程分为两个阶段来进行处理:准备阶段和提交阶段。
核心思想就是对每一个事务都采用先尝试后提交的处理方式,处理后所有的读操作都要能获得最新的数据,因此也可以将二阶段提交看作是一个强一致性算法。
简单理解就是:
但是2PC方案也会面临很多问题
架构的调整是否必须按照上述演变路径进行?
不是的,以上所说的架构演变顺序只是针对某个侧面进行单独的改进,在实际场景中,可能同一时间会有几个问题需要解决,或者可能先达到瓶颈的是另外的方面,这时候就应该按照实际问题实际解决。如在政府类的并发量可能不大,但业务可能很丰富的场景,高并发就不是重点解决的问题,此时优先需要的可能会是丰富需求的解决方案。
对于将要实施的系统,架构应该设计到什么程度?
对于单次实施并且性能指标明确的系统,架构设计到能够支持系统的性能指标要求就足够了,但要留有扩展架构的接口以便不备之需。对于不断发展的系统,如电商平台,应设计到能满足下一阶段用户量和性能指标要求的程度,并根据业务的增长不断的迭代升级架构,以支持更高的并发和更丰富的业务。
服务端架构和大数据架构有什么区别?
所谓的“大数据”其实是海量数据采集清洗转换、数据存储、数据分析、数据服务等场景解决方案的一个统称,在每一个场景都包含了多种可选的技术,如:
总的来说大数据架构就是根据业务的需求,整合各种大数据组件组合而成的架构,一般会提供分布式存储、分布式计算、多维分析、数据仓库、机器学习算法等能力。而服务端架构更多指的是应用组织层面的架构,底层能力往往是由大数据架构来提供。
至此分布式的基础理论就到此结束啦,接下来我们谈一谈分布式在具体通过业务场景浅谈分布式设计思路