什么是分布式系统

本文转自InfoQ,原做者:张帆mysql

若是如今让你阐述一下什么是“分布式系统”,你脑子里第一下跳出来的是什么?我想,此时能够用苏东坡先生的一句诗,来形象地描述你们对分布式系统的认识:sql

横当作岭侧成峰,远近高低各不一样

我以为每一个人脑子里一会儿涌现出来的确定是很是具象的东西,就像下面这些:数据库

一:“分布式系统”等于 SOA、ESB、微服务这些东西吗?

若是你一会儿想到的是 XX 中心、XX 服务,意味着你把服务化的模式(SOA、ESB、微服务)和分布式系统错误地划上了等号。缓存

那么,什么是“服务化”呢?服务化就像企业当中将相同岗位的人员划分到同一个部门管理,以此来收敛特定的工做入口,再进行二次分配,以提升人员利用率和劳动成果的复用度。服务化的本质是“分治”,而“分治”的前提是先要拆,而后才谈得上如何治。这时,高内聚、低耦合的思想在拆分过程当中起到了一个很是重要的做用,由于这能够尽量地下降拆分后不一样组件间进行协做的复杂度。因此重要的是“怎么拆“,还有如何按部就班地拆,而这个过程当中你到底是采用了何种服务化模式(好比 SOA、ESB、微服务等)并非关键。架构

为何说“怎么拆”最重要呢?我来举个例子,企业的组织架构包括三种模型:职能型、项目型、矩阵型。你能够把这里的企业理解为一个“分布式系统”,把后面的 3 种模型理解为这个分布式系统的 3 种形态。做为这个“系统”的全部人,你须要考虑如何拆分它,才能使得各功能组件相互之间能够更好地协做。假设,你要将一个总计 10000 名员工的企业按“职能型”拆分红 20 个部门,获得的结果是每一个部门 500 人。app

这时,若是工做是流水线式的上下游关系。一个部门完工了再交给下一个部门。框架

那么这时候是高内聚、低耦合的。由于一个工种只与另外一个工种产生了关联,而且仅有一次。异步

但若是工做须要频繁的由不一样职能的人员同时进行,会致使同一个部门可能与多个部门产生联系。分布式

那么,这时是低内聚、高耦合的。由于一个工种须要和其余多个工种产生关联而且远不止一次。函数

能够看到服务化体现了“分治”的效果,这也是分布式系统的核心思想,所以从“分治”这个本质上来看,服务化的确是分布式系统,但分布式系统不只仅停留在那些服务化的模式上。

我相信,你在工做中参与开发的任何软件系统,处处都存在着须要拆分的地方,除非它的功能极简到只须要计算一个 1+1。好比,当咱们在电商平台点击“提交订单”的时候,会涉及生成订单、扣除积分、扣除库存等等动做。电商系统初期全部的功能可能都在一个系统里面,那么这些操做能够写在一个方法体里吗?我想只要代码可以成功运行,大部分人是不会管你怎么写的。可是若是这时须要增长一个红包功能呢?相信你或多或少遇到过在几百上千行代码中去增改功能的事情,其中的痛苦应该深有体会。

要解决这个问题就是要作拆分,经过梳理、归类,将不一样的紧密相关的部分收敛到一个独立的逻辑体中,这个逻辑体能够是函数、类以及命名空间,等等。因此,从这个角度来讲“分治”的问题其实早就存在咱们的工做中,就看咱们是否有去关注它了。所以,这并不仅是咱们在进行服务化时才须要考虑的问题。

那么如何才能作好这个事情,更好的拆分能力正是咱们须要掌握的。若是只是由于看到其余人这么拆,我也这么拆,根据“二八原则”,或许“依样画葫芦”能够达到 80% 的契合度,可是每每那剩下的 20% 会是耗费咱们 80% 精力的“大麻烦”。要知道,只有掌握了核心主旨,才能更快地找到最理想的高内聚、低耦合方案

二:"分布式系统"是各个中间件么?

又或许,听到分布式系统,你想到了某某 MQ 框架、某某 RPC 框架、某某 DAL 框架,把运用中间件和分布式系统错误地划上了等号。

这里须要搞清楚的是,中间件起到的是标准化的做用。中间件只是承载这些标准化想法的介质、工具,能够起到引导和约束的效果,以此起到大大下降系统复杂度和协做成本的做用。咱们来分别看一下:

  • MQ 框架标准化了不一样应用程序间非实时异步通讯的方式。

  • RPC 框架标准化了不一样应用程序间实时通信的方式。

  • DAL(Data Access Layer,数据访问层)框架标准化了应用程序和数据库之间通信的方式。

因此,虽然分布式系统中会运用中间件,但分布式系统却不只仅停留在用了什么中间件上。你须要清楚每一类中间件背后是对什么进行了标准化,它的目的是什么,带来了哪些反作用,等等。只有如此,你才能真正识别不一样技术框架之间的区别,找到真正适合当前系统的技术框架。

那么标准是拍脑壳决定的吗?确定不是,正如前面所说每一次标准化都是有目的的,须要产生价值。好比,大部分中间件都具有这样一个价值:

为了在软件系统的迭代过程当中,避免将精力过多地花费在某个子功能下众多差别不大的选项中。

 

在现实中,这点更多时候出如今技术层面的中间件里,好比,数据库访问框架的做用是为了标准化操做不一样数据库的差别,使得上层应用程序不用纠结于该怎么与 mysql 交互或者该怎么与 SQL SERVER 交互。由于与业务相比,技术层面“稳定”多了,因此作标准化更有价值,更能得到长期收益。但“稳定”是相对的,哪怕单纯在业务层面也存在相对稳定的部分。

好比,你能够想象一下“盛饭”的场景,在大多数状况下其中相对稳定的是什么,不稳定的是什么。想完以后看下面的示例。

...
基类:人 
继承基类的子类:男人、女人

基类:碗 
继承基类的子类:大碗、小碗、汤碗

基类:勺子 
继承基类的子类:铁勺、陶瓷勺、塑料勺

function 盛饭(参数 人,参数 碗,参数 勺子){
    do 人拿起碗
    do 人拿起勺子
    do 人用勺子舀起饭
    do 人把勺子放到碗的上方并倒下

} 
...

从这个示例里咱们发现,不稳定的部分都已经成为变量了,那么剩下的这个方法体起到的做用和前面提到的中间件是同样的,它标准化,标准化了盛饭的过程。因此识别相对稳定的部分是什么,如何把它们提炼出来,而且围绕这些点进行标准化,才是咱们须要掌握的能力。而锻炼这个能力和须要这个能力的地方一样并不局限于分布式系统。

列举这些现象只是想说,咱们在认知一个分布式系统的时候,内在胜于表象,掌握一个扎实的理论基本功更为重要。并且,这些训练场无处不在。

三:海市蜃楼般的“分布式系统”

我相信,自从进入移动时代以来,各类高大上的系统架构图愈来愈频繁地出现,你的眼前充斥着各类主流、非主流的眼花缭乱的技术框架。你不禁得肃然起敬一番,心中呐喊着:“对,这就是我想去的地方,我想参与甚至实现一个这样牛逼的分布式系统,不再想天天只是增删改查了。”

得不到的事物老是美好的,但每每咱们也会过分地高估它的美好。与此相似,高大上的架构图背后呈现的系统的确也是一个成熟分布式系统的样貌,但咱们要清楚一点:罗马不是一日建成的。

并且,“分布式”这个词只是意味着形态上是散列状的,而“一分为二”和“一分为 N”本质上并无区别。因此,不少小项目或者大型项目的初期所搭配的基础套餐“单程序 + 单数据库”,一样能够理解为分布式系统,其中遇到的问题不少一样也存在于成熟的分布式系统中。

想象一下,下面的场景是否在“单程序 + 单数据库”项目中出现过?

  • log 记录执行成功,可是数据库的数据没发生变化;

  • 进程内的缓存数据更新了,可是数据库更新失败了。

这里咱们停顿 30 秒,思考一下为何会出现这些问题?

这里须要咱们先思考一下“软件”是什么。 软件的本质是一套代码,而代码只是一段文字,除了提供文字所表述的信息以外,自己没法“动”起来。可是,想让它“动”起来,使其可以完成一件咱们指定的事情,前提是须要一个宿主来给予它生命。这个宿主就是计算机,它可让代码变成一连串可执行的“动做”,而后经过数据这个“燃料”的触发,“动”起来。这个持续的活动过程,又被描述为一个运行中的“进程”。

那么除了咱们开发的系统是软件,数据库也是软件,前者负责运算,后者负责存储运算后的结果(也可称为“状态”),分工协做。

因此,“单程序 + 单数据库”为何也是分布式系统这个问题就很明白了。由于咱们所编写的程序运行时所在的进程,和程序中使用到的数据库所在的进程,并非同一个。也所以致使了,让这两个进程(系统)完成各自的部分,然后最终完成一件完整的事,变得再也不像由单个个体独自完成这件事那么简单。这就如“两人三足”游戏同样,如何尽量地让外部看起来像是一个总体、天然地前进。

因此,咱们能够这么理解,涉及多个进程协做才能提供一个完整功能的系统就是“分布式系统”。

那么再回到上面举例的两个场景,咱们在思考“单程序 + 单数据库”项目中遇到的这些问题背后的缘由和解决它的过程时,与咱们在一个成熟的分布式系统中的遭遇是同样的,例如数据一致性。固然,这只是分布式系统核心概念的冰山一角。

维基百科对“分布式系统”的宏观定义是这样的:

分布式系统是一种其组件位于不一样的联网计算机上的系统,而后经过互相传递消息来进行通讯和协调。为了达到共同的目标,这些组件会相互做用。

咱们能够再以大小关系来解释它:把须要进行大量计算的工程数据分割成小块,由多台计算机分别计算,而后将结果统一合并得出数据结论的科学。这本质上就是“分治”。而“单程序 + 单数据库”组合的系统也包含了至少两个进程,“麻雀虽小五脏俱全”,这也是“分布式系统”。

四:总结

如今,咱们搞清楚了,看待一个“分布式系统”的时候,内在胜于表象。以及,只要涉及多个进程协做才能提供一个完整功能的系统,就是“分布式系统”

我相信还有不少其余景象出现你的脑海中,但这大多数都是分布式系统的本质产生的“化学反应”,进而造成的结果。若是停留在这些表象上,那么咱们最终将没法寻找到“分布式系统”的本质,也就没法获得真正的“道”,更不会真正具有驾驭这些形态万千的“分布式系统”的能力。

因此,但愿你在学习分布式系统的时候,不要因追逐“术”而丢了“道”。没有“道”只有“术”是空壳,最终会走火入魔,学得越多,会越混乱,处处都是矛盾和疑惑。

所以,咱们这个系列除了教给你在具体场景下的最佳实践,还会和你讲解为何这样作,以及该如何去权衡不一样方案。不会过多的讲述具体的技术框架,大部份内容围绕理论展开,欲使每一个人可以掌握好这些分布式中的基础理论和思路,修炼好本身的内功。

我将在后续的文章中,以一个项目的初期到成熟期做为路线图,带领你按部就班地深刻到分布式系统中,层层递进地去剥开它的本质,而且围绕这个本质去思考(是什么问题,有哪些方式能够解决,何时该用何种种方式等等),让你知其然且知其因此然,造成一套完整的知识体系,完成核心“骨架”的塑造。而在此以后,你本身在课外学习时,就能够去填充“血肉”部分,逐渐丰满本身。将来,你们的区别就在于胖一点和瘦一点,但只要能很好地完成工做,胖瘦又有何影响?

 

 

那么,这时是低内聚、高耦合的。由于一个工种须要和其余多个工种产生关联而且远不止一次。

能够看到服务化体现了“分治”的效果,这也是分布式系统的核心思想,所以从“分治”这个本质上来看,服务化的确是分布式系统,但分布式系统不只仅停留在那些服务化的模式上。

我相信,你在工做中参与开发的任何软件系统,处处都存在着须要拆分的地方,除非它的功能极简到只须要计算一个 1+1。好比,当咱们在电商平台点击“提交订单”的时候,会涉及生成订单、扣除积分、扣除库存等等动做。电商系统初期全部的功能可能都在一个系统里面,那么这些操做能够写在一个方法体里吗?我想只要代码可以成功运行,大部分人是不会管你怎么写的。可是若是这时须要增长一个红包功能呢?相信你或多或少遇到过在几百上千行代码中去增改功能的事情,其中的痛苦应该深有体会。

要解决这个问题就是要作拆分,经过梳理、归类,将不一样的紧密相关的部分收敛到一个独立的逻辑体中,这个逻辑体能够是函数、类以及命名空间,等等。因此,从这个角度来讲“分治”的问题其实早就存在咱们的工做中,就看咱们是否有去关注它了。所以,这并不仅是咱们在进行服务化时才须要考虑的问题。

那么如何才能作好这个事情,更好的拆分能力正是咱们须要掌握的。若是只是由于看到其余人这么拆,我也这么拆,根据“二八原则”,或许“依样画葫芦”能够达到 80% 的契合度,可是每每那剩下的 20% 会是耗费咱们 80% 精力的“大麻烦”。要知道,只有掌握了核心主旨,才能更快地找到最理想的高内聚、低耦合方案

2“分布式系统”是各类中间件吗?

又或许,听到分布式系统,你想到了某某 MQ 框架、某某 RPC 框架、某某 DAL 框架,把运用中间件和分布式系统错误地划上了等号。

这里须要搞清楚的是,中间件起到的是标准化的做用。中间件只是承载这些标准化想法的介质、工具,能够起到引导和约束的效果,以此起到大大下降系统复杂度和协做成本的做用。咱们来分别看一下:

  • MQ 框架标准化了不一样应用程序间非实时异步通讯的方式。

  • RPC 框架标准化了不一样应用程序间实时通信的方式。

  • DAL(Data Access Layer,数据访问层)框架标准化了应用程序和数据库之间通信的方式。

因此,虽然分布式系统中会运用中间件,但分布式系统却不只仅停留在用了什么中间件上。你须要清楚每一类中间件背后是对什么进行了标准化,它的目的是什么,带来了哪些反作用,等等。只有如此,你才能真正识别不一样技术框架之间的区别,找到真正适合当前系统的技术框架。

那么标准是拍脑壳决定的吗?确定不是,正如前面所说每一次标准化都是有目的的,须要产生价值。好比,大部分中间件都具有这样一个价值:

为了在软件系统的迭代过程当中,避免将精力过多地花费在某个子功能下众多差别不大的选项中。

在现实中,这点更多时候出如今技术层面的中间件里,好比,数据库访问框架的做用是为了标准化操做不一样数据库的差别,使得上层应用程序不用纠结于该怎么与 mysql 交互或者该怎么与 SQL SERVER 交互。由于与业务相比,技术层面“稳定”多了,因此作标准化更有价值,更能得到长期收益。但“稳定”是相对的,哪怕单纯在业务层面也存在相对稳定的部分。

好比,你能够想象一下“盛饭”的场景,在大多数状况下其中相对稳定的是什么,不稳定的是什么。想完以后看下面的示例。

相关文章
相关标签/搜索