如何在Spark上执行大型计算

时间:2019-02-21 09:12:07

标签: scala apache-spark dataframe hadoop bigdata

我在Hive中有2个表:useritem,并且我试图为两个表之间的笛卡尔积(即交叉联接)计算每个表的2个特征之​​间的余弦相似度。 >

大约有20000 users和5000 items,导致100 million行计算。我在具有12个核心的Hive群集上使用Scala Spark运行计算。

代码有点像这样:

val pairs = userDf.crossJoin(itemDf).repartition(100)
val results = pairs.mapPartitions(computeScore)  // computeScore is a function to compute the similarity scores I need

由于Hadoop群集上的内存问题(GC分配失败),Spark作业将始终失败。如果我将计算量减少到1000万左右,它肯定会工作-不到15分钟。

如何在不增加硬件规格的情况下计算整个集合?如果这项工作需要更长的时间运行并且不会中途失败,我会很好。

2 个答案:

答案 0 :(得分:0)

如果您查看Spark文档,您会发现Spark使用不同的数据管理策略。用户可以通过spark配置文件中的配置或直接在代码或脚本中启用这些策略。

以下有关数据管理策略的文档: data management policies

“ MEMORY_AND_DISK”策略将对您有利,因为如果数据(RDD)不在内存中,则其余分区将存储在硬盘中。但是,如果您必须经常访问硬盘驱动器,则此策略可能会很慢。

答案 1 :(得分:0)

执行此操作的步骤很少: 1.交叉连接后检查预期的数据量,并将其除以200,因为spark.sql.shuffle.partitions默认为200。每个分区的原始数据必须大于1 GB。 2.计算每个行的大小,然后乘以另一个表的行数,就可以估算出粗略的体积。相较于CSV档案,该程序在Parquet中的运作会更好 3.需要根据总数据量/ 500 MB设置spark.sql.shuffle.partitions 4. spark.shuffle.minNumPartitionsToHighlyCompress需要设置得比Shuffle Partition少一点 5.根据两个文件/表的连接列对源实木复合地板数据进行存储桶化 6.提供高Spark Executor内存并考虑堆空间也管理Java堆内存