这里先来聊聊什么是分布式。
与其直接用些抽象、晦涩的技术名词去给分布式下一个定义,还不如从理解分布式的发展驱动因素开始,我们一起去探寻它的本质,自然而然地也就清楚它的定义了。
这里将介绍分布式的起源,是如何从单台计算机发展到分布式的,进而深入理解什么是分布式。为了更好地理解这个演进过程,我将不考虑多核、多处理器的情况,假定每台计算机都是单核、单处理器的。
分布式起源
单兵模式:单机模式
1946年情人节发布的ENIAC是世界上的第一台通用计算机,它占地170平米重达30吨,每秒可进行5000次加法或者400次乘法运算,标志着单机模式的开始。
所谓单机模式是指,所有应用程序和数据均部署在一台电脑或服务器上,由一台计算机完成所有的处理。
以铁路售票系统为例,铁路售票系统包括用户管理、火车票管理和订单管理等模块,数据包括用户数据、火车票数据和订单数据等,如果使用单机模式,那么所有的模块和数据均会部署在同一台计算机上,也就是说数据存储、请求处理均由该计算机完成。这种模式的好处是功能、代码和数据集中,便于维护、管理和执行。
单机模式的示意图,如下所示:
这里需要注意的是,本文的所有示意图中,紫色虚线表示在一台计算机内。
事物均有两面性,我们再来看看单机模式的缺点。单个计算机的处理能力取决于CPU和内存等,但硬件的发展速度和性能是有限的,而且升级硬件的性价比也是我们要考虑的,由此决定了CPU和内存等硬件的性能将成为单机模式的瓶颈。
你有没有发现,单机模式和单兵作战模式非常相似,单台计算机能力再强,就好比特种兵以一敌百,但终归能力有限。此外,将所有任务都交给一台计算机,也会存在将所有鸡蛋放到一个篮子里的风险,也就是单点失效问题。
归纳一下,单机模式的主要问题是:性能受限、存在单点失效问题。
游击队模式:数据并行或数据分布式
“游击队模式”这一概念是由卡尔·施米特提出的,在他的论文《游击队理论》中有所阐述。这篇论文最初来源于施米特在1962年所做的两次学术演讲,并在1963年正式发表。
既然单机模式存在性能和可用性的问题。那么,有没有什么更好的计算模式呢?答案是肯定的。
为解决单机模式的问题,并行计算得到了发展,进而出现了数据并行(也叫作数据分布式)模式。并行计算采用消息共享模式使用多台计算机并行运行或执行多项任务,核心原理是每台计算机上执行相同的程序,将数据进行拆分放到不同的计算机上进行计算。
请注意,并行计算强调的是对数据进行拆分,任务程序在每台机器上运行。要达到这个目的,我们必须首先把单机模式中的应用和数据分离,才可能实现对数据的拆分。这里的应用就是执行任务的程序,任务就是提交的请求。以铁路售票系统为例,运行在服务器上的用户管理、火车票管理和订单管理等程序就是应用,用户提交的查询火车票、购买火车票的请求就是任务。
在单机模式中,应用和数据均在一台计算机或服务器上,要实现数据的并行,首先必须将应用和数据分离以便将应用部署到不同的计算机或服务器上;然后,对同类型的数据进行拆分,比方说,不同计算机或服务器上的应用可以到不同的数据库上获取数据执行任务。
以铁路售票系统的数据并行为例,主要包括两个步骤,如下所示:
第一步,将应用与数据分离,分别部署到不同的服务器上:
第二步,对数据进行拆分,比如把同一类型的数据拆分到两个甚至更多的数据库中,这样应用服务器上的任务就可以针对不同数据并行执行了。
对于铁路售票系统来说,根据线路将用户、火车票和订单数据拆分到不同的数据库中,部署到不同的服务器上,比如京藏线的数据放在数据库服务器1上的数据库中,沪深线的数据放在数据库服务器2上的数据库中。
需要注意的是,为了更好地理解这个数据拆分的过程,我在这里选择拆分数据库的方式进行讲解。由于数据库服务器本身的并发特性,因此你也可以根据你的业务情况进行选择,比方说所有业务服务器共用一个数据库服务器,而不一定真的需要去进行数据库拆分。
可以看出,在数据并行或数据分布式模式中,每台计算机都是全量地从头到尾一条龙地执行一个程序,就像一个全能的铁道游击队战士。所以,也可以将这种模式形象地理解成游击队模式,就和铁道游击队插曲的歌词有点类似:“我们扒飞车那个搞机枪,撞火车那个炸桥梁……”
这种模式的好处是,可以利用多台计算机并行处理多个请求,使得我们可以在相同的时间内完成更多的请求处理,解决了单机模式的计算效率瓶颈问题。但这种模式仍然存在如下几个问题,在实际应用中,我们需要对其进行相应的优化:
- 相同的应用部署到不同的服务器上,当大量用户请求过来时,如何能比较均衡地转发到不同的应用服务器上呢?解决这个问题的方法是设计一个负载均衡器,这在“分布式高可靠”模块会介绍负载均衡的相关原理。
- 当请求量较大时,对数据库的频繁读写操作,使得数据库的IO访问成为瓶颈。解决这个问题的方式是读写分离,读数据库只接收读请求,写数据库只接收写请求,当然读写数据库之间要进行数据同步,以保证数据一致性。
- 当有些数据成为热点数据时,会导致数据库访问频繁,压力增大。解决这个问题的方法是引入缓存机制,将热点数据加载到缓存中,一方面可以减轻数据库的压力,另一方面也可以提升查询效率。
从上面介绍可以看出,数据并行模式实现了多请求并行处理,但如果单个请求特别复杂,比方说需要几天甚至一周时间的时候,数据并行模式的整体计算效率还是不够高。
由此可见,数据并行模式的主要问题是:对提升单个任务的执行性能及降低时延无效。
集团军模式:任务并行或任务分布式
那么,有没有办法可以提高单个任务的执行性能,或者缩短单个任务的执行时间呢?答案是肯定的。任务并行(也叫作任务分布式)就是为解决这个问题而生的。那什么是任务并行呢?
任务并行指的是,将单个复杂的任务拆分为多个子任务,从而使得多个子任务可以在不同的计算机上并行执行。
我们仍以铁路售票系统为例,任务并行首先是对应用进行拆分,比如按照领域模型将用户管理、火车票管理、订单管理拆分成多个子系统分别运行在不同的计算机或服务器上。换句话说,原本包括用户管理、火车票管理和订单管理的一个复杂任务,被拆分成了多个子任务在不同计算机或服务器上执行,如下图所示:
可以看出,任务并行模式完成一项复杂任务主要有两个核心步骤:首先将单任务拆分成多个子任务,然后让多个子任务并行执行。这种模式和集团军模式很像,任务拆分者对应领导者,不同子系统对应不同兵种,不同子程序执行不同任务就像不同的兵种执行不同的命令一样,并且运行相同子系统或子任务的计算机又可以组成一个兵团。
在集团军模式中,由于多个子任务可以在多台计算机上运行,因此通过将同一任务待处理的数据分散到多个计算机上,在这些计算机上同时进行处理,就可以加快任务执行的速度。因为,只要一个复杂任务拆分出的任意子任务执行时间变短了,那么这个任务的整体执行时间就变短了。
当然,nothing is perfect。集团军模式在提供了更好的性能、扩展性、可维护性的同时,也带来了设计上的复杂性问题,毕竟对一个大型业务的拆分也是一个难题。不过,对于大型业务来讲,从长远收益来看,这个短期的设计阵痛是值得的。这也是许多大型互联网公司、高性能计算机构等竞相对业务进行拆分以及重构的一个重要原因。
分布式是什么?
讲了半天,那到底什么是分布式呢?
总结一下,分布式其实就是将相同或相关的程序运行在多台计算机上,从而实现特定目标的一种计算方式。
从这个定义来看,数据并行、任务并行其实都可以算作是分布式的一种形态。从这些计算方式的演变中不难看出,产生分布式的最主要驱动力量,是我们对于性能、可用性及可扩展性的不懈追求。
总结
在文章里分享了分布式的起源,即从单机模式到数据并行(也叫作数据分布式)模式,再到任务并行(也叫作任务分布式)模式。
单机模式指的是,所有业务和数据均部署到同一台机器上。这种模式的好处是功能、代码和数据集中,便于维护、管理和执行,但计算效率是瓶颈。也就是说单机模式性能受限,也存在单点失效的问题。
数据并行(也叫作数据分布式)模式指的是,对数据进行拆分,利用多台计算机并行执行多个相同任务,通过在相同的时间内完成多个相同任务,从而缩短所有任务的总体执行时间,但对提升单个任务的执行性能及降低时延无效。
任务并行(也叫作任务分布式)模式指的是,单任务按照执行流程,拆分成多个子任务,多个子任务分别并行执行,只要一个复杂任务中的任意子任务的执行时间变短了,那么这个业务的整体执行时间也就变短了。该模式在提高性能、扩展性、可维护性等的同时,也带来了设计上的复杂性问题,比如复杂任务的拆分。
在数据并行和任务并行这两个模式的使用上,用户通常会比较疑惑,到底是采用数据并行还是任务并行呢?一个简单的原则就是:任务执行时间短,数据规模大、类型相同且无依赖,则可采用数据并行;如果任务复杂、执行时间长,且任务可拆分为多个子任务,则考虑任务并行。在实际业务中,通常是这两种模式并用。
课后思考
你觉得分布式与传统的并行计算的区别是什么?
分布式计算与传统的并行计算在设计理念、应用目标和资源管理上存在显著差异。- 设计理念:
- 传统并行计算通常指的是多处理器或多核处理器在同一时间内执行多个计算任务,这些处理单元通常共享内存和资源,强调的是计算性能的提升。
- 分布式计算则涉及多个独立的计算机节点协作完成一项任务,这些节点可能分布在不同的地理位置,它们之间通过网络进行通信,每个节点拥有自己的内存和资源。
- 应用目标:
- 并行计算主要应用于需要大量计算的场景,如科学模拟和复杂数学问题的求解,其目标是提高单个任务的计算速度。
- 分布式计算更多用于处理大量的独立任务,例如大规模的数据处理和分析,其优势在于能够同时处理许多小任务,从而加快整体的处理速度。
- 资源管理:
- 在并行计算中,由于资源共享,资源管理相对简单,因为所有处理单元都在同一系统中协同工作。
- 分布式计算中的资源管理更为复杂,因为需要协调和管理分散在不同地点的计算资源,并确保它们能够高效地共同完成任务。
微服务与任务并行模式的区别是什么?
结论:微服务拆分后,天然支持任务并行模式。各子任务就是单独被拆分好的微服务,以供并行调用执行。
微服务架构和任务并行模式是两种不同的概念,它们在目的、实现方式和应用场景上有所区别。以下是具体分析:
- 目的:
- 微服务架构的目的是通过服务的解耦和细粒度的组件化来提高系统的灵活性、可维护性和可扩展性。它允许开发团队独立地开发、部署和扩展每个服务,从而加快开发速度并减少系统间的依赖。
- 任务并行模式则是为了提高计算效率,特别是在处理大量数据或执行复杂计算时,通过同时执行多个任务来缩短整体的处理时间。
- 实现方式:
- 微服务架构通常涉及到将应用程序分解为一系列小型、独立的服务,每个服务负责一个功能模块,并且可以独立运行和扩展。这些服务之间通过网络通信,通常使用HTTP RESTful API或轻量级的通信机制(如RPC)进行交互。
- 任务并行模式则可以通过多线程、多进程或分布式计算来实现。在微服务架构中,任务并行可以作为一个优化手段,例如通过并行调用不同的服务来提高系统性能。
- 应用场景:
- 微服务架构适用于大型复杂的应用程序,它可以使系统更加模块化,便于团队协作和持续集成/持续部署(CI/CD)。
- 任务并行模式则适用于需要高性能计算的场景,如科学模拟、大数据分析等。
总的来说,微服务架构专注于通过服务分解来提高系统的模块化和可维护性,而任务并行关注于提高计算效率和加速任务执行。两者虽然在某些情况下可以相互配合,但它们的核心目标和实现方式是不同的。