与 Spark 对比

Apache Spark 是一个流行的分布式计算工具,用于处理表格数据集,并且正在成为当今大数据分析领域的主导力量。Dask 有一些方面似乎与 Spark 相交,我们经常被问到:“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

DataFrames

  • 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 提供了一个 实时 futures 接口,其级别低于 Spark streaming。这使得更具创意和复杂的用例成为可能,但比 Spark streaming 需要更多的工作。

图 / 复杂网络

  • 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 工作负载的集群,那么也很容易在您当前的基础设施上运行 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