Spark-在工作集上进行集群计算

来源:互联网 发布:大韩帝国知乎 编辑:程序博客网 时间:2024/06/02 02:23

pdf版本下载地址:http://download.csdn.net/detail/rongyongfeikai2/9752562

Spark-在工作集上进行集群计算

MateiZaharia, Mosharaf Chowdhury,Michael J. Franklin, Scott Shenker, Ion Stoica

加利福利亚伯克利大学

摘要

         MapReduce以及它的变体已经在集群上成功实现了大规模数据密集型程序。然而,这些系统中的大多数都是建立在非循环数据流模型之上的,而这个模型也许对于其他一些应用而言并不适用。本文关注如下类型的应用:那些期望在并行操作中重复使用数据集的应用。这包括一些迭代机器学习算法,以及交互式数据分析工具。我们建立了一个叫做Spark的框架用于支持这些应用,与此同时框架也保留了MapReduce的可扩展性和容错性的特征。为了达到这个目标,Spark提出了一种叫做弹性分布式数据集(RDD)的抽象概念。RDD是一个只读的分布在集群各个节点上的数据集合,如果有分区失效的话RDD可以被重建。Spark在迭代式的机器学习任务上与Hadoop相比性能提升了10倍,也可以交互式的亚秒级查询39G的数据。

1.   简介

一种新的集群计算模型变得流行起来,即在由非可靠主机建立的集群上进行并行数据计算,并自动提供任务调度、故障恢复以及负载均衡。MapReduce倡导了这种模型,而类似Dryad或者Map-Reduce-Merge的系统推广了对于这种类型的数据流的支持。这些系统提供给用户一种编程模型,即创建非循环数据流图并将数据传输给一组计算节点,并实现了可扩展和自动故障恢复。这允许底层系统管理任务调度以及进行故障恢复,而无需用户的参与。

虽然这种数据流编程模型对于大多数应用而言是非常有效的,但也有一些应用是无法使用非循环数据流高效的实现的。本文,我们关注如下类型的应用:希望在并行操作中重复使用数据集的应用。下面有两个例子,即Hadoop用户指出的MapReduce效率不高的例子:

  • 迭代任务:许多机器学习算法在同一份数据集上迭代式的进行计算,用于进行参数调优(如:梯度下降)。虽然每一轮迭代可以被表达为一个MapReduce任务,但是每一个任务都需要从硬盘上重新加载数据,造成了明显的性能影响。
  • 交互分析:Hadoop经常被用于在大的数据集上进行专门的查询分析,使用一些SQL接口如Pig或者Hive。理想状态下,用户应该将数据集加载到内存中,并且进行反复的查询。然而,使用Hadoop,查询会有明显的延迟(数十秒)因为它们作为独立的MapReduce任务执行,并从硬盘上加载数据。

本文提出了一种新型集群计算模型叫做Spark,支持上述工作集应用,并提供与MapReduce相同的可扩展性和容错性。

Spark中最主要的抽象叫做弹性分布式数据集(RDD),代表了分区分布在一系列机器节点上的对象集合,如果一个分区丢失了可以被重建。用户可以跨节点的缓存RDD到内存里,并且在多个类似于MapReduce的并行操作中复用它。RDD通过血统(lineage)这个概念实现容错性:如果RDD中的一个分区丢失了,RDD是知道它自己是如何从其他RDD转变而来的,所以有能力重新生成这个分区。虽然RDD并不是一个一般的共享内存的概念,但是它们在表达能力这方面,与可扩展性以及健壮性上这方面上,取得了一个最佳的平衡。并且我们发现RDD适用于各种应用程序。

Spark是用scala实现的,这是一种运行在Java虚拟机里的静态类型的高级语言,它和DryadLINQ一样有函数式编程的接口。另外Spark可以使用一种修改过的Scala解释器交互式的进行使用,它可以允许用户定义RDD、方法、变量和类,并且在一个集群中并行的操作它们。我们相信Spark是第一个支持用这种高效、多用途的编程语言交互式的访问集群当中的大量数据集的系统。

本文组织结构如下。第二节介绍了Spark的编程模型以及RDD。第三节展示一些示例任务。第四节介绍我们的实现方式,包括集成Scala语言以及它的解释器。第五小节展示最近的结果。我们在第六小节介绍相关的一些工作,并且通过第七小节的讨论结束全文。

2.编程模型

为了使用Spark,开发者需要编写driver程序,实现应用程序高级控制流以及启动各种并行操作。Spark提供了两种主要的并行编程的概念:弹性分布式数据集,以及在这些数据集上的并发操作(通过应用在这些数据集上的方法调用触发)。另外,Spark还提供两种限制类型的共享变量,可以被运行在集群上的方法使用,这个我们稍后解释。

2.1弹性分布式数据集

弹性分布式数据集(RDD)是一种只读的分区分布在多个节点上的,当有分区失效时可以被重建的对象集合。RDD中的元素并不需要实际的被存储起来,取而代之的是,RDD拥有足够的如何从初始数据中计算出来自己的信息。这就意味着,当有节点失效时,RDD是可以被重建的。

在Spark中,每个RDD都用一个Scala对象表示,开发者可以使用如下4种途径创建RDD:

  • 通过共享文件系统中的文件创建,例如Hadoop分布式文件系统(HDFS)
  • 通过“parallelizing”一个Scala集合(例如:数组),在driver程序里,表示将数据划分成多份并且将它们发送给多个节点
  • 通过一个已存在的RDD转化。一个元素是类型A的数据集,可以通过一个叫做flatMap的操作,转化为元素是类型B的数据集,即将每一个元素通过一个用户定义的方法typeA=>List[B]。其他的转换也可以通过flatMap进行表达,包括map(让元素通过一个方法type A=>B)和filter(挑选符合预期的元素)。
  • 通过改变一个已存在RDD的持久化方式。默认情况下,RDD是懒加载的并且存活期是短暂的。换而言之,数据集当中的分区只有当RDD被并行操作使用时才会真正实例化,使用完毕后内存就会被释放。但是,用户可以使用以下两种操作修改RDD的持久化方式:

--数据集的cache操作是懒加载的,但是在第一次操作触发计算时RDD就会被保存到内存中,因为它将会被复用

--save操作会对数据集进行求值并且将它写到分布式文件系统里例如HDFS。save的版本可以在后序的操作中使用。

需要指明的是cache操作仅仅是一个暗示:如果集群中并没有足够的内存来保存数据集的每个分区,Spark将会在未能保存到内存里的分区被使用时重新将它们计算出来。我们这样设计,是为了让Spark能够在节点失效或者数据集过大的情况下,仍然可以正常工作。

我们还计划扩展Spark,使它能够支持其他层级的持久化(如,内存中的分区在多个其他节点中保存副本)。我们的目标是让用户可以在RDD存储代价、访问速度、丢失分区的概率、以及重新计算RDD的代价中进行权衡。

2.2 并行操作

         RDD支持多种并行操作。

         reduce:使用方法将数据集中的元素结合在一起,然后返回结果给driver程序

         collect:将数据集中的所有元素返回给driver程序。例如,最简单的并行更新一个数组的方法就是,先parallelize,然后再map,最后再collect这个数组

         foreach:让数据集中的所有元素经过一个用户定义的方法。这只是一个有副作用的方法(也许会将数据复制到另一个系统,或者更新后面要说的共享变量)

         我们需要指出当前Spark只支持一个在MapReduce里进行groupreduce的操作;reduce结果仅由单进程收集(driver)。我们计划在未来的版本里,使用“shuffle”操作来支持分布式数据集上的group reduce,这部分将在第7节里进行描述。然而,就算只用一个reducer也足以实现大量有用的算法。例如,一篇最近的关于在多核系统里进行机器学习的论文,使用MapReduce在没有支持并行reduction的情况下实现了10个机器学习相关的算法。

2.3 共享变量

         开发者调用map、filter、reduce方法,会传递闭包(方法)给Spark。在函数式编程中,闭包会在创建时引用变量。当Spark在工作节点运行闭包时,这些变量会被复制到工作节点。

         然而,Spark也允许开发者创建指定类型的两种共享变量,它们虽然简单但也很有用:

         广播变量:如果一大份只读的数据(例如:查找表)被多个并行操作使用,那么它如果只复制给每个工作节点一次,比每次都复制给每个闭包要更好。Spark允许用户创建“广播变量”,它就只会复制给每个工作节点一次

         累加器:这是一种开发者可以在方法当中进行累加的变量。它们可以被用作实现MapReduce的计数器,以及实现并行程序求和。累加器可以被定义为任何可以“加”并且有“零值”的类型。由于累加器只能进行累加,所以也是很容易实现容错性的。

3.示例

         我们下面来展示一些Spark程序的示例。请注意我们省略了类型,因为Scala支持类型推断。

3.1 文本搜索

         假设我们想要检索一个存储在HDFS上的大的日志文件中包含“error”的行数。可以从一个文件类型的数据集开始如下实现:

         我们首先创建一个叫做file的分布式数据集,它代表了HDFS文件中的行的集合。我们转换这个数据集得到一个包含“ERROR”的行的集合,并且map每一行为1,然后再通过reduce操作进行求和。filter、map、reduce方法的参数都是Scala语法。

         请注意errs,ones都是懒加载的RDD,它们并未被真正实例化。当reduce方法被调用时,每一个工作节点都用流方式检测ones的输入块,然后添加它们来执行本地的reduce,最后再将本地的count值返回给driver端。在使用懒加载数据集这方面,Spark模仿了MapReduce。

         Spark与其他一些框架不同之处在于,它可以跨操作的持久化中间数据集。例如,如果想要复用errs数据集,我们可以如下所示创建一个缓存的RDD:

         我们现在可以在cachedErrs数据集上进行并行操作或由它转换出新的数据集,但是工作节点在第一次计算之后就会在内存中缓存这个数据集的所有分区,这样就可以极大的加快后序的操作。

3.2 逻辑回归

         接下来的程序实现逻辑回归算法,这是一个迭代式的分类算法,想要找到一个超平面w来很好的将点集划分成两个部分。这个算法使用梯度下降:即先用一个随机值初始化w,然后在每轮迭代中,用w带入方法进行求和并不断的修正w。因此在迭代中将数据缓存在内存中对于算法非常有利。我们并不解释逻辑回归的细节,而是用它来展示Spark的新的特性:

         首先我们创建了一个叫做points的RDD,然后再使用一个for循环。for是Scala中的关键字,触发对一个集合的遍历操作并且有一个循环体闭包。即,代码for(p <- points){body}与代码points.foreach(p=> {body})是等价的。因此,我们就触发了Spark的并行foreach操作。

         其次,为了对于梯度进行求和,我们使用了一个叫做gradient的累加器(值是Vector类型)。注意,在循环中使用一个重载的+=方法对于gradient进行累加。循环与累加器的结合使得 Spark程序与普通的串行程序看起来相同。事实上,这个例子与逻辑回归普通串行版本的不同之处只有3行。

3.3 交替最小平方

         我们最后的例子是一个叫做交替最小平方的算法(ALS)。ALS主要是为了解决协同过滤问题,比如根据用户历史的电影评级,来预测他们对于还未看过的电影的评级(类似于Netflix的挑战)。与前面的示例不同,ALS是CPU密集型的,而非数据密集型的。

         我们简要概括下ALS算法,如果读者想要了解细节请看附录后面的文章。假设我们想要预测u个用户对于m个电影的评分,并且我们有一个部分填充的已知评级的用户电影对的矩阵R。ALS的模型R,是由两个矩阵M和U构成,它们的维度分别为m*k以及k*u。即,每个用户和每个电影都有个k维的特征向量来描述他们的特征。一个用户对于一个电影的评级是它的特征向量与电影的特征向量的点积。ALS使用已知的评级得到M和U,然后用M和U的叉积来预测未知电影的评级。以下是迭代步骤:

         1.使用随机值来初始化M

         2.优化U让M与R之间的误差最小

         3.优化M让U与R之间的误差最小

         4.重复2和3步骤直至算法收敛

         ALS的步骤2和3可以在每个节点上并行的更新不同的用户/电影。然而,因为所有的步骤都要使用R,所以让R是一个广播变量是非常有帮助的,这样就不会在每一步中都将它重复的发送给计算节点。ALS的算法在Spark当中的实现如下所示。注意我们parallelize了集合0 until u(一个Scala的范围对象)并且collect它来更新每一个数组:

4.实现

         Spark在Mesos之上构建,这是一个集群操作系统,允许并行程序细粒度的共享集群,并且提供了API让程序能够在集群上运行任务。这就允许Spark运行在已经存在的集群计算框架一起,如Hadoop与MPI的Mesos端口。另外,建立在Mesos之上极大的降低了Spark的编程工作量。

         Spark的核心是实现了弹性分布式数据集。例如,假设我们定义了一个叫做cachedErrs的缓存数据集,用于代表日志文件中包含错误的部分,然后我们用map和reduce对它进行统计,如3.1节那样:

        

         这些数据集都会被存储为对象链,使得RDD能够知道血统(lineage),如图1所示。每个数据集对象都有一个指针指向它的父对象,并且有它的父对象如何转化的信息。

         在内部,每一个RDD对象都实现了一个简单的接口,接口包括三个方法

  • getPartitions,此方法返回分区id列表
  • getIterator(partitions),迭代遍历分区
  • getPreferedLocations(partition),用于任务调度时获取数据位置

         当并行方法在数据集上被调用时,Spark会为数据集的每个分区创建一个任务进行处理,并且将任务发送到工作节点。我们使用延迟调度技术,使得每一个任务都到优先选择的位置执行。

         不同类型的RDD的区别仅仅在于它们如何实现RDD接口。例如,对于HDFS文件类型的RDD而言,分区是HDFS上的块ID,它们优先选择的位置是块位置,getIterator方法将会开启一个读取块文件的数据流。对于Mapped数据集而言,分区及优先位置则与它们的父数据集相同,但是iterator方法会对于父数据集的每一个元素执行map方法。最后,对于缓存数据集而言,getIterator方法将会查看转换分区的已缓存副本,每一个分区的优先位置在初始状态下同父数据集分区的优先位置相同,但是在分区被缓存到一些节点之后会得到更新,以便于优先复用这些节点。这个设计使得容错性非常好实现:如果一个节点失效了,那么分区将会重新从它们的父数据集重新读取,并且最终被缓存到其他节点上。

图1.分布式数据集血统链第4小节示例

         最后,将任务发送给工作节点需要将闭包传递给它们--包括那些用于定义分布式数据集的闭包,以及操作闭包例如reduce操作。为了实现这一点,我们依靠着Scala对象就是Java对象,并且可以使用Java序列化方法进行序列化这一事实;Scala的这个特性使得将计算任务传递给其他机器的实现非常简单。然而,Scala自身的闭包实现并不完美,因为我们发现在一个闭包对象中引入了一个外部变量的话,这个变量是不会再它的内部真正被使用的。我们已经提了这个bug,与此同时,我们对于闭包类的字节码进行静态检测找到这些未被使用的变量并将这些相关的属性置为null来解决这个问题。由于没有多余的空间,所以我们就不再细说分析的细节了。

         共享变量:Spark有两种类型的共享变量,广播变量和累加器,都是使用类的自定义序列化格式实现的。当用户创建了一个广播变量b,值为v,v会被保存为共享文件系统中的一个文件。序列化后的b其实是指向文件的路径。当b的值被一个工作节点请求时,Spark首先检测v是否是在本地缓存中,如果不在缓存中的话则从文件系统中读取它。我们最开始使用HDFS来实现广播变量,不过目前我们正在开发一种更高效的流式广播系统。

         累加器是一种不同的序列化技巧实现的。每个累加器在初始化是都有一个独一无二的ID。但一个累加器被保存时,它的序列化结构中包含这个ID以及累加器所属类型的“零值”。在工作节点上,累加器都会由任务中的每一个线程用thread-local变量创一个副本,并且在任务开始时被值为“零值”。在每一个任务运行完毕后,工作节点会向driver程序发送消息,更新累加器。driver对于每一个分区的每一个操作只对累加器更新一次,一次来规避任务重复执行导致的重复累加问题。

         解释器整合:由于没有空间,我们只概述一下Spark如何整合Scala的解释器。Scala对于用户输入的每一行都会编译一个类。这个类包括一个单例对象,含有变量以及这一行的方法,并且在构造器中运行这一行代码。例如,如果用户输入val x=5,然后输入println(x),解释器就会定义一个类(如Line1)包含x,然后编译第二行为println(Line1.getIntance().x)。这些类会加载到Java虚拟机中来运行每一行。为了解释器能够在Spark中运行,我们进行了两点修改。

         1.我们让解释器将类输出到共享文件系统中,这样它们就可以在工作节点上被工作节点上的Java类装载器加载

         2.我们修改了生成代码,这样单例变量的每一行都可以直接引用前一行,而无需getInstance这样的静态方法。这样就允许闭包得到它们引用的单例的当前状态,不论它们是否被发送到了工作节点上。如果我们不这样修改,那么对于单例变量的修改将不会冒泡给其他工作节点(比如设置x=7以及上述的示例)。

5.结果

         虽然我们目前对于Spark的实现仍处于早期阶段。但我们仍然进行了3次实验用于证明它作为一个集群计算框架是有希望的。

         逻辑回归:我们将3.2节的逻辑回归任务,同Hadoop当中的逻辑回归任务进行比较,使用29GB大小的数据集,运行在20个EC2节点上每个节点4核,结果如图2所示。在Hadoop中,每一轮迭代耗时127s,因为它是作为独立的MapReduce任务执行的。在Spark中,第一轮耗时174s(也许是因为使用了Scala而非Java),但是后序轮迭代仅仅花费6s,这是因为它们使用了已缓存的数据。这就使得任务快速了10倍。

图2.逻辑回归任务在Hadoop和Spark上的表现

         我们还尝试在任务运行时,关闭一个节点。在一个10轮迭代的任务中,这使得每个任务平均减慢了50s(21%)。在丢失节点上的数据,将会被重新计算,并且缓存到其他节点上,但是恢复是时间在当前实验中还是非常高的,这是因为我们使用了一个高的HDFS块大小(128M),每个节点只有12个文件块,所以恢复进程并不能使用集群上的所有核。小的文件块大小将会有更快的恢复时间。

         交替最小平方:我们实现了3.3小节中的交替最小平方算法,来评估广播变量在分布式数据集的多个节点上的好处。我们发现不使用广播变量,每一轮迭代时重新发送评级的矩阵R所耗费的时间占任务总时间的大部分。此外,广播变量的简单实现(使用HDFS或者NFS),广播的时间随着节点数目的增长而线性增长,这样就限制了Job的可扩展性。我们实现了应用级别的多播系统来缓解这一问题。然而,就算是有非常快速的广播,在每一轮迭代中重新发送R也是非常耗时的。使用广播变量,在工作节点的内存当中缓存R,在5000个电影15000个用户的30个EC2节点的集群上进行实验性能提升了2.8倍。

         交互式Spark:我们使用Spark解释器加载从wiki上导出的39G数据在15个EC2机器上并且进行交互式的查询。在第一轮数据查询时,花费了大概35s,与Hadoop Job相比。但是,后序的查询只需要0.5s~1s,甚至对全部数据进行扫描也是如此。这个与本地数据相比,提供了一种本质的不同的经验。

6.相关工作

         分布式共享内存:Spark弹性分布式数据集,可以看做一种分布式共享内存的概念(DSM),这个概念已经被广泛的研究过了。RDD与分布式共享内存有两处不同。其一,RDD提供了一种更加严格的编程模型,但也是一种当有节点失效时可以被重建的模型。虽然有一些DSM模型采用检查点的方式实现容错性,Spark却是使用RDD当中记录的血统信息来重建丢失的分区。这就意味着仅仅只有丢失的分区才需要被重建,而且它们可以在不同的节点并行的被重建,而不需要整个程序都返回到检查点的位置。另外,如果没有节点失效,也不需要做多余的事情。其二,RDD使用MapReduce来计算数据,而不是让所有的计算节点访问一个全局地址空间。

         另外的一些系统受到DSM的限制提升性能、可靠性和可编程性。Munin让开发者使用访问模式注解变量,它们这样可以选择一个最优的一致性协议。Linda提供了元组空间编程模型来实现容错性。Thor提供持久化共享对象的接口。

         集群计算框架:Spark的并行操作符号MapReduce模型。而且,RDD可以跨操作的持久化。

         Twister也意识到需要扩展MapReduce以便支持迭代任务,它是一个MapReduce框架支持在长时间的map任务间保存静态数据在内存中。然而,Twister在目前并没有实现容错性。Spark的弹性分布式数据集,不仅支持容错性,而且比迭代式的MapReduce任务更加通用。一个Spark程序可以定义多个RDD,并且可以在它们中交替运行操作,然而一个Twister程序只能有一个map方法和一个reduce方法。这也使得Spark对于交互式数据查询非常有用,一个用户可以定义多个数据集并且查询它们。

         Spark的广播变量提供了与Hadoop分布式缓存相同的功能,Hadoop分布式缓存是一个能够通过运行特定的Job将文件传输到各个节点的。然而,广播变量还可以跨并行操作的使用。

         语言整合:Spark整合的语言同DryadLINQ比较类似,DryadLINQ使用.NET语言将查询生成语法树然后在集群上运行。同DryadLINQ的区别,在于Spark可以在并行操作中持久化RDD到内存中。另外,Spark丰富了整合的语言模型,支持共享变量(广播变量和累加器),实现了使用自定义序列化格式的类。

         我们推荐是用SMR来使用Scala,这是一个Scala接口可以在Hadoop上使用闭包来定义map和reduce操作。我们对于SMR的贡献在于,共享变量以及更加健壮的闭包序列化实现(第4小节描述的)。

         最后,IPython是一个Python解释器,让用户可以在集群中进行计算,使用容错性的任务队列接口或者低层消息传递接口。Spark提供了相似的交互式接口,但更专注于数据密集型计算任务。

         血统:在数据集中获取血统信息或者起源信息,让应用中的数据可以被重建,在数据库领域的科学计算这块已经是一个长久以来被研究的主题。我们推荐读者阅读【7】【23】【9】来了解相关工作。Spark提供了严格的编程模型,可以非常方便的获取血统信息,这些信息可以用于重建丢失的数据集元素。

7.未来工作

         Spark对于集群编程提供了3个简单的数据抽象:弹性分布式数据集(RDD),和两个限制类型的共享变量:广播变量与累加器。虽然这些抽象是有限的,但我们发现它们足以实现许多应用,并对于现有的集群计算框架进行变革,包括迭代和交互计算。未来,我们相信RDD背后的核心思想,数据集掌握足够的信息使得自身可以被重建,也许可以在集群编程中被证明有用发展一些其他概念。

         未来,我们主要集中研究4个方面:

         1.正式确定RDD的属性以及Spark中的其他抽象,使得它们使用与不同类型的应用以及工作量。

         2.强化RDD,使得用户可以在存储代价和重新计算的代价之间权衡

         3.定义RDD的新的操作,比如"shuffle"操作用一个指定的key对于RDD进行重新分区。类似的操作,可以让我们实现group by和join。

         4.在Spark解释器的基础上提供高层次的交互接口,例如SQL和R。

8.致谢

         我们感谢Ali Ghodsi对于这篇文章的反馈。这项研究是由加利福利亚MICRO、加利福利亚Discovery、自然科学、加拿大工程师委员会、以及伯克利大学RAD实验室赞助商: Sun Microsystems, Google, Microsoft,Amazon, Cisco, Cloudera, eBay,Facebook, Fujitsu,HP, Intel, NetApp, SAP, VMware, and Yahoo!支持的。

 

附录

[1] Apache Hive.http://hadoop.apache.org/hive.

[2] Hadoop Map/Reduce tutorial.http://hadoop.apache.org/

common/docs/r0.20.0/mapred tutorial.html.

[3] Logistic regression – Wikipedia.

http://en.wikipedia.org/wiki/Logisticregression.

[4] The R project for statisticalcomputing.

http://www.r-project.org.

[5] Scala programming language.http://www.scala-lang.org.

[6] Twister: Iterative MapReduce.

http://iterativemapreduce.org.

[7] R. Bose and J. Frew. Lineage retrievalfor scientific data

processing: a survey. ACM ComputingSurveys, 37:1–28,

2005.

[8] J. B. Carter, J. K. Bennett, and W.Zwaenepoel.

Implementation and performance of Munin. InSOSP ’91.

ACM, 1991.

[9] J. Cheney, L. Chiticariu, and W.-C.Tan. Provenance in

databases: Why, how, and where. Foundationsand Trends

in Databases, 1(4):379–474, 2009.

[10] C. T. Chu, S. K. Kim, Y. A. Lin, Y.Yu, G. R. Bradski,

A. Y. Ng, and K. Olukotun. Map-reduce formachine

learning on multicore. In NIPS ’06, pages281–288. MIT

Press, 2006.

[11] J. Dean and S. Ghemawat. MapReduce:Simplified data

processing on large clusters. Commun. ACM,

51(1):107–113, 2008.

[12] J. Ekanayake, S. Pallickara, and G.Fox. MapReduce for

data intensive scientific analyses. InESCIENCE ’08,

pages 277–284, Washington, DC, USA, 2008.IEEE

Computer Society.

[13] D. Gelernter. Generative communicationin linda. ACM

Trans. Program. Lang. Syst., 7(1):80–112,1985.

[14] D. Hall. A scalable language, and ascalable framework.

http://www.scala-blogs.org/2008/09/scalable-languageand-

scalable.html.

[15] B. Hindman, A. Konwinski, M. Zaharia,A. Ghodsi, A. D.

Joseph, R. H. Katz, S. Shenker, and I.Stoica. Mesos: A

platform for fine-grained resource sharingin the data

center. Technical Report UCB/EECS-2010-87,EECS

Department, University of California,Berkeley, May

2010.

[16] B. Hindman, A. Konwinski, M. Zaharia,and I. Stoica. A

common substrate for cluster computing. InWorkshop on

Hot Topics in Cloud Computing (HotCloud)2009, 2009.

[17] M. Isard, M. Budiu, Y. Yu, A. Birrell,and D. Fetterly.

Dryad: Distributed data-parallel programsfrom sequential

building blocks. In EuroSys 2007, pages59–72, 2007.

[18] A.-M. Kermarrec, G. Cabillic, A.Gefflaut, C. Morin, and

I. Puaut. A recoverable distributed sharedmemory

integrating coherence and recoverability.In FTCS ’95.

IEEE Computer Society, 1995.

[19] B. Liskov, A. Adya, M. Castro, S.Ghemawat, R. Gruber,

U. Maheshwari, A. C. Myers, M. Day, and L.Shrira. Safe

and efficient sharing of persistent objectsin thor. In

SIGMOD ’96, pages 318–329. ACM, 1996.

[20] B. Nitzberg and V. Lo. Distributedshared memory: a

survey of issues and algorithms. Computer,24(8):52 –60,

aug 1991.

[21] C. Olston, B. Reed, U. Srivastava, R.Kumar, and

A. Tomkins. Pig latin: a not-so-foreignlanguage for data

processing. In SIGMOD ’08. ACM, 2008.

[22] F. P´erez and B. E. Granger. IPython:a system for

interactive scientific computing. Comput.Sci. Eng.,

9(3):21–29, May 2007.

[23] Y. L. Simmhan, B. Plale, and D.Gannon. A survey of

data provenance in e-science. SIGMOD Rec.,

34(3):31–36, 2005.

[24] H.-c. Yang, A. Dasdan, R.-L. Hsiao,and D. S. Parker.

Map-reduce-merge: simplified relationaldata processing

on large clusters. In SIGMOD ’07, pages1029–1040.

ACM, 2007.

[25] Y. Yu, M. Isard, D. Fetterly, M.Budiu, U´ . Erlingsson,

P. K. Gunda, and J. Currey. DryadLINQ: Asystem for

general-purpose distributed data-parallelcomputing using

a high-level language. In OSDI ’08, SanDiego, CA, 2008.

[26] M. Zaharia, D. Borthakur, J. SenSarma, K. Elmeleegy,

S. Shenker, and I. Stoica. Delayscheduling: A simple

technique for achieving locality andfairness in cluster

scheduling. In EuroSys 2010, April 2010.

[27] Y. Zhou, D. Wilkinson, R. Schreiber,and R. Pan.

Large-scale parallel collaborativefiltering for the Netflix

prize. In AAIM ’08, pages 337–348, Berlin,Heidelberg,

2008. Springer-Verlag.

7


爱元宵三五风光,月色婵娟,灯火辉煌。
月满冰轮,灯烧陆海,人踏春阳。
三美事方堪胜赏,四无情可恨难长。
怕的是灯暗光芒,人静荒凉,角品南楼,月下西厢。

 

0 0
原创粉丝点击