从一个引人注目的标题“Spark 为什么这么慢?”开始,值得注意的是,称 Spark“慢”可能意味着多种含义。聚合速度慢吗?数据加载?存在不同的情况。此外,“Spark”是一个广泛的术语,其性能取决于编程语言和使用上下文等因素。因此,在深入讨论之前,让我们将标题改进得更加精确。
由于我主要在 Databricks 上使用 Spark 和 Python,因此我将进一步缩小范围。
优化后的标题将是:
“Spark 的第一印象:‘听说它很快,但为什么感觉很慢?’初学者的视角”
作为广泛使用 pandas、NumPy 和机器学习库的人,我钦佩 Spark 通过并行和分布式处理处理大数据的能力。当我终于在工作中使用 Spark 时,我对它看起来比 pandas 慢的场景感到困惑。不确定出了什么问题,我发现了一些见解并想与大家分享。
我们简单介绍一下Spark的基本架构。
(集群模式概述)
Spark 集群由执行实际处理的 工作节点和协调和计划执行的驱动程序节点组成。这种架构会影响下面讨论的所有内容,因此请记住这一点。
现在,进入要点。
Spark 针对大规模数据处理进行了优化,但它也可以处理小型数据集。然而,看看这个基准:
(在单节点机器上对 Apache Spark 进行基准测试)
结果表明,对于 15GB 以下的数据集,pandas 在聚合任务中优于 Spark。为什么?简而言之,Spark 优化的开销超过了小数据集的好处。
该链接显示了 Spark 并不慢的情况,但这些情况通常处于本地集群模式。对于独立设置,由于节点之间的网络通信开销,较小的数据集可能是一个缺点。
Spark 采用惰性求值,这意味着转换不会立即执行,而是推迟到某个操作(例如收集、计数、显示)触发计算为止。
示例(熊猫):
df = spark.read.table("tpch.lineitem").limit(1000).toPandas() df["l_tax_percentage"] = df["l_tax"] * 100 for l_orderkey, group_df in df.groupby("l_orderkey"): print(l_orderkey, group_df["l_tax_percentage"].mean())
执行时间:3.04秒
Spark 中的等效项:
from pyspark.sql import functions as F sdf = spark.read.table("tpch.lineitem").limit(1000) sdf = sdf.withColumn("l_tax_percentage", F.col("l_tax") * 100) for row in sdf.select("l_orderkey").distinct().collect(): grouped_sdf = sdf.filter(F.col("l_orderkey") == row.l_orderkey).groupBy("l_orderkey").agg( F.mean("l_tax_percentage").alias("avg_l_tax_percentage") ) print(grouped_sdf.show())
执行时间:3分钟后仍在运行。
为什么?
Spark 代码在 pandas 中有效地执行了此操作:
for l_orderkey, group_df in df.groupby("l_orderkey"): df["l_tax_percentage"] = df["l_tax"] * 100 print(l_orderkey, group_df["l_tax_percentage"].mean())
通过使用 Spark 的缓存或重构逻辑以尽量减少重复计算来避免此类模式。
https://spark.apache.org/docs/latest/rdd-programming-guide.html#shuffle-operations
随机播放 当数据在 Workers 之间重新分配时发生,通常是在 groupByKey、join 或重新分区等操作期间。随机播放可能会很慢,原因是:
例如,拥有更多 Worker 并不总能提高洗牌期间的性能。
您觉得这有帮助吗?如果有效使用,Spark 是一个出色的工具。除了加速大规模数据处理之外,Spark 还以其可扩展的资源管理而大放异彩,尤其是在云中。
尝试 Spark 来优化您的数据运营和管理!
以上是为什么 Spark 慢?的详细内容。更多信息请关注PHP中文网其他相关文章!