An Architecture for Fast and General Data Processing on Large Clusters

Matei的博士论文. 我看的是CSDN众包翻译版本 https://code.csdn.net/CODE_Translation/spark_matei_phd.


高效率的数据共享机制

我们的工作源于观察到很多数据流模型不适用的应用场景所共有的一个特征: 在计算过程中都需要高效率的 数据共享 。例如,迭代算法,如 PageRank, K-means 聚类,或逻辑回归,都需要进行多次访问相同的数据集;交互数据挖掘经常需要对于同一数据子集进行多个特定的查询;而流式应用下则需要随时间对状态信息进行维护和共享。不幸的是,尽管数据流框架支持大量的计算操作运算,但是它们缺乏针对数据共享的高效原语。在这些框架中, 实现计算之间(例如,两个的 MapReduce 作业之间)数据共享只有一个办法,就是将其写到一个稳定的外部存储系统,如分布式文件系统。这会引入数据备份、磁盘 I/O 以及序列化,这些都会引起大量的开销,从而占据大部分的应用执行时间。

事实上,在针对这些新应用而定制的框架进行研究的过程中,我们的确有发现它们会对数据共享进行优化。例如,Pregel是一种针对图迭代计算的系统,它会将中间状态保存在内存中。而 HaLoop是一种迭代 MapReduce 的系统,它会在各步骤中都以一种高效率的方式对数据进行分区。不幸的是,这些框架只能支持特定的计算模式( 例如 ,循环一系列的 MapReduce 的步骤),并对用户屏蔽了数据共享的方式。它们不能提供一种更为通用的抽象模式, 例如 ,允许一个用户可以加载几个数据集到内存中并进行一些跨数据集的即时查询。

现有的基于集群的内存存储抽象,比如分布式共享内存,键-值存储,数据库,以及 Piccolo,提供了一个对内部状态基于细粒度更新的接口( 例如, 表格里面的单元).在这样的设计之下,提供容错性的方法就要么是在主机之间复制数据,要么对各主机的更新情况做日志记录。这两种方法对于数据密集型的任务来说代价很高,因为它们需要在带宽远低于内存的集群网络间拷贝大量的数据,同时还将产生大量的存储开销。


不适合RDD的应用

RDDS 不太适用于通过异步细粒度更新来共享状态的应用,比如针对 Web 应用或增量网络爬虫的存储系统。对于这些应用,那些传统的更新日志和数据检查点的系统会更有效,例如数据库,RAMCloud, Percolator 和 Piccolo 。我们的目标是为批量分析提供一个高效的编程模型,这些异步应用仍然交由定制系统来处理。但是,第 5 章会提供一些把这些类型的应用与 RDD 模型结合起来的可能方法,比如批量更新。


解释RDD表达能力

为什么 RDD 能够表达这些不同的编程模型?原因就是 RDD 上的限制在许多并行应用程序中影响非常小。其原因在于,虽然 RDD 仅能通过批量变换来创建,但众多的并行程序本质上都是对多条记录执行相同的操作 ,而这点便使得它们易于表达。另外,RDD 的不变性也不会影响其表达,因为相同数据集的各个不同版本可以通过多个对应的 RDD 来表示。事实上,大多数当前的MapReduce 应用所基于的文件系统,比如 HDFS,并不允许更新文件(译注:记录只能创建或删除,而不能修改)。在后续章节(3 和 5)中,我们会对 RDD 表达进行更为详细的阐述。最后一个问题是,为什么之前的框架没有提供相同级别的通用性呢?我们认为,这是由于这些系统仅关注在 MapReduce 和 Dryad 所不擅长的特定问题上,比如迭代,而未能发现这些问题均是因为缺乏对数据共享的抽象。


集群应用资源瓶颈

虽然集群应用是多种多样的,但是它们都受到相同的底层硬件的限制。目前的数据中心有一个非常不合理的存储层次结构,这将会因相同的原因限制大多数应用。例如,现在一个典型的数据中心可能有以下硬件特性:

鉴于这些特性,许多应用所关心的最重要的性能指标就是控制网络布局和通信。


经验总结

数据共享的重要性。我们工作的基本主线是数据共享对于性能的重要性,数据共享无论是对单一模式的计算( 例如, 迭代算法或数据流作业)应用,还是多种计算模式交错的应用都非常重要。特别是对于“大数据”的应用程序,数据集迁移代价是非常高的,所以对应用开发者来说,有效共享是很关键的。然而,以前的系统大多集中在实现特定的数据流模式,而 RDDs 使数,同时其足够据集成为一等原语,为用户提供了足够的机制来控制其属性( 例如, 分区和持久性)抽象的接口能够自动提供容错功能。 由于每台机器的网络带宽,存储带宽和计算能力之间的差异,我们认为数据共享在大多数分布式应用中,仍备受关注,并行处理平台仍将需要解决这一问题。

在共享环境中衡量性能,而不是基于单一应用。虽然针对特定应用的进行执行引擎优化是有益的,但我们所得到的另一个总结是,现实中的部署往往是比较复杂的,而在这些复杂的设置中衡量性能则是最重要的。特别是:

例如,假设一个机器学习算法的专门实现,使用一个像MPI的这样的执行模型(在整个应用运行过程中资源是静态分配的),比Spark 执行快上 5 倍。然而在一个端到端的工作流程中这样的专有系统仍然会比较慢,这个流程包括使用MapReduce脚本的解析数据文件,然后运行学习算法。为了衔接这两个过程,将会需要把解析所得的数据集额外输出到一个可靠的存储系统中,从而来实现系统之间的共享。并且在一个多用户集群中,专有系统需要预先为应用选择一个固定的分配,这或将导致应用出现排队状况,又或是没有充分利用资源,并且与RDDs这样的细粒度执行模式相比,降低了集群中的所有用户的响应能力。 我们认为,由于观点和上面所说的第一个经验相同(数据迁移比较昂贵)集群将会被动态地分享,这需要应用横向或是纵向积极地扩展以及轮流访问每个节点上的数据。在这些环境中,我们认为计算机系统将不得不为了这样的共享应用而进行 优化 ,从而在大多数部署中获得一定的性能优势。

瓶颈优化相当重要。一个有趣的经验是,如何设计通用处理引擎还要看瓶颈在哪里。在很多情况下,一些资源最终限制了整个应用的性能,所以给用户优化这些资源的控制力能够得到良好的性能。例如,当 Cloudera 发布 Impala SQL 引擎时,伯克利 AMPLab 发现,与 Shark 相比,在许多查询中,性能几乎相同。这是为什么呢?这些查询要么是 I/O,要么是网络瓶颈,这两个系统都使可用带宽达到了饱和。这是一个有趣的方法来处理通用性问题,因为这意味着一般不需要低级抽象。例如,RDDs 通过控制分区给用户优化网络使用(最常见的瓶颈)的能力。但是,他们是使用通用的模式来做到这一点的( 例如, 分区),而不需要用户手动选择哪台机器上的每块数据,因此可以自动处理再平衡和容错能力。