与 Spark 的对比

Apache Spark 是一个流行的表格数据集分布式计算工具,如今正成长为大数据分析领域的主导名称。Dask 有几个方面似乎与此领域相交,我们经常被问到:“Dask 与 Spark 相比如何?”

以公正和知情的方式回答此类对比问题很困难,尤其是在差异可能有些技术性时。本文试图做到这一点;我们欢迎任何更正。

摘要

通常,Dask 比 Spark 更小、更轻量。这意味着它具有较少的功能,而是与特别是数值 Python 生态系统中的其他库结合使用。它与 Pandas 或 Scikit-Learn 等库配合使用以实现高级功能。此外,Dask 在标准基准测试中的性能通常比 Spark 更快、更稳定。

语言

  • Spark 用 Scala 编写,并对 Python 和 R 提供一些支持。它与其他 JVM 代码互操作性良好。

  • Dask 用 Python 编写,并且只真正支持 Python。它与通过 Python 链接的 C/C++/Fortran/LLVM 或其他原生编译代码互操作性良好。

生态系统

  • Spark 是一个一体化项目,催生了它自己的生态系统。它与许多其他 Apache 项目集成良好。

  • Dask 是更广阔的 Python 生态系统的一部分。它与 NumPy、pandas 和 Scikit-learn 等其他库结合并增强它们。

成熟度和信任度

  • Spark 历史更久 (自 2010 年起),已成为大数据企业领域中一个主导且备受信赖的工具。

  • Dask 相对年轻 (自 2014 年起),是备受信赖的 NumPy/pandas/Scikit-learn/Jupyter 技术栈的扩展。

范围

  • Spark 更侧重于传统的商业智能操作,如 SQL 和轻量级机器学习。

  • Dask 应用更广泛,既用于商业智能应用,也用于一些科学和定制化场景。

内部设计

  • Spark 的内部模型是更高级别的,对统一应用的计算提供了良好的高级优化,但在处理更复杂的算法或临时系统时缺乏灵活性。它本质上是 Map-Shuffle-Reduce 范式的扩展。

  • Dask 的内部模型是更低级别的,因此缺乏高级优化,但能够实现更复杂的算法并构建更复杂的定制系统。它本质上基于通用任务调度。

规模

  • Spark 可以从单个节点扩展到数千个节点的集群。

  • Dask 可以从单个节点扩展到数千个节点的集群。

API

DataFrame

  • Spark DataFrame 有自己的 API 和内存模型。它还实现了 SQL 语言的一个大型子集。Spark 包含一个用于复杂查询的高级查询优化器。

  • Dask DataFrame 复用 Pandas API 和内存模型。它既不实现 SQL 也不实现查询优化器。它能够进行随机访问、高效的时间序列操作以及其他 Pandas 风格的索引操作。

机器学习

  • Spark MLLib 是一个内聚的项目,支持使用 Spark 的 Map-Shuffle-Reduce 风格系统易于实现的常见操作。考虑 MLLib 的人也可能希望考虑 其他 基于 JVM 的机器学习库,如 H2O,其性能可能更好。

  • Dask 依赖并与现有的库(如 Scikit-learn 和 XGBoost)互操作。这些库可能更熟悉或性能更高,但通常导致整体的内聚性较低。有关集成,请参见 dask-ml 项目。

数组

  • Spark 原生不支持多维数组(考虑到其计算模型,这将具有挑战性),尽管在 MLLib 中可以找到对二维矩阵的一些支持。人们可能还想看看 Thunder 项目,该项目将 Apache Spark 与 NumPy 数组结合在一起。

  • Dask 完全支持 NumPy 模型,用于 可扩展的多维数组

流处理

  • Spark 对流数据的支持是一流的,并且很好地集成到其其他 API 中。它采用微批处理方法。这在大型统一流操作中提供了不错的性能。

  • Dask 提供了一个 实时 Future 接口,该接口比 Spark 流处理更底层。这使得实现更具创意和复杂的用例成为可能,但比 Spark 流处理需要更多工作。

图 / 复杂网络

  • Spark 提供了 GraphX,一个用于图处理的库。

  • Dask 不提供此类库。

自定义并行

  • Spark 通常期望用户使用其高级原语(map, reduce, groupby, join, …)来组合计算。也可以通过 RDD 的子类化来扩展 Spark,尽管这样做很少见。

  • Dask 允许您为更复杂和定制的系统指定任意任务图,这些系统不是标准集合的一部分。

您可能选择 Spark 的原因

  • 您偏好 Scala 或 SQL 语言

  • 您主要拥有 JVM 基础设施和遗留系统

  • 您想要一个成熟且值得信赖的商业解决方案

  • 您主要进行商业分析并进行一些轻量级机器学习

  • 您想要一个一体化解决方案

您可能选择 Dask 的原因

  • 您偏好 Python 或原生代码,或者拥有不希望完全重写的大型遗留代码库

  • 您的用例复杂或不完全适合 Spark 计算模型

  • 您希望从本地计算向集群计算进行更轻量级的过渡

  • 您希望与其他技术互操作,并且不介意安装多个软件包

同时选择两者的原因

在相同的数据和相同的集群上使用 Dask 和 Spark 都很容易。

它们都可以读写常见格式,例如 CSV、JSON、ORC 和 Parquet,从而使得在 Dask 和 Spark 工作流之间传递结果变得容易。

它们都可以部署在相同的集群上。大多数集群都设计为同时支持许多不同的分布式系统,使用诸如 Kubernetes 和 YARN 之类的资源管理器。如果您已经有一个运行 Spark 工作负载的集群,那么在您当前的 infrastructure 上运行 Dask 工作负载也很可能很容易,反之亦然。

特别是对于来自传统 Hadoop/Spark 集群(例如 Cloudera/Hortonworks 销售的集群)的用户,您正在使用 Yarn 资源管理器。您可以使用 Dask Yarn 项目以及其他项目(例如 JupyterHub on Hadoop)在这些系统上部署 Dask。

开发者面对的差异

图粒度

Spark 和 Dask 都使用有向无环图表示计算。然而,这些图表示的计算粒度非常不同。

Spark RDD 上的一个操作可能会向图中添加一个节点,例如 MapFilter。这些是传达意义的高级操作,最终将转化为许多小任务在单个 worker 上执行。这种多任务状态仅在 Spark 调度器内部可用。

Dask 图跳过这种高级表示,直接进入多任务阶段。因此,Dask 集合上的一个 map 操作会立即生成并可能将数千个微小任务添加到 Dask 图中。

底层图规模的这种差异影响着可以进行的分析和优化类型,也影响着暴露给用户的通用性。Dask 无法执行 Spark 可以执行的一些优化,因为 Dask 调度器没有对被要求执行的计算的自顶向下视图。然而,Dask 能够轻松表示远比这更 复杂的算法,并将这些算法的创建暴露给普通用户。

结论

  • Spark 成熟且功能齐全。如果您想要一个涵盖所有功能的项目,并且您已经在使用大数据硬件,那么 Spark 是一个安全的选择,特别是如果您的用例是典型的 ETL + SQL 并且您已经在用 Scala。

  • Dask 更轻量,更容易集成到现有代码和硬件中。如果您的难题超出典型的 ETL + SQL,并且您希望为现有解决方案添加灵活的并行性,那么 Dask 可能是一个不错的选择,特别是如果您已经在用 Python 以及相关的库(如 NumPy 和 Pandas)了。

如果您想要管理 100GB 或以下的表格 CSV 或 JSON 数据,那么您应该忘记 Spark 和 Dask,而使用 PostgresMongoDB