分布式架构的演进
系统架构演化历程-初始阶段架构
初始阶段 的小型系统 应用程序、数据库、文件等所有的资源都在一台服务器上通俗称为LAMP
特征:
应用程序、数据库、文件等所有的资源都在一台服务器上。
描述:
通常服务器操作系统使用linux,应用程序使用PHP开发,然后部署在Apache上,数据库使用Mysql,汇集各种免费开源软件以及一台廉价服务器就可以开始系统的发展之路了。
系统架构演化历程-应用服务和数据服务分离
好景不长,发现随着系统访问量的再度增加,webserver机器的压力在高峰期会上升到比较高,这个时候开始考虑增加一台webserver
特征:
应用程序、数据库、文件分别部署在独立的资源上。
描述:
数据量增加,单台服务器性能及存储空间不足,需要将应用和数据分离,并发处理能力和数据存储空间得到了很大改善。
系统架构演化历程-使用缓存改善性能
特征:
数据库中访问较集中的一小部分数据存储在缓存服务器中,减少数据库的访问次数,降低数据库的访问压力。
描述:
系统访问特点遵循二八定律,即80%的业务访问集中在20%的数据上。
缓存分为本地缓存和远程分布式缓存,本地缓存访问速度更快但缓存数据量有限,同时存在与应用程序争用内存的情况。
系统架构演化历程-使用应用服务器集群
在做完分库分表这些工作后,数据库上的压力已经降到比较低了,又开始过着每天看着访问量暴增的幸福生活了,突然有一天,发现系统的访问又开始有变慢的趋势了,这个时候首先查看数据库,压力一切正常,之后查看webserver,发现apache阻塞了很多的请求,而应用服务器对每个请求也是比较快的,看来 是请求数太高导致需要排队等待,响应速度变慢
特征:
多台服务器通过负载均衡同时向外部提供服务,解决单台服务器处理能力和存储空间上限的问题。
描述:
使用集群是系统解决高并发、海量数据问题的常用手段。通过向集群中追加资源,提升系统的并发处理能力,使得服务器的负载压力不再成为整个系统的瓶颈。
系统架构演化历程-数据库读写分离
享受了一段时间的系统访问量高速增长的幸福后,发现系统又开始变慢了,这次又是什么状况呢,经过查找,发现数据库写入、更新的这些操作的部分数据库连接的资源竞争非常激烈,导致了系统变慢
特征:
多台服务器通过负载均衡同时向外部提供服务,解决单台服务器处理能力和存储空间上限的问题。
描述:
使用集群是系统解决高并发、海量数据问题的常用手段。通过向集群中追加资源,使得服务器的负载压力不在成为整个系统的瓶颈。
系统架构演化历程-反向代理和CDN加速
特征:
采用CDN和反向代理加快系统的 访问速度。
描述:
为了应付复杂的网络环境和不同地区用户的访问,通过CDN和反向代理加快用户访问的速度,同时减轻后端服务器的负载压力。CDN与反向代理的基本原理都是缓存。
系统架构演化历程-分布式文件系统和分布式数据库
随着系统的不断运行,数据量开始大幅度增长,这个时候发现分库后查询仍然会有些慢,于是按照分库的思想开始做分表的工作
特征:
数据库采用分布式数据库,文件系统采用分布式文件系统。
描述:
任何强大的单一服务器都满足不了大型系统持续增长的业务需求,数据库读写分离随着业务的发展最终也将无法满足需求,需要使用分布式数据库及分布式文件系统来支撑。
分布式数据库是系统数据库拆分的最后方法,只有在单表数据规模非常庞大的时候才使用,更常用的数据库拆分手段是业务分库,将不同的业务数据库部署在不同的物理服务器上。
系统架构演化历程-使用NoSQL和搜索引擎
特征:
系统引入NoSQL数据库及搜索引擎。
描述:
随着业务越来越复杂,对数据存储和检索的需求也越来越复杂,系统需要采用一些非关系型数据库如NoSQL和分数据库查询技术如搜索引擎。应用服务器通过统一数据访问模块访问各种数据,减轻应用程序管理诸多数据源的麻烦。
系统架构演化历程-业务拆分
特征:
系统上按照业务进行拆分改造,应用服务器按照业务区分进行分别部署。
描述:
为了应对日益复杂的业务场景,通常使用分而治之的手段将整个系统业务分成不同的产品线,应用之间通过超链接建立关系,也可以通过消息队列进行数据分发,当然更多的还是通过访问同一个数据存储系统来构成一个关联的完整系统。
纵向拆分:
将一个大应用拆分为多个小应用,如果新业务较为独立,那么就直接将其设计部署为一个独立的Web应用系统
纵向拆分相对较为简单,通过梳理业务,将较少相关的业务剥离即可。
横向拆分:将复用的业务拆分出来,独立部署为分布式服务,新增业务只需要调用这些分布式服务
横向拆分需要识别可复用的业务,设计服务接口,规范服务依赖关系。
系统架构演化历程-分布式服务
特征:
公共的应用模块被提取出来,部署在分布式服务器上供应用服务器调用。
描述:
随着业务越拆越小,应用系统整体复杂程度呈指数级上升,由于所有应用要和所有数据库系统连接,最终导致数据库连接资源不足,拒绝服务。
Q:分布式服务应用会面临哪些问题?
A:
(1) 当服务越来越多时,服务URL配置管理变得非常困难,F5硬件负载均衡器的单点压力也越来越大。
(2) 当进一步发展,服务间依赖关系变得错踪复杂,甚至分不清哪个应用要在哪个应用之前启动,架构师都不能完整的描述应用的架构关系。
(3) 接着,服务的调用量越来越大,服务的容量问题就暴露出来,这个服务需要多少机器支撑?什么时候该加机器?
(4) 服务多了,沟通成本也开始上升,调某个服务失败该找谁?服务的参数都有什么约定?
(5) 一个服务有多个业务消费者,如何确保服务质量?
(6) 随着服务的不停升级,总有些意想不到的事发生,比如cache写错了导致内存溢出,故障不可避免,每次核心服务一挂,影响一大片,人心慌慌,如何控制故障的影响面?服务是否可以功能降级?或者资源劣化?
Java分布式应用技术基础
分布式服务下的关键技术:消息队列架构
消息对列通过消息对象分解系统耦合性,不同子系统处理同一个消息
分布式服务下的关键技术:消息队列原理
分布式服务下的关键技术:服务框架架构
服务框架通过接口分解系统耦合性,不同子系统通过相同的接口描述进行服务启用
服务框架是一个点对点模型
服务框架面向同构系统
适合:移动应用、互联网应用、外部系统
分布式服务下的关键技术:服务框架原理
分布式服务下的关键技术:服务总线架构
服务总线同服务框架一样,均是通过接口分解系统耦合性,不同子系统通过相同的接口描述进行服务启用
服务总线是一个总线式的模型
服务总线面向同构、异构系统
适合:内部系统
分布式服务下的关键技术:服务总线原理
分布式架构下系统间交互的5种通信模式
request/response模式(同步模式):客户端发起请求一直阻塞到服务端返回请求为止。
Callback(异步模式):客户端发送一个RPC请求给服务器,服务端处理后再发送一个消息给消息发送端提供的callback端点,此类情况非常合适以下场景:A组件发送RPC请求给B,B处理完成后,需要通知A组件做后续处理。
Future模式:客户端发送完请求后,继续做自己的事情,返回一个包含消息结果的Future对象。客户端需要使用返回结果时,使用Future对象的.get(),如果此时没有结果返回的话,会一直阻塞到有结果返回为止。
Oneway模式:客户端调用完继续执行,不管接收端是否成功。
Reliable模式:为保证通信可靠,将借助于消息中心来实现消息的可靠送达,请求将做持久化存储,在接收方在线时做送达,并由消息中心保证异常重试。
五种通信模式的实现方式-同步点对点服务模式
五种通信模式的实现方式-异步点对点消息模式1
五种通信模式的实现方式-异步点对点消息模式2
五种通信模式的实现方式-异步广播消息模式
分布式架构下的服务治理
服务治理是服务框架/服务总线的核心功能。所谓服务治理,是指服务的提供方和消费方达成一致的约定,保证服务的高质量。服务治理功能可以解决将某些特定流量引入某一批机器,以及限制某些非法消费者的恶意访问,并在提供者处理量达到一定程度是,拒绝接受新的访问。
基于服务框架Dubbo的服务治理-服务管理
道你的系统,对外提供了多少服务,可以对服务进行升级、降级、停用、权重调整等操作
可以知道你提供的服务,谁在使用,因业务需求,可以对该消费者实施屏蔽、停用等操作
基于服务框架Dubbo的服务治理-服务监控
可以统计服务的每秒请求数、平均响应时间、调用量、峰值时间等,作为服务集群规划、性能调优的参考指标。
基于服务框架Dubbo的服务治理-服务路由
基于服务框架Dubbo的服务治理-服务保护
基于服务总线OSB的服务治理-功能介绍
基于服务总线OSB的服务治理
Q:Dubbo到底是神马?
A:
淘宝开源的高性能和透明化的RPC远程调用服务框架
SOA服务治理方案
Q:Dubbo原理是?
A:
分布式计算就是通过计算机网络将计算工作分布到多台主机上,多个主机一起协同完成工作。
我试着列一下相关知识吧。
-
网络通讯,网络是分布式的基础,对分布式的理解建立在对网络的理解上,包括:
-
OSI模型的7层
-
TCP/IP,DNS,NAT
-
HTTP,SPDY/HTTP2
-
Telnet
-
-
网络编程,是通过程序在多个主机之间通信。包括:
-
Socket
- 多线程
- 非阻塞IO
- 网络框架
-
Netty
* Mina
* ZeroMQ -
操作系统的网络部分
-
RPC,Socket使用不是很方便,很多分布式应用是基于RPC的,包括:
-
同步RPC
- 异步RPC
- 主要的一些RPC协议
-
RMI
* Rest API
* Thrift -
集群,分布式计算离不开集群。集群就是多台主机被当作一个系统
-
集群类型
-
高可用,如主机备机切换,冷备,热备,双活
* 伸缩性,如Web服务器集群,数据库服务器的Sharding
* 并行计算,如网格,大数据- 集群相关技术,包括:
-
高可用性,保证服务一直能够被访问,延长MTBF,缩短MTTR
-
冗余的设备
* 多副本,为了避免单点失效1
2
3
41 * 负载均衡,如何将大量工作负载分配到多个主机上,最大化吞吐量,最小化平均响应时间,最大化资源利用率。
2 * 伸缩性(横向),能够添加计算机和设备来应对增长的计算压力
3 * 分片(Sharding),把数据分成多个数据集,由多个服务器来分别处理。
4 -
自动分片
1
2
31 * 容错性,当硬件或软件发生故障,能够继续运转
2 * 故障检测,以及故障预测
3 -
心跳包
* 告警
* 性能预警1
2
3
41 * 故障转移,当出现错误,如何解决,为了高可用性和容错性
2 * 分布式一致性,在分布式环境中如何维持状态的一致性,严格一致性,还是最终一致性
3 * 集群状态协调,如Zookeeper,etcd等。
4 -
分布式锁,在分布式环境中如何进行加锁
* 选主,当Master宕机,如何选择出新的Master,协议如Raft1
2
3
41 * 一致性哈希,如何将数据分布到集群中的多个主机。
2
3 * 分布式事务,保证在多台服务器上完成的操作符合事务的ACID属性。
4 -
安全,网络通常需要保证安全。
-
身份认证,如何验证人或机器是他们声明的身份
-
基于用户名/口令
* 基于数字证书- 私密性,如何防止窃听和嗅探
-
对称加密
* 非对称加密- 完整性,如何保证数据不被篡改
-
安全散列
* 消息认证码(MAC)- 不可否认性
-
基于数字证书的数字签名和验签
* 基于密钥的散列,如HMAC -
互联网站的基本架构
-
页面缓存
-
负载均衡器,如HAProxy,Nginx
-
分布式缓存,如Memcache,Redis
-
消息队列,如ActiveMQ,Kafka
-
-
分布式框架
-
关系型数据库(Sharding,主从同步)
- NoSQL
-
HBase,基于HDFS和Zookeeper的NoSQL
* Cassandra,无主集群- 大数据
-
HDFS,分布式文件系统
* MapReduce,将数据处理任务拆分为多个工作,通过集群来完成。
* Spark,提供分布式的数据集抽象
一、三个步骤完成华丽转身——任意软件变为“分布式”
分布式——一个高大上的名词,是计算机软件设计中人民群众喜闻乐见的“逼格满满”、“不明觉厉”的几个名词之一。但很可惜,这玩意儿一点也不复杂,甚至有些“简单”。不信?你只要遵循下述步骤即可将任何一个软件拆分为“分布式”的:
-
将你的整个软件视为一个系统(不管它有多复杂)
-
将整个系统分割为一系列的 Process(进程), 每个 Process 完成一定的功能
-
将这些 Process 分散到不同的机器上。分散后,选择若干种(没错一种可能不够)通信协议把他们连接起来
对付任何软件,是任何软件都可以的。接下来我当然要解释清楚为什么。
二、跳出误区——分布式不等于并行计算
人们常常把分布式系统自然而然的和并行计算联系起来。然而这并不正确。实际上,分布式系统并不一定是并行的,举个简单的例子就能理解——
某软件,功能如下:
- 提示用户输入两个数 A 和 B
- 在内部,对 A 和 B 执行某数学运算,获得 C
- 输出 C
很简单吧?这三个步骤是无法并行的。它们需要被依次执行。但是这个软件依然可以被改为分布式的,方法就是用前面提到的方法,把步骤 2 的计算过程独立为一个 Process 移动到另外一台计算机上完成。
如果我们从整个系统流程的观点来看,并没有什么并行。整个过程都是顺序执行的。只不过执行时出现了“跨设备”的现象而已。可见,分布式本身就只如其字面意思所指,指的仅仅是从结构角度的分散而已。
当然啊,现实世界中,我们更多的时候钟情于分布式,还是因为它与并行之间可以相互配合。例如实现既是分布同时也是并行的系统。
好了,理解这一点之后就不难解释为什么我会说前文提到的三步骤是万用大法了。接下来我们继续讨论分布式本身。
三、拆分+连接是分布式系统的本质
所谓分布式,无非就是”将一个系统拆分成多个子系统并散布到不同设备“的过程而已。
本质上而言,实现一个分布式系统,最核心的部分无非有两点:
- 如何拆分——可以有很多方式,核心依据一是业务需求,二是成本限制。这是实践中构建分布式系统时最主要的设计依据。
- 如何连接——光把系统拆开成 Process 还不够,关键是拆开后的 Process 之间还要能通信,因此涉及通信协议设计的问题,需要考虑的因素很多,好消息是这部分其实成熟方案很多
四、为什么你要使用分布式?
分布式系统并非灵丹妙药,解决问题的关键还是看你对问题本身的了解。通常我们需要使用分布式的常见理由是:
- 为了性能扩展——系统负载高,单台机器无法承载,希望通过使用多台机器来提高系统的负载能力
- 为了增强可靠性——软件不是完美的,网络不是完美的,甚至机器本身也不可能是完美的,随时可能会出错,为了避免故障,需要将业务分散开保留一定的冗余度
在以提供 Service 为主的服务端软件开发过程中常常遇到这些问题。
五、一些分布式方案能解决你的问题,另一些却不能,要学会的其实是选择
笼统的讨论分布式没有太大的意义,就如我刚才所谈的,实际上分布式很容易实现。真正难的地方在于如何选择正确的分布方案。
例如,当你想要建立一个分布式的数据管理系统的时候,你就必须得面对“一致性”问题。如果你对数据一致性要求很高,你就不得不容忍一些缺陷例如规模伸缩困难;而如果你放弃它,你可以轻松伸缩规模,但你必须解决好由此带来的一系列数据不一致导致的问题。(CAP 问题)
于是你会意识到,有许多种分布方案,为了正确解决你的问题,你需要对每一个方案都进行了解,并评估,选择不同的方案有时候区别不大,有时候却会深刻的影响整个系统中其他部分的工作方式,甚至影响用户界面中用户操作时的流程。这是我们学习分布式系统的重点所在。
六、分布式学习入门——基础知识要点
如我前面所讲,分布式入门不难。主要包含如下知识点:
- Process(进程)。在分布式系统中,进程是基本单元
- 通信协议。Process 间需要相互配合才能完成工作,因此通信协议是最基本要解决的问题。这部分其实挺复杂,牵涉面光,不过核心还是抓住两方面,一是存在哪些需求,二是各个协议如何满足这些需求
- 命名法。两个 Process 要通信,必须相互知道对方的名字,名字可以是数字,也可以是结构化的字符串。例如众所周知域名系统就是一种命名方案,但是方案还有很多,各有特点
- 协作。上面都在谈 Process 之间的通信,可是为什么要通信?因为要协作。协作是个复杂的主题,其中最基本最基本的一个问题就是同步问题。而聊同步问题必然要聊“锁”……知识点就这么展开了
上面几点是最基础的知识。了解了这些其实就算入门了。可是如何进阶呢?那么必然要开始学习下面的问题:
- 一致性。数据存储时,最基本的问题。其实也是实际设计系统时常常需要反复考虑的问题
- 容错。冗余是容错的基础,但并不是全部,分布式本身为实现容错提供了一些便利,这也是实际设计系统时常常需要考虑的问题
好了,如果这些你都学的差不多了,那咱们“纸上谈兵”也就告一段落了。接下来进入实战演练。
七、实战演练?其实你已经开发过分布式系统了
你有没有开发过简单的增删改查软件?这类软件通常都需要搭配一个独立的数据库管理系统共同完成功能。实际上,只要你开发过这么简单的软件,那么你就已经开发过分布式系统了。
“什么,基于数据库管理系统开发出来的软件就可以算分布式呀?我做了很多这类软件,怎么我从来没听过这种说法? 真的,我没开玩笑。还记得我们前面提到的吗,什么是分布式?不就是一个大系统拆分成多个小系统分散到不同的设备上吗。回想一下,当你写一个简单的增删改查软件时,只要用到数据库管理系统,是不是具有如下特点:
- 整个系统中,你写的代码跑在 A 进程里,而数据库管理系统则跑在另外一个进程 B 里
- A 进程与 B 进程通过某种通信协议连接
- 既可以使 A 进程与 B 进程运行在同一台机器上,也可以将它们分开运行于不同的机器上,并且系统依然可以照常运行
你看,这不就是分布式系统的特点吗?
“啊,原来如此,可是我印象里一说分布式的话,应该会讲「集群」啊啥的吧,这么简单的也算?”
关于「集群」的问题我们之后会谈到,它也是分布式系统的一个应用,但谈集群的时候,我们谈的往往是更具体的东西。但咱们看问题,需要抓住本质。别看麻雀小,五脏却俱全。
不过,你已经熟悉的东西,我们在这里就不再展开了,我们不妨关注其他一些更有趣的话题。