【分布式系统遨游】分布式计算

引言

随着计算技术的发展,有些应用须要很是巨大的计算能力才能完成,若是采用集中式计算,须要耗费至关长的时间来完成。怎么解决这个问题呢?固然是把这些问题分红多份,在不一样的机器上去解决,众人拾柴火焰高嘛。而分布式计算就是将该应用分解成许多小的部分,分配给多台计算机进行处理。这样能够节约总体计算时间,大大提升计算效率。在分布式中,针对这种状况咱们大概有两种计算模式:MapReduce和Stream,接下来就让咱们来看看它们是何方神圣。注意:本文讲述的两种计算模式是以特定数据类型(分别对应静态数据和动态数据)做为计算维度。而在分布式领域中还有另外两种分布式计算模式,即 Actor 和流水线。它们是以计算过程或处理过程的维度的,不作本文讲述的重点。segmentfault

Map Reduce

相信你们都有据说过Hadoop这个框架,这个框架主要用来解决海量数据的计算问题。那么它是如何作到海量数据的计算呢?你可能会想,既然是海量数据,有这么大的规模,那就让多个进程去处理,最后去汇总一下结果,这样就能够加大马力,提高速度了。
没错,就是这种想法,在分布式领域中咱们称这种叫做MR(Map Reduce)模式。咱们上边分红多个进程处理的想法能够归结成一个词--分而治之,是的,MR就是一个典型的分而治之(简称分治法)的表明。缓存

分治法是什么

分治法就是将一个复杂的、难以直接解决的大问题,分割成一些规模较小的、能够比较简单的或直接求解的子问题,这些子问题之间相互独立且与原问题形式相同,递归地求解这些子问题,而后将子问题的解合并获得原问题的解。好比咱们统计全国人口数量。网络

分治法的使用场景

  1. 问题规模比较大或复杂,且问题能够分解为几个规模较小的、简单的同类型问题进行求解;
  2. 子问题之间相互独立,不包含公共子问题;
  3. 子问题的解能够合并获得原问题的解。

分治法解决问题的步骤

  1. 分解原问题。将原问题分解为若干个规模较小,相互独立,且与原问题形式相同的子问题。
  2. 求解子问题。若子问题规模较小且容易被解决则直接求解,不然递归地求解各个子问题。
  3. 合并解,就是将各个子问题的解合并为原问题的解。

MR的抽象模型

了解了分治法以后,咱们再来看看本段的主角MR,以下图所示,MapReduce 分为 Map 和 Reduce 两个核心阶段,其中 Map 对应“分”, 即把复杂的任务分解为若干个“简单的任务”执行;Reduce 对应着“合”,即对 Map 阶段的结果进行汇总。并发

mr1.png

在第一阶段,也就是 Map 阶段,将大数据计算任务拆分为多个子任务,拆分后的子任务一般具备以下特征: 相对于原始任务来讲,划分后的子任务与原任务是同质的,好比原任务是统计全国人口数,拆分为统计省的人口数子任务时,都是统计人口数;而且,子任务的数据规模和计算规模会小不少。多个子任务之间没有依赖,能够独立运行、并行计算,好比按照省统计人口数,统计河北省的人口数和统计湖南省的人口数之间没有依赖关系,能够独立、并行的统计。
第二阶段,也就是 Reduce 阶段,第一阶段拆分的子任务计算完成后,汇总全部子任务的 计算结果,以获得最终结果。也就是,汇总各个省统计的人口数,获得全国的总人口数。app

上边了解了这么多,那么在 MapReduce 里,各个组件是如何分工完成一个复杂任务的呢?框架

MR的工做原理

为了解答这个问题,我先带你了解一下 MapReduce 的组件结构。分布式

mr2.png

如上图所示,MapReduce 主要包括如下三种组件:函数

  • Master,也就是 MRAppMaster,该模块像一个大总管同样,独掌大权,负责分配任 务,协调任务的运行,并为 Mapper 分配 map() 函数操做、为 Reducer 分配 reduce() 函数操做。
  • Mapper worker,负责 Map 函数功能,即负责执行子任务。
  • Reducer worker,负责 Reduce 函数功能,即负责汇总各个子任务的结果。

基于这三种组件,MapReduce 的工做流程以下所示:oop

mr3.png

程序从 User Program 开始进入 MapReduce 操做流程。其中图中的“step1,step2, ...,step6”表示操做步骤。学习

  • step1:User Program 将任务下发到 MRAppMaster 中。而后MRAppMaster 执行任 务拆分步骤,把 User Program 下发的任务划分红 M 个子任务(M 是用户自定义的数 值)。假设,MapReduce 函数将任务划分红了 5 个,其中 Map 做业有 3 个,Reduce 做 业有 2 个;集群内的 MRAppMaster 以及 Worker 节点都有任务的副本。
  • step2:MRAppMaster 分别为 Mapper 和 Reducer 分配相应的 Map 和 Reduce 做业。 Map 做业的数量就是划分后的子任务数量,也就是 3 个;Reduce 做业是 2 个。
  • step3:被分配了 Map 做业的 Worker,开始读取子任务的输入数据,并从输入数据中抽 取出 <key, value> 键值对,每个键值对都做为参数传递给 map() 函数。
  • step4:map() 函数的输出结果存储在环形缓冲区 kvBuffer 中,这些 Map 结果会被按期 写入本地磁盘中,被存储在 R 个不一样的磁盘区。这里的 R 表示 Reduce 做业的数量,也是 由用户定义的。在这个案例中,R=2。此外,每一个 Map 结果的存储位置都会上报给 MRAppMaster。
  • step5:MRAppMaster 通知 Reducer 它负责的做业在哪个分区,Reducer 远程读取相 应的 Map 结果,即中间键值对。当 Reducer 把它负责的全部中间键值对都读过来后,首 先根据键值对的 key 值对中间键值对进行排序,将相同 key 值的键值对汇集在一块儿,从而 有利于 Reducer 对 Map 结果进行统计。
  • step6:Reducer 遍历排序后的中间键值对,将具备相同 key 值的键值对合并,并将统计 结果做为输出文件存入负责的分区中。

从上述流程能够看出,整个 MapReduce 的工做流程主要能够归纳为 5 个阶段,即: Input(输入)、Splitting(拆分)、Mapping(映射)、Reducing(化简)以及 Final Result(输出)。
全部 MapReduce 操做执行完毕后,MRAppMaster 将 R 个分区的输出文件结果返回给 User Program,用户能够根据实际须要进行操做。好比,一般并不须要合并这 R 个输出文 件,而是将其做为输入交给另外一个 MapReduce 程序处理。

举个例子

咱们来描述一个具体的例子来帮助你们理解,假设咱们如今要统计苏锡常地区第二季度手机订单数量 Top3 的品牌。咱们来看看具体的统计步骤吧。

  1. 任务拆分(Splitting 阶段)。根据地理位置,分别统计苏州、无锡、常州第二季度手机 订单 Top3 品牌,从而将大规模任务划分为 3 个子任务。
  2. 经过循环调用 map() 函数,统计每一个品牌手机的订单数量。其中,key 为手机品牌, value 为手机购买数量(单位:万台)。以下图 Mapping 阶段所示(为简化描述,图中 直接列出了统计结果)。
  3. 与前面讲到的计算流程不一样的是,Mapping 阶段和 Reducing 阶段中间多了一步 Shuffling 操做。Shuffling 阶段主要是读取 Mapping 阶段的结果,并将不一样的结果划 分到不一样的区。在大多数参考文档中,Mapping 和 Reducing 阶段的任务分别定义为映 射以及归约。可是,在映射以后,要对映射后的结果进行排序整合,而后才能执行归约 操做,所以每每将这一排序整合的操做单独放出来,称之为 Shuffling 阶段。
  4. Reducing 阶段,归并同一个品牌的购买次数。
  5. 获得苏锡常地区第二季度 Top3 品牌手机的购买记录。

mr4.png

由上述流程能够看出,Map/Reduce 做业和 map()/reduce() 函数是有区别的:

  • Map 阶段由必定数量的 Map 做业组成,这些 Map 做业是并发任务,能够同时运行, 且操做重复。Map 阶段的功能主要由 map() 函数实现。每一个 Map 做业处理一个子任务 (好比一个城市的手机消费统计),须要调用屡次 map() 函数来处理(由于城市内不一样 的居民倾向于不一样的手机)。
  • Reduce 阶段执行的是汇总任务结果,遍历 Map 阶段的结果从而返回一个综合结果。与 Reduce 阶段相关的是 reduce() 函数,它的输入是一个键(key)和与之对应的一组数 据(values),其功能是将具备相同 key 值的数据进行合并。Reduce 做业处理一个分 区的中间键值对,期间要对每一个不一样的 key 值调用一次 reduce() 函数。在完成 Map 做 业后,每一个分区中会存在多个临时文件;而执行完 Reduce 操做后,一个分区最终只有 一个输出文件。

根据上文咱们知道MR模式的核心思想是分治法,在这种模式下任务完成后整个进程就结束了,并且它并不适合去处理实时任务。实时性任务主要是针对流数据的处理,对处理时延要求很高,一般须要有常驻服务进程,等待数据的随时到来随时处理,以保证低时延。处理流数据任务的计算模式,在分布式领域中叫做 Stream。

流式计算

流式计算是什么

近年来,因为网络监控、传感监测、AR/VR 等实时性应用的兴起,一类须要处理流数据的 业务发展了起来。好比各类直播平台中,咱们须要处理直播产生的音视频数据流等。这种如流水般持续涌现,且须要实时处理的数据,咱们称之为流数据。它有什么特征呢?一、数据如流水般持续、快速地到达;二、海量数据规模,数据量可达到 TB 级甚至 PB 级;三、对实时性要求高,随着时间流逝,数据的价值会大幅下降; 四、数据顺序没法保证,也就是说系统没法控制将要处理的数据元素的顺序。那么,在分布式领域中,对于这种流数据的计算模式就是流计算,也叫作Stream。由于流数据大量、快速、时变的特色,因此它一般被用于处理数据密集型应用。

流式计算的工做原理

由于流式计算强调的是实时性,数据一旦产生就会被当即处理,因此在当一条数据处理完成后会序列化存储到缓存中,而后马上经过网络传输到下一个节点,由下一个节点继续处理,而不是像MapReduce 那样,等到缓存写满才开始处理、传输。为了保证数据的实时性,在流计算中,不会存储任何数据,就像水流同样滚滚向前。那么,它的处理流程是怎么样的呢?使用流计算进行数据处理通常会有三个步骤,参见下图:

str1.png

  • step1:提交流式计算做业。怎么理解呢?一个模式运行的前提你须要有必定的制度,否则流计算系统它不知道怎么去处理数据不就搞笑了么。因此,这一步去作的是给计算系统灌输一个“制度”,其中包括处理节点的个数,数据转发的规则等。另外,流式计算做业是常驻计算服务。
  • step2: 加载流式数据进行计算。流式计算在启动后就一直处于待触发态,等到一旦有数据过来就当即执行计算逻辑去处理。从上图中咱们能够看出,在流计算系统中,有多个流处理节点,流处理节点会对数据进行预约义的处理操做,并在处理完后按照某种规则转发给后续节点继续处理。此外,流计算系统中还存在管理节点,主要负责管理处理节点以及数据的流动规则。
  • step3:实时计算结果。流式计算做业在获得小批量数据的计算结果后,能够马上将结 果数据写入在线 / 批量系统,无需等待总体数据的计算结果,以进一步作到实时计算结果的实时展示。

小结一下,流计算是处理持续到达的数据,它并不会去存储数据,适用于对数据处理有较高实时性要求的场景,好比网络监控,传感检测,AR/VR和视频流等实时应用。

以上咱们分别学习了MapReduce(批处理)和Stream(流式计算)模式,咱们也对它们有了一些了解,虽然这两种计算模式对数据的处理方式不一样,但都是以特定数据类型(分别对应静态数据和动态数据)做为计算维度。

下期预告

【分布式系统遨游】分布式数据存储

关注咱们

欢迎对本系列文章感兴趣的读者订阅咱们的公众号,关注博主下次不迷路~

Nosay