Mahout spark-itemsimilarity saveAsTextFile最后阶段非常慢

时间:2015-11-05 17:32:22

标签: apache-spark mahout mahout-recommender collaborative-filtering

我在 HDP 2.2 群集上的YARN客户端模式中使用 Mahout 0.11.0 Spark 1.51 CLI。我的输入大约是325Mb,分为1000个部分文件。这是我调用的确切命令:

  <div class="form-group">
     <%= f.label :company %>
     <%= f.text_field  :company, class: "form-input" %>
  </div>

应用程序很好地哼唱直到最后阶段,$MAHOUT_HOME/bin/mahout spark-itemsimilarity --input unit-similarity-dump/bpc1 --output mahout-cooccurrence-output4 --maxPrefs 200 --maxSimilaritiesPerItem 100 --master yarn-client --sparkExecutorMem 10g -D:spark.yarn.executor.memoryOverhead=1024 -D:spark.executor.cores=5 -D:spark.executor.instances=50 -D:spark.yarn.am.memory=4g -D:spark.yarn.am.memoryOverhead=512 -D:spark.yarn.am.cores=2 -D:spark.driver.memory=20g -D:spark.yarn.driver.memoryOverhead=2048 -D:spark.driver.cores=4 -D:spark.driver.maxResultSize=10g -D:spark.yarn.queue=product -D:hdp.version=2.2.6.0-2800 被调用。此时,任务停滞不前,每个任务需要45分钟到一个小时才能成功。经过仔细检查,似乎每个任务都在读取 MapPartitionsRDD 的所有1000个分区,我认为,直觉上,这些分区必须是性能问题的根源。这些分区在所有执行程序中均匀分布,因此我认为每个任务都需要请求来自n-1执行者的所有分区,这些分区不是其直接父代。

优化此应用程序的最佳方法是什么?分区越少,请求的远程数据就越少?执行者较少,因此每个任务的本地化数据百分比都较高?尝试为RDD强制更高的复制因子?现在它似乎默认为存储级别:内存反序列化1x复制,100%缓存。

以下是舞台细节的屏幕截图:saveAsTextFile stage

提前感谢任何见解。

更新

我尝试仅使用具有多个核心(即任务)的1个执行程序,尽管所有RDD分区都存在于单个本地执行程序中,但性能仍然非常慢。我认为唯一的罪魁祸首是最终saveAsTextFile DAG中由reduceByKey造成的混乱。

第二次更新:

我也尝试过只使用1个输入分区,而我之前使用的是100或甚至1000.结果非常相似,并总结为here。为清楚起见,在这次运行中,我使用了一个带有5个内核的20g执行器。然而,这种方法确实导致聚合资源分配减少了大约一个数量级(以MB秒和vcore秒为单位)。这可能是由于先前运行中执行程序和线程的过度分配,并且暗示瓶颈可能不受计算限制。

1 个答案:

答案 0 :(得分:0)

不确定我是否遵循上述所有描述。有一个BiMap双向字典,可以将有序Mahout id中的列和行id转换为字符串外部id。这些数据结构在内存中,每种类型的id(行/列)总共有2个哈希映射。 reduceByKey适用于Mahout ID,因此只在输入和输出期间进行转换。这些数据结构被读入驱动程序然后广播到每个节点,每个节点只有一个副本,其中BiMap(实际上是BiDictionary)由执行者共享。

分区设置为&#34; auto&#34;默认情况下。在Mahout 11中哪一个应该是针对共生计算优化的值,这就是为什么事情会随着#34;而哼唱。

之后的最后一步在reduceByKey中取剩余矩阵(行键,向量)中的每个值,将key和vector元素的每个id转换回字符串,并将文本写入到文件中平行。

坦率地说,我发现文本文件的读写非常依赖于手动调整。我的主要经验是并行阅读,Spark在分区之前读取所有文件统计信息 - 全部。这是非常缓慢的,因为在阅读之前需要1000个文件并将它们连接到一个文件(尝试自己,他们可能已经解决了这个问题)。

听起来我觉得你需要一个更好的saveAsTextFile。使用您自己的分布式操作可以更好地手动调整saveAsTextFile,在基于您自己的参数对RDD进行一些重新分区后,foreach可以正常工作。请参阅此处的文档:http://spark.apache.org/docs/latest/programming-guide.html#printing-elements-of-an-rdd

如果要进行实验,请将TextDelimitedIndexedDatasetReaderWriter子类化为您自己的编写者Trait。 Mahout的mapBlock操作也可以使用。它将一行行传递给每个mapBlock,您可以使用BiMap编写这些行来转换ID。

很想听听Mahout用户名单上的任何结果。