并且向每个空闲工作器分配映射 任务或者精简任务。存在Μ个映射任务(每个输入片段有一个映射任务)。向映射任务分 配的工作器使用映射器W对输入执行映射操作W产生例如被划分成R个集合的中间结果。 当中间结果划分成R个集合时,存在R个精简任务待分配。向精简任务分配的工作器使用 精简器W对中间值执行精简操作W产生输出。一旦完成了所有映射任务和所有精简任务, 主控就向运用映射精简库20化的用户程序或者库返回。作为结果,实施映射精简操作为跨 越处理设备群集的并行操作集合。
[0093] 对于先使用关联交换操作来组合具有给定键的所有值的精简器,可W指定单独用 户定义组合器函数W在映射阶段期间执行对与给定键相关联的值的部分组合。每个映射工 作器可W保持已经从映射器发出的键/值对的高速缓存,并且使用组合器函数W在向混洗 阶段发送组合的键/值对之前尽可能多地进行本地组合。精简器可W通过组合来自不同映 射工作器的值来完成组合步骤。
[0094] 作为默认,混洗阶段可W向任意地、但是确定性地选择的精简工作器机器发送每 个键和值组,其中运一选择确定哪个输出文件碎片将保持该键的结果。备选地,可W指定用 户定义的碎片器函数,该碎片器函数选择哪个精简工作器机器应当接收用于给定键的组。 用户定义的碎片器可W用来辅助负荷平衡。用户定义的碎片器也可W用来将输出键分类 到精简"桶"中,其中第i个精简工作器的所有键被排序在第i+ 1个精简工作器的所有键之 前。与每个精简工作器按照词典顺序处理键的事实联系,运一种碎片器可W用来产生分类 输出。
[0095] 流水线库202c提供支持数据并行流水线的函数和类,并且特别地提供包括映射 精简操作的链或者有向非循环图形的流水线。流水线库202c可W帮助减轻实施映射精简 操作的链的负担中的一些负担。一般而言,许多现实世界计算需要映射精简级的链。尽管 一些逻辑计算可W被表达为映射精简操作,但是其它逻辑计算需要映射精简操作的序列或 者图形。随着逻辑计算的复杂性增长,将计算映射到映射精简操作的物理序列的挑战增加。 一般将更高级概念(比如"对出现次数计数"或者"按照键接合表")手工编译成更低级映 射精简操作。此外,用户可W承担编写驱动器程序W在恰当序列中援引映射精简操作并且 管理对保持数据的中间文件的创建和删除的附加负担。
[0096] 流水线库202c可W回避或者减少产生设及到多个映射精简操作的数据并行流水 线的一些难度W及针对开发者产生附加协调代码W在运样的数据并行流水线中将单独映 射精简级链接在一起的需要。流水线库202c也可W回避或者减少用于管理对在流水线级 之间的中间结果的创建和W后删除的附加工作。作为结果,流水线库202c可W帮助防止逻 辑计算本身变成隐藏于所有低级协调细节之中,由此使新开发者容易理解计算。另外,利用 流水线库202c可W帮助防止将流水线划分成特定级变成向代码"烤入化akein)"并且如 果逻辑计算需要演变则W后难W改变。
[0097] -般而言,应用软件202a可W运用库20化或者库202c中的一个或者两个库。应 用开发者可W开发应用软件,该应用软件运用映射精简库20化W执行被制定为映射精简 操作的计算。
[0098] 备选地或者附加地,应用开发者可W在开发包括多个映射精简操作的数据并行流 水线时运用流水线库202c。如下文进一步讨论的那样,流水线库202c可W允许开发者使用 其中实施流水线库202c的本机编程语言W更自然方式对计算编码,而未考虑在映射精简 操作方面设计逻辑计算或者构建操作的有序图形。流水线库202c可W在执行之前在多个 映射精简操作方面制定逻辑计算,并且继而通过实施映射精简操作本身或者与映射精简库 20化对接W实施映射精简操作来执行计算。
[0099] 图3是图示了可W用来实施流水线库200c的流水线库300的示例的框图。流水 线库300包括一个或者多个并行数据汇集类302、一个或者多个并行操作304、评价器306、 优化器308和执行器310。一般而言,并行数据汇集类302用来实例化并行数据对象,运些 并行数据对象保持数据汇集,并且并行操作304用来对由并行数据对象保持的数据执行并 行操作。可W组成并行操作304W实施数据并行计算和整个流水线或者甚至多个流水线, 可W使用并行汇集类302和并行操作304来实施并行操作304。
[0100] 并行数据汇集类302和并行操作304呈现对许多不同数据表示和对不同执行策略 的简单高级统一抽象。并行数据汇集类302抽象出如何对数据进行表示的细节,运些细节 包括是否将数据表示为存储器中的数据结构、一个或者多个文件或者外部存储服务。类似 地,并行操作304抽象出它们的实现策略,比如是否将操作实施为映射精简库20化的本地、 依次循环、远程并行援引、实施为对数据库的查询或者实施为流计算。
[0101] 评价器306延缓对并行操作的评价而不是在执行数据并行流水线时随着遍历并 行操作而评价它们。取而代之,评价器306构造包含操作及其变元的内部执行计划数据流 图形。一旦构造了用于整个逻辑计算的执行计划数据流图形,优化器308例如通过应用将 并行操作的链一起融合或者组合成更小数目的组合操作的图形变换来修正执行计划。修 正的执行计划可W包括广义映射精简操作,该广义映射精简操作包括多个并行映射操作和 多个并行精简操作(例如,下文进一步描述的MapShuffleCombineRe化ce操作)、但是可 W用单个映射函数和单个精简函数转译成单个映射精简操作,该单个映射函数用于实施多 个映射操作,该单个精简函数用于实施多个精简操作。执行器310使用下层原语(例如, MapRe化ce操作)来执行修正的操作。当运行执行计划时,执行器310可W至少部分基于处 理的数据的大小来选择使用哪个策略W实施每个操作(例如,本地依次循环比对远程并行 MapRe化ce)。执行器310也可W将远程计算置于它们对其操作的数据附近,并且可W并行 执行独立操作。执行器310也可W管理对计算内所需任何中间文件的创建和清理。
[0102] 可W用多种编程语言中的任何编程语言实施流水线库300。下文描述用Java(R) 编程语言的一个实现方式的方面的示例。
[0103] 流水线库300提供被称为PCollection<T>的并行数据汇集类,该并行数据汇集 类是T类型的元素的不可变包。PCollection可W具有定义好的顺序(称为序列),或者 元素可W是无序的(称为汇集)。汇集由于它们更少被约束而可W比序列更高效地生成 和处理。可W通过按照若干可能格式中的一种格式读取文件来创建PCollection<T〉。例 如,可W读取文本文件作为PCollectiorKString〉,并且可W在如何将每个二进制记录解 码成T类型的对象的规范给定时读取面向二进制记录的文件作为PCollection<T〉。当使 用Java(R)来实施流水线库300时,也可W根据存储器中的化va(R)Collection<T>创建 PCollection<T>〇
[0104] 可W读入由多个文件碎片代表的数据集作为单个逻辑PCollection。例如:
[010 引 PCollection<St;ring〉lines=
[010引 readTextFileCollection广/gfs/data/shakes/hamlet.txt");
[0107] PCollection<DocInfo〉docInfos=
[0108] readRecordFileCollection("/gfs/webdocinfo/part-*",recordsOf值ocinfo. class));
[0109] 在运一示例中,recordsOf(…)指定其中将Docin化实例编码为二进制记录 的特定方式。其它预定义编码指定符可W包括用于UTF-8-编码文本的stringsO、用 于32位整数的可变长度编码的intsO和用于根据对分量的编码而推导的对的编码的 pairsOf(el,e2)。一些实现方式可W允许用户指定他们自己的定制编码。
[0110] 第二并行数据汇集类302是PT油le<K,V〉,该并行数据汇集类代表具有类型K的键 和类型V的值的(不可变)多映射。PT油le<K,V〉可W仅为对的无序包。并行操作304中 的一些并行操作可W仅适用于对的PCollection,并且在化va(R)中,PT油le<K,V〉可W被 实施为PCollection皆air<K,V〉〉的子类W捕获运一抽象。在另一语言中,ΡΤ油le<K,V〉可W被定义为PCollection皆air<K,V〉〉的类型同义词。
[01U] 并行数据对象(比如PCollection)可W被实施为其中实施库300的本机语言的 第一类对象。当是运种情况时,对象可W如同在本机语言中的其它对象那样可操控。例 如,PCollection可W能够向语言中的常规方法中传递和从运些方法返回,并且可W能够 存储于语言的其它数据结构中(但是一些实现方式可能防止PCollection存储于其它 PCollection中)。本机语言的常规控制流程构造也可W能够用来定义设及到对象的计算, 运些对象包括函数、条件句和循环。例如,如果化va(R)是本机语言,则:
[0112]
[011引
[0114] 实施并行数据对象作为库300的本机语言中的第一类对象可W简化使用库的程 序开发,因为开发者可W按照他或者她将使用其它对象的方式相同的方式使用并行数据对 象。
[0115] 除了并行数据汇集类之外,流水线库300也可W包括单个数据汇集类 P化ject<T〉,该数据汇集类用于支持在执行流水线期间检查PCollection的内容的能力。 与保持多个元素的PCollection对照,P化ject<T>是用于类型T的单个对象(例如,类型T 的单个本机对象(例如,Java(R)对象))的容器,并且设计K)bject的任何相关联的方法 W对单个元素操作。如同PCollection,可W延缓或者具体化(如下文进一步描述的那样) P化ject,从而允许计算它们作为流水线中的延缓的操作的结果。一旦运行流水线,则可W 使用getValueO来提取现在具体化的K)bject的内容。
[0116] 例如,在使用Java(R)的一个实现方式中,asSequentialCollection〇操作可 W应用于PCollection<T>W产生P0bject<Collection<T〉〉,一旦流水线运行,可W检查 P0bject<Collection<T〉>W读出计算的PCollection的所有元素作为常规Java(R)存储器 中的Collection:
[0117]
[0118] 作为另一示例,对Τ向PCollection<T>和组合函数应用的combine0操作(下文 描述)产生代表完全组合结果的K)bject<T〉。可W运样计算全局求和W及最大值。
[0119]P化ject的内容也可W能够例如使用由流水线库300提供的operate0原语在流 水线的执行内被检查。operateO原语取得FObject的列表和变元化erate化(该变元定 义将对每个K)bject执行的操作),并且返回K)bject的列表。当被评价时,operate0提 取现在具体化的变元TObject的内容并且向变元化erate化中传递它们。化erate化返回 本机对象(比如化va(R)对象)的列表,并且operate0在作为结果而返回的FObject内 卷绕运些本机对象。使用运一原语,可W在流水线内嵌入并且按照延缓方式执行任意计算。 换言之,可W在流水线中包括对包含多个元素的PCollection操作的除了ParallelDo操作 (下文描述)之外的操作。例如,考虑嵌入对读取和写入文件的外部服务的调用:
[0120]
[012。 运一示例使用用于在PCollection与包含文件名的K)bject之间转换的操作。应 用于PCollection和文件格式选择的viewAsFileO产生所选格式的如下临时碎片文件的 名称的FObject<St;ring〉,可W在执行流水线期间在该碎片文件中发现PCollection的内 容。文件读取操作(比如readRecordFileCollectionO)可W被超载W允许读取名称包含 于FObject中的文件。
[012引按照很相同的方式,也可W通过向parallelDoQ中传递Wbject的内容作为副输 入来在Do化(下文描述)内检查它们。通常,Do化对PCollection的每个元素执行操作, 并且仅接收PCollection作为输入。在一些情况下,对每个PCollection的操作可W设及 到在FObject中存储的值或者其它数据。在运一情况下,Do化可W如常接收PCollection 作为输入并且接收K)bject作为副输入。当运行流水线并且最终评价parallelDoO操作 时,提取并且向用户的Do化提供任何现在具体化的Wbject副输入的内容,并且继而对输 入PCollection的每个元素援引Do化W使用来自FObject的数据对元素执行定义的操作。 例如:
[0123]
[0124] 如上文描述的那样,对并行数据对象(比如PCollection)援引数据并行操作 304。流水线库300定义一些原语数据并行操作,其中在运些原语方面实施其它操作。数据 并行原语之一是parallelDo 0,该数据并行原语支持对输入PCollection<T>的逐个元素 (elementwise)计算W产生新输出PCollection<S〉。运一操作取得函数式对象Dop·]!。, S〉 作为它的主变元,该对象定义如何将输入PCollection<T>中的每个值映射到将在输出 PCollection。〉中出现的零个或者更多个值中。运一操作也取得将作为结果而产生的 PCollection或者PT油le种类的指示。例如:
[0125]
[0126] 在运一代码中,collectionOf (strings 0)指定parallelDo 0操作应当产生无序 PCollection,该PCollection的String元素应当使用UTF-8来编码。其它选项可W包括 用于有序PCollection的sequenceOf(elemEncoding)和用于ΡΤ油le的t油leOf化巧linco ding,valueEncoding)。emitFN是向用户的process!;···)方法传递的回调函数,该回调函数 应当针对应当向输出PCollection添加的每个ou1:Elem拨引emitF·]!.emit(ou1:Elem)。可W 包括Do化的子类(比如Map化(实施映射)和Filter化(实施过滤器))W在一些情况下 提供更简单的接口。
[0127] 操作parallelDoQ可W用来表达MapRe化ce操作的映射和精简部分二者。库300 也可W包括parallelDo0的如下版本,该版本允许根据输入PCollection的单次遍历同时 产生多个输出PCollection。
[0128] 如果可W远程分布并且并行运行Do化函数,则可W防止Do化函数访问封包程序 (enclosingprogram)的任何全局可变状态。Do化对象可W能够维持本地实例可变状态, 但是可W存在并行操作而没有共享状态的多个DoFn复制件。
[0129] 第二原语grou地化巧0将类型PT油le<K,V〉的多映射(该多映射可W具有许多 键/值对,运些键/值对具有相同键)转换成类型PT油le<K,Collection^〉〉的单映射,其 中每个键映射到具有该键的所有值的无序汇集。例如,下文计算如下表,该表将U化映射到 文档汇集,运些文档链接到运些U化:
[0130]
[0131] 操作grou地化eyO对应于MapRe化ce的混洗步骤。也可W存在如下变体,该变体 允许指定用于每个键的值的汇集的分类顺序。
[0132] 第Ξ原语combineValuesQ取得输入PT油le<K,Collection^〉〉和对V的相关联 的组合函数,并且返回PT油le<K,V〉,其中值的每个输入汇集已经被组合成单个输出值。例 如:
[0133]
[0135] 操作combineValuesQ在语义上是parallelDoQ的特殊情况,但是组合函数的关 联性允许通过组合MapRe化ce组合器(作为每个映射器的部分来运行)和MapRe化ce精简 器(用于完成组合)来实施操作,运可W比在精简器中完成所有组合更高效。
[0136] 第四原语flattenO取得PCollection<T>的列表并且返回包含输入PCollection 的所有元素的单个PCollection<T〉。操作flattenO可W未实际复制输入,而是仅如同输 入是一个逻辑PCollection来看待输入。
[0137] 流水线通常W向外部储存器写入最终所得PCollection的操作而结束。例如:
[0138]wordCounts.writeToRecordFileTable(Vgfs/data/shakes/hamlet-counts. records");
[0139] 流水线库300可W包括对在上文描述的原语方面推导的PCollection的多个其它 操作。运些推导的操作可W与用户可W编写的帮助器函数相同。例如,countO操作取得 PCollection。〉并且返回PT油le<T,Integer〉,该PT油le<T,Integer〉将输入PCollection 的每个相异元素映射到元素出现的次数。可W使用与用来计算上述wordCounts的模式相 同的模式在parallelDo0、g;rou地化巧0和combineValues