我正在运行一个火花作业,该作业处理大约2 TB的数据。处理过程涉及:
OrderBy
键df.filter(col("key").isin(keyset: _*) )
df.filter(!col("key").isin(keyset: _*) )
并将其写入实木复合地板。这是更大的数据集。原始avro数据约为2TB。处理大约需要1个小时。我想对其进行优化。我将在步骤3之后缓存数据帧,使用洗牌分区大小为6000。最小执行者= 1000,最大= 2000,执行者内存= 20 G,执行者核心=2。还有其他优化建议吗?左联接比过滤器性能更好吗?
答案 0 :(得分:4)
一切对我来说都不错。
如果您的数据集很小,那么isin
可以。
1)确保可以增加核心数量。执行者core = 5
不建议每个执行者使用5个以上的内核。这是基于一项研究的结果,任何具有5个以上并发线程的应用程序都会开始影响性能。
2)确保分区结构良好/统一。
示例(仅用于调试目的,不适用于生产):
import org.apache.spark.sql.functions.spark_partition_id
yourcacheddataframe.groupBy(spark_partition_id).count.show()
这将打印spark分区号和多少条记录 存在于每个分区中。以此为基础,如果您没有更多的并行性,则可以重新分区。
3)spark.dynamicAllocation.enabled
可能是另一种选择。
例如:
spark-submit --conf spark.dynamicAllocation.enabled=true --conf spark.dynamicAllocation.cachedExecutorIdleTimeout=100 --conf spark.shuffle.service.enabled=true
连同所有其他所需的道具...多数民众赞成在那份工作。如果在spark-default.conf中提供这些道具,它将应用于所有作业。
答案 1 :(得分:0)
spark.dynamicAllocation.enabled已启用
分区大小非常不均匀(根据输出镶木地板零件文件的大小),因为我正在执行orderBy键,并且某些键比其他键更频繁。
键集是一个很小的集(7个元素)
答案 2 :(得分:0)
除了已提及的内容外,根据您的要求和群集,还提供了一些建议:
df.withColumn("in_keyset", when( col('key').isin(keyset), lit(1)).otherwise(lit(0)). \
write.partitionBy("in_keyset").parquet(...)
可能会加快操作速度,以防止读入数据+爆炸2倍。 partitionBy确保键集中的项与其他键不在同一个目录中。