Spark、Dask、Ray:选择合适的框架


Spark、Day、Ray:历史概要

Apache Spark

Spark由加州大学伯克利分校AMPLab的Matei Zaharia于2009年创建。这个项目的主要目的是为了加快分布式大数据任务的执行速度,而当时的分布式大数据任务是由Hadoop MapReduce处理的。MapReduce在设计时考虑到了可伸缩性和可靠性,但性能或易用性却不是它的强项。MapReduce不断需要将中间结果存储到磁盘,这是Spark要克服的关键障碍。通过引入弹性分布式数据集(RDD)范式,并利用内存缓存和延迟计算,与MapReduce相比Spark能够将延迟降低几个数量级。这使得Spark成为大规模、容错和并行数据处理事实上的标准。GraphX(用于分布式图形处理),MLLIB(用于机器学习),SparkSQL(用于结构化和半结构化数据)等组件的加入进一步增强了该项目。

值得注意的是,Spark是用Scala编写的,随后添加了Python和R支持,因此与它交互通常感觉不够Pythonic。理解RDD范式以及如何在Spark中完成工作需要一些时间,但对于熟悉Hadoop生态系统的人来说,这通常不是问题。

Dask

Dask是发布于2015年的一个用于并行计算的开源库,所以与Spark相比它比较新。这个框架原本是ContinuumAnalytics(现Anaconda公司)开发的,这个公司是很多Python开源包的创造者,包括Anaconda Python发行版。Dask最初的目的只是将NumPy并行化,这样它就可以利用具有多个cpu和核的工作站计算机。与Spark不同,在Dask开发中采用的最初设计原则之一是“什么都不发明”。这一决定背后的想法是,与Dask一起使用Python进行数据分析应该让开发人员感到熟悉,并且知识升级时间应该很短。根据其创建者的说法,Dask的设计原则经过了多年的发展,现在它正在被开发成一个用于并行计算的通用库。

围绕平行numpy的初始想法,进一步发展到包括一个完全成熟的、轻量级的任务调度器,它可以跟踪依赖关系并支持大型多维数组和矩阵的并行化。后来,并行化的Pandas DataFrames和scikit-learn得到了进一步的支持。这使得该框架能够缓解Scikit的一些主要痛点,比如计算量大的网格搜索和太大而无法完全放入内存的工作流。最初的单机并行化目标后来被引入的分布式调度超越了,该计划现在使Dask能够在多机多TB问题空间中舒适地运行。

Ray

Ray是加州大学伯克利分校的另一个项目,其使命是“简化分布式计算”。Ray由两个主要组件组成——Ray Core(一个分布式计算框架)和Ray Ecosystem(广义上说,Ray Ecosystem是与Ray打包的一系列特定于任务的库)(例如,Ray Tune——一个超参数优化框架,用于分布式深度学习的RaySGD,用于强化学习的RayRLib等等)。

Ray类似于Dask,因为它允许用户在多台机器上以并行的方式运行Python代码。然而,与Dask不同的是,Ray并没有试图模拟NumPy和Pandas 接口——它的主要设计目标不是临时替代Data Science的工作负载,而是提供一个通用的底层框架来并行化Python代码。这使得它更像一个通用的集群和并行框架,可以用来构建和运行任何类型的分布式应用程序。由于Ray Core的架构方式,它经常被认为是一个用于构建框架的框架。还有越来越多的项目与Ray集成,以利用加速GPU和并行计算。spaCy、hugs Face和XGBoost都是引入Ray互操作性的第三方库的例子。

选择合适的框架

不幸的是,没有简单直接的方法来选择“最好的”框架。每个复杂的问题都是如此,答案很大程度上取决于环境和在我们特定工作流程中发挥作用的许多其他因素。让我们看看这三个框架,并考虑它们的优点和缺点,同时考虑各种常见的用例。

Spark

  • 优势

    • 技术成熟(2014年5月发布)
    • 大量公司提供商业服务支持
    • 针对大型数据集的数据工程 / ETL任务类型的理想选择。
    • 提供高层SQL抽象(Spark SQL)
  • 劣势

    • 涉及新的执行模型和API的陡峭学习曲线。
    • 调试困难
    • 复杂的体系结构使得IT很难单独维护,因为适当的维护需要了解SPARK的计算范式和内部工作(例如,内存分配)
    • 缺乏丰富的数据可视化生态
    • 没有内建GPU加速,需要 RAPIDS Accelerator(激流加速器)来访问GPU资源

Dask

  • 优势
    • 纯Python框架-非常容易学习和切换
    • 对Pandas DataFrames和NumPy 数组有开箱即用的支持
    • 通过Datashader可以很容易对数十亿行数据进行探索性分析
    • 提供Dask Bags :一个Pythonic版本的PySpark RDD,带有map、filter、groupby等函数功能
    • Dask可以带来令人印象深刻的性能改进。2020年6月,英伟达公布了在16个DGX A100系统(128个A100 gpu)上使用RAPIDS、Dask和UCX进行TPCx-BB测试的惊人结果 results on the TPCx-BB 。然而,对此我们还是持保留态度。2021年1月,TPC迫使英伟达将这些结果撤下,因为它们违反了TPC的合理使用政策
  • 劣势
    • 目前还没有太多的商业支持(但有几家公司已经开始在这个领域开展工作,例如Coiled和QuanSight)。
    • 没有内置的GPU支持。依靠RAPIDS 来加速GPU

Ray

  • 优势
    • 最小集群配置
    • 最适合计算繁重的工作负载。已经有研究表明,Ray在某些机器学习任务(如NLP、文本规范化等)上的表现优于Spark和Dask。最重要的是,即使在单个节点上也是如此,Ray的工作速度似乎比Python标准多进程快10%左右
    • 因为Ray越来越多地被用于扩展不同的ML库,所以您可以以一种可扩展的、并行的方式将它们一起使用。另一方面,Spark将您限制在其生态系统中可用的框架数量少得多
    • 独特的基于Actor的抽象,多个任务可以异步地在同一个集群上工作,从而获得更好的利用率(相比之下,Spark的计算模型没有那么灵活,而是基于并行任务的同步执行)。
  • 劣势
    • 相对较新(首次发布于2017年5月)
    • 并不是针对分布式数据处理量身定制的。Ray没有用于分区数据的内置原语。该项目只是刚刚引入 Ray Datasets,但这是一个全新的添加,仍然是相当新只有一个简单的骨架。
    • GPU支持仅限于调度和预订。实际怎样使用GPU取决于远程功能(通常是通过TensorFlow和Pytorch等外部库)

通过分析这三个框架的优缺点,我们可以总结出以下选择标准:

  • 如果工作负载以数据为中心,并且更多地围绕ETL/预处理,那么我们最好的选择就是Spark。特别是如果组织对Spark API有系统化认知
  • Dask/Ray选择并不是那么明确,但一般规则是Ray旨在加快任何类型的Python代码,Dask适合于数据科学特定的工作流程

让事情更复杂的是,还有一个Dask-on- Ray项目,它允许你运行Dask工作流而不使用Dask分布式调度器。为了更好地理解Dask-on- Ray试图填补的空白,我们需要看看Dask框架的核心组件。其中包含集合抽象(DataFrames、数组等)、任务图(一个DAG,它代表了一组类似于Apache Spark DAG的操作)和调度器(负责执行Dask图)。分布式调度器是Dask中可用的调度器之一,它负责协调分布在多台机器上的多个工作进程的操作。这个调度器非常棒,因为它易于设置、保持最小的延迟、允许点对点数据共享,并支持比简单的map-reduce链复杂得多的工作流。另一方面,分布式调度器也不是没有缺陷。它的一些缺点包括:

  • 它是一个单点 - 分布式调度程序没有高可用性机制,因此,如果失败,则需要重置整个群集,并且所有过程中的任务都会丢失。
  • 它是用Python编写的,这使得它易于安装和调试,但它也引入了通常与Python一起使用的标准性能考虑因素。
  • Client API在设计时考虑到了数据科学家,并没有针对来自高可用性生产基础设施的调用进行定制(例如,它假设客户端是长期存在的,可能通过Jupyter会话在集群上操作)
  • 它对有状态执行提供了最低限度的支持,因此很难实现容错管道。
  • 它可能会成为瓶颈,而且无法自行扩展

相比之下,容错和性能是深深嵌入在Ray调度器设计中的原则。它是完全去中心化的(没有瓶颈)、提供更快的数据共享(通过Apache Plasma)、单个调度器是无状态的(容错)、支持有状态的参与者等等。这使得在Ray集群上运行Dask任务具有很大吸引力是非常可以理解的,这也是être搞Dask-on-Ray调度器的原因。对Dask -on- Ray项目的深入研究超出了这篇博文的范围,但是如果你有兴趣更深入地比较两者的性能,请随意查看Anyscale所做的内存管理和性能基准测试

如何做出自己的选择?(提示:你真的需要吗?)

现在我们已经看了Spark、Dask和Ray的优缺点,在简要讨论了Dask-on-Ray的混合方案后,很明显这不是“一刀切”的情况。这三个框架从一开始就有不同的设计目标,试图将根本上不同的工作流程塞到一个框架中可能不是最明智的选择。一种更好的方法是在设计数据科学流程和配套基础设施时考虑到灵活性,理想情况下使您能够使用正确的工具完成工作。典型的流程管道可能涉及在Spark中执行一些类似etl的数据处理,然后在Ray中执行机器学习工作流。如果平台能够以可控、容错和随需应变的方式自由运行,那么数据科学团队就能够利用这两种框架的优点。

从Spark(DataFrames)到Ray(分布式训练)再到Spark(转换)的高层概述。Ray评估器将这种复杂性封装在Spark评估器接口中。图片来源:https://eng.uber.com/elastic-xgboost-ray/

混合框架的重要性已经通过集成库的出现得到了明显体现,这些集成库使框架间的通信更加精简流线化。比如,Spark on Ray 正是这样做的——它“结合你的Spark和Ray集群,使用PySpark API轻松地进行大规模数据处理,并使用TensorFlow和PyTorch无缝地使用这些数据来训练你的模型“。还有 Ray on Spark 项目它使我们能够在Apache Hadoop/Yarn上运行Ray程序。这种方法已经在实际的生产工作负载中成功地测试过了。例如,Uber的机器学习平台 Michelangelo定义了Ray Extiator API,该API为终端用户抽象了在Spark和Ray之间移动的过程。Uber Engineering最近发布的一篇文章详细介绍了这一点,其中介绍了一种涉及Spark和XGBoost on Ray的分布式培训架构

总结

本文介绍了三个最流行的并行计算框架。讨论了它们的优点和缺点,并就如何为手头的任务选择正确的框架给出了一些一般性的指导。推荐的方法不是寻找适合所有可能的需求或用例的最终框架,而是理解它们如何适应各种工作流,并拥有足够灵活的数据科学基础设施,以允许混合匹配方法。

posted @ 2022-08-09 18:27  Tacey Wong  阅读(4630)  评论(0编辑  收藏  举报