分布式该从何谈起??
前言
现如今做开发,写代码出门和人聊天,动不动就会提起分布式,而且很多使用的框架、中间件都会采用分布式的设计。所以开阔自己的眼界,别做个 API Boy(Girl)。想了想开始试水写点相关的文章,一来梳理一下自己的学习心得,再者编写博客的过程中,也是对知识加强的一种途径。BTW 如果能帮助有些人就再好不过啦~~
作为第一篇文章,先来看看分布式到底是什么。抛去那些抽象的的技术名词,该如何阐述这个概念呢??
注:为了更好地理解分布式的发展过程,默认每个计算机或服务器都是单核、单处理器的。
分布式起源
从第一台计算机开始聊聊
世界上第一台通用计算机是在 1946 年情人节发布的 ENIAC,由于当时硬件水平的限制,就如大家所说的那样,占地面积大,还显得特别笨重,但在那个时候已经做到了每秒可进行 5000 次加法或者 400 次乘法运算,标志着单机模式的开始。
从这方面来看,电脑的出现就是为了计算,其实现如今也不例外,如果有时间可以简单来谈谈计算,试着从莱布尼茨开始说起 哈哈。回归正题,所谓单机模式简单来说是指,所有应用程序和数据均部署在一台电脑或服务器上,由一台设备完成所有的处理。
最近“双十一”,就以电商网站系统为例,删繁就简,只关注以下几个模块,分别是:用户管理、商品管理和订单管理。数据也就包括用户数据、商品数据和订单数据等。如果使用单机模式,那么所有的模块和数据均会部署在同一台计算机上,也就是说数据存储、请求处理均有同一个服务器来完成。这种模式的好处是功能、代码和数据更加集中,便于维护、管理和执行。
单机模式的示意图,如下所示:
Every coin has two sides. 那么单机部署的缺点是什么呢??单个计算机的处理能力取决于 CPU 和内存等,但硬件的发展速度和性能是有限的(可以看看摩尔定律),而且升级硬件的成本也比较高,可以说硬件的性能是单机模式的瓶颈。还有就是如果当前将所有的任务都交给一台服务器,可能会承受较大的负载压力,或者受到攻击挂了的话,所有的服务也就不能正常运行了,这也就将所有鸡蛋放到一个篮子里的风险,也就是单点失效问题。
顺着这个思路往下走,既然单机模式存在性能的瓶颈,也就会导致会存在可用性的问题,有没有更好的解决办法呢?
数据并行
为解决单机模式的问题,并行计算得到了发展,也就是我们常说的 MapReduce,并进一步出现了数据并行模式,也有的人喜欢称之为数据分布式模式。并行计算采用消息共享模式使用多台计算机并行运行或执行多项任务,核心原理是每台服务器上执行相同的程序,将数据进程拆分到不同的服务器上进行计算。
需要注意的是,并行计算强调的是对数据进行拆分,任务程序在每台机器上运行。要达到这个目的,首先要做的是把单机模式中的应用和数据分离,才可能实现对数据的拆分。这里的应用就是执行任务的程序,任务就是提交的请求。还是来看上面的这个例子,运行在服务器上的用户管理、商品管理和订单管理等程序都是应用,用户提交的查询浏览商品、购买商品的请求就是任务。
在单机模式中,应用和数据均在一台计算机或服务器上,要实现数据的并行,必须先将应用和数据分离以便将应用部署到不同的计算机或服务器上;然后,对同类型的数据进行拆分,比如说,不同计算机或服务器上的应用可以到不同的数据库上获取数据执行任务。
这么讲可能比较抽象,来看看图:
第一步,将应用与数据分离,分别部署到不同的服务器上。
第二步,对数据进行拆分,比如把同一类型的数据拆分到两个甚至更多的数据库中,这样应用服务器上的任务就可以针对不同数据并行执行了。
对于电商销售系统,根据商品类型将用户、商品和订单数据拆分到不同的数据库中,部署到不同的服务器上,比如运动鞋服类的数据放在数据库服务器 1 上,电脑数据的数据放在数据库 2。
这种模式的好处是,可以利用多台计算机并行处理多个请求,使得我们可以在相同的时间内完成更多的请求处理,解决了单机模式的计算效率瓶颈问题。但这种模式仍然存在如下几个问题,在实际应用中,我们还需要进行相对应的优化:
- 相同的应用部署到不同的服务器上,当大量用户请求过来时,如何能比较均衡地转发到不同的应用服务器上呢?这也就是我们常说的“负载均衡”的问题,等后期有时间再展开聊聊;
- 当请求量较大时,对数据库的频繁读写操作,会导致数据库的 IO 访问成为瓶颈。这种就可以使用“读写分离”的模式,也就是“主从库”的方式来解决,主数据库负责读写操作,然后再同步数据给从库,从而可以做到读数据库只接收读请求,写数据库只接收写请求,需要注意的是保证数据一致性;
- 当有些数据成为热点数据时,会导致数据库访问频繁,压力增大。解决这个问题的方法是引入缓存机制,将热点数据加载到缓存中,一方面可以减轻数据库的压力,另一方面也可以提高查询效率。
由此我们可以看出,数据并行模式实现了多请求并行处理,但如果单个请求特别复杂,比如说需要几个小时甚至几天的时候,这种模式的整体计算效率还是不够高。其主要问题是:对提升单个任务的执行性能及降低时延无效。
任务并行
既然数据并行是存在一定缺陷的,我们就可以想是不是可以提高单个任务的执行性能,或者缩短单个任务的执行时间呢?也就出现了任务并行的模式,有的人可能喜欢称之为“任务分布式”,都是一个概念。
任务并行指的是,将单个复杂的任务拆分为多个子任务,从而使得子任务可以在不同的计算机并行执行。
我们仍以电商销售系统为例,任务并行首先是对应用进行拆分,比如按照领域模型将用户管理、商品管理、订单管理拆分成多个子系统分别运行在不同的计算机或服务器上。简单来说就是,原本包括用户管理、商品管理和订单管理的一个复杂任务,被拆分成多个子任务在不同的服务器上执行。
可以看出,任务并行模式完成一项复杂任务主要有两个核心步骤:首先将单任务拆分成多个子任务,然后让多个子任务并行执行。我们可以这样类比,任务拆分对应于部门领导,不同子系统对应不同的开发人员,不同子程序执行不同任务就像不同的程序员使用不同的技术栈一样,并且运行子系统或者子任务的计算机又可以组成一个服务。
在这种模式中,由于多个子任务可以在多台服务器上运行,因此通过将同一任务待处理的数据分散到多个服务器上,在这些服务器上同事进行处理,就可以加快任务执行的速度。因为,只要一个复杂任务拆分出的任意子任务执行时间变短了,那么这个任务整体的执行时间也就相对而言变短咯。
当然,任务分布式也存在一定的缺点,它在提供了更好的性能、扩展性、可维护性的同时,也带来了设计上的复杂性问题。毕竟对一个大型的复杂业务进行拆分并不是一件轻松的事情。从长远收益来看,这个短期设计上的阵痛是值得的。我们在平时也要注意多积累,有些技术可能仅仅是自己感兴趣,但不要因为短期内或公司的业务用不上就放弃不去学习,要有长远目标,慢慢多学一点点,回头来看会有不一样的感悟噢~~
分布式是什么??
看到这里,有些人就可能会觉得,啰里八嗦讲了一堆,诶 分布式到底是什么呢?
用大白话说来说分布式就是,将相同或相关的程序运行在多台服务器上,从而实现特定目标的一种计算方式。
从这个角度来看,数据并行、任务并行其实都可以算作是分布式的一种形态。从这些计算方式的演变中不难看出,产生分布式的最主要原因是,数据量的暴增,如何更有效地追求高性能、可用性以及可扩展性。。
总结
这篇博客,简单聊了分布式的起源,从最初的单机模式到数据并行,再到任务并行。起初我是想从 GFS 和 MapReduce 的角度来阐述,但脱离业务,从数据出发可能会让不懂大数据的同学来说有点抽象,分布式文件系统和分布式计算引擎等后期有时间再拎出来单独唠唠(开始挖坑叻。。。)
单机模式指的是,所有业务和数据均部署到同一台机器上。这种模式的好处是功能、代码和数据集中,便于维护、管理和执行,但计算效率是瓶颈。也就是说单机模式性能受限,也存在单点失效的问题。
数据并行(也叫作数据分布式)模式指的是,对数据进行拆分,利用多台计算机并行执行多个相同任务,通过在相同的时间内完成多个相同任务,从而缩短所有任务的总体执行时间,但对提升单个任务的执行性能及降低时延无效。
任务并行(也叫作任务分布式)模式指的是,单任务按照执行流程,拆分成多个子任务,多个子任务分别并行执行,只要一个复杂任务中的任意子任务的执行时间变短了,那么这个业务的整体执行时间也就变短了。该模式在提高性能、扩展性、可维护性等的同时,也带来了设计上的复杂性问题,比如复杂任务的拆分。
在数据并行和任务并行这两个模式的使用上,用户通常会比较疑惑,到底是采用数据并行还是任务并行呢?一个简单的原则就是:任务执行时间短,数据规模大、类型相同且无依赖,则可采用数据并行;如果任务复杂、执行时间长,且任务可拆分为多个子任务,则考虑任务并行。在实际业务中,通常是这两种模式并用。