我跑步时
import time
start_time = time.time()
print(df_join.count())
end_time = time.time()
print((end_time - start_time))
我得到
25721
19.099464416503906
我跑步时
start_time = time.time()
df_join.cache()
print(df_join.count())
end_time = time.time()
print((end_time - start_time))
5分钟后它仍在运行。缓存27行数据真的需要这么长时间吗?大约15到20列宽,复杂度是url字符串。
编辑1: 事实证明,我有一列,其类型是jsons数组。如果我将其取出,则一切正常。不幸的是,pyspark将其作为字符串读取,我不知道如何告诉它是jsons数组
我该如何改善?
答案 0 :(得分:0)
不确定URL字符串的含义,但是字符串具有最大的字节数并在序列化时占用最多的内存...我会运行
df_join.explain()
并检查转换中触发了多少次重排...因为这是一个很小的数据集,所以减少到类似
spark.conf.set("spark.sql.shuffle.partitions, 8)
还希望确保每个执行器有足够的内核,可以在运行时通过启动shell进行设置,例如
pyspark --master yarn executor-cores 5
总体而言,速度缓慢可能是由诸如设置了什么部署(本地,独立,yarn [客户端/集群])配置参数的数据量之类的原因引起的...通常是我所见的原因是持久时间更长作业归结为由广泛的转换(联接/ aggs)触发的输出分区的数量,执行器内核不足(我相信启动时默认值为1),并且pyspark / sparkR的速度不快是因为JVM之外需要将串行对象与其他对象之间进行传输的独立进程
还要检查STORAGE TAB下的Spark UI,并确保所有分区都已100%缓存...如果仅一部分内存适合,那么您可能必须增加执行程序的内存,因为部分缓存的DF会导致大量检索问题未缓存的分区
pyspark --master yarn --executor-memory "gb"
很抱歉有很多建议... Spark有时是一个讨厌的小虫子,根本原因可能是一长串的问题
from pyspark.sql.functions import col, array
df = spark.createDataFrame([
(["1, 2, 3"]),
(["4, 5, 6"]),
(["7, 8, 9"])
], ["string_array"])
df.select(array("string_array").alias("array_data")).printSchema()
df.select(array("string_array").alias("array_data")).show()
root
|-- array_data: array (nullable = false)
| |-- element: string (containsNull = true)
+----------+
|array_data|
+----------+
| [1, 2, 3]|
| [4, 5, 6]|
| [7, 8, 9]|
+----------+
jsonDF = spark.range(1).selectExpr("""
'{"myJSONValue" : [1, 2, 3]}' as jsonString""")
jsonDF.show(truncate=False)
jsonDF.printSchema()
jsonDF.select(array("jsonString").alias("json_array")).show(truncate=False)
jsonDF.select(array("jsonString").alias("json_array")).printSchema()
+---------------------------+
|jsonString |
+---------------------------+
|{"myJSONValue" : [1, 2, 3]}|
+---------------------------+
root
|-- jsonString: string (nullable = false)
+-----------------------------+
|json_array |
+-----------------------------+
|[{"myJSONValue" : [1, 2, 3]}]|
+-----------------------------+
root
|-- json_array: array (nullable = false)
| |-- element: string (containsNull = false)
答案 1 :(得分:0)
一般来说,这里有多个因素:
count
执行与SELECT COUNT(1) FROM table
等效的查询-这使Spark可以进行大刀阔斧的早期优化,从而避免获取计算父表不需要的任何数据。
但是,如果将数据标记为cached
,缓存might take precedence,则必须提取计划中存在的所有列。
Spark SQL使用MEMORY_AND_DISK
存储级别-分配和/或回收内存以及潜在的磁盘IO都很昂贵。
最终缓存不是免费的午餐-它需要昂贵且广泛的转换-默认情况下hence _AND_DISK
存储级别,以减少缓存逐出和重新计算的风险。
如果您假设最终数据仅包含少量行,则第一个组件是最有可能的罪魁祸首。