有啥方法可以提高 PySpark 输出的效率吗?

Posted

技术标签:

【中文标题】有啥方法可以提高 PySpark 输出的效率吗?【英文标题】:Is there any way to increase the efficiency of PySpark outputs?有什么方法可以提高 PySpark 输出的效率吗? 【发布时间】:2017-12-01 18:30:08 【问题描述】:

我正在尝试测试 PySpark 迭代一些非常大的数据(10 GB 到 1 TB)数据的能力。对于大多数脚本,我发现 PySpark 的效率与 Scala 代码大致相同。在其他情况下(如下面的代码),我会遇到严重的速度问题,速度会慢 10 到 12 倍。

path = "path/to/file"
spark = SparkSession.builder.appName("siteLinkStructureByDate").getOrCreate()
sc = spark.sparkContext   

df = RecordLoader.loadSomethingAsDF(path, sc, spark)
fdf = df.select(df['aDate'], df['aSourceUrl'], df['contentTextWithUrls'])
rdd = fdf.rdd
rddx = rdd.map (lambda r: (r.aDate, CreateAVertexFromSourceUrlAndContent(r.aSourceUrl, r.contentTextWithUrls)))\
 .flatMap(lambda r: map(lambda f: (r[0], ExtractDomain(f[0]), ExtractDomain(f[1])), r[1]))\
 .filter(lambda r: r[-1] != None)\
 .countByValue()

print([((x[0], x[1], x[2]), y) for x, y in rddx.items()]) 

我们认为我们已将问题隔离到 .countByValue()(它返回一个 defaultdict),但应用 countItems() 或 reduceByKey() 会产生几乎相同的结果。我们也 99% 确定问题不在于 ExtractDomain 或 CreateAVertexFromSourceUrlAndContent(不是函数的真实名称,只是为了使其易于理解的伪代码)。

所以我的问题是第一个

    我可以在这段代码中做些什么来减少时间吗? PySpark 从根本上说是 比它的 Scala 慢得多吗 对方? 有没有办法复制平面图 改用 PySpark 数据帧(了解数据帧是 通常比 Pyspark 中的 RDD 快)?

【问题讨论】:

【参考方案1】:

这里最大的问题可能是通信 - Spark SQL(列格式) -> 普通 Scala 对象 -> pickle (Pyrolite) -> 套接字 -> unpickle -> 普通 Python 对象。这需要大量的复制、转换和移动。

有一种方法可以使用 PySpark 数据帧来复制平面地图

是的。它被称为explode - 但公平地说,它也很慢。

了解数据帧通常比 Pyspark 中的 RDD 更快

这通常是正确的(Scala 和 Python 都是),但您可能需要 udf 来实现 ExtractDomainCreateAVertexFromSourceUrlAndContent - 这是另一件缓慢的事情。仅从您可能可以使用parse_url_tuple 的名称来看。

从根本上说,PySpark 是否比它的 Scala 慢很多?

它有点慢。通常在经过良好调整的代码上不会那么慢。但实现细节有所不同——Scala 和 Python 中的同一组操作可以以不同的方式实现。

我可以在这段代码中做些什么来减少时间吗?

我建议先进行分析。一旦确定了负责的部分(转换、合并),您就可以尝试定位它。

【讨论】:

以上是关于有啥方法可以提高 PySpark 输出的效率吗?的主要内容,如果未能解决你的问题,请参考以下文章

有啥好的习惯和工具可以帮助程序员提高工作效率

有啥方法可以提高vmware虚拟机的性能吗

SparkSession 中的 udf 和 pyspark.sql.functions 中的 udf 有啥区别

在 pyspark 中注册我的 udf 有啥好处吗?

有啥方法可以自动输出 requirements.txt 吗?

有啥方法可以在 pyspark 数据框中找到包含数据的列数