改善Spark ML ALS的计算性能

时间:2018-06-28 20:49:06

标签: performance apache-spark apache-spark-sql amazon-emr

我有一个火花工作,它在隐式反馈等级矩阵上执行Alternating Least Squares (ALS)。我按如下方式创建ALS对象。

val als = new ALS()
  .setCheckpointInterval(5)
  .setRank(150)
  .setAlpha(30.0)
  .setMaxIter(25)
  .setRegParam(0.001)
  .setUserCol("userId")
  .setItemCol("itemId")
  .setRatingCol("rating")
  .setImplicitPrefs(true)
  .setIntermediateStorageLevel("MEMORY_ONLY")
  .setFinalStorageLevel("MEMORY_ONLY")

将创建评级矩阵,并将其用于拟合ALS模型,如下所示。

val ratingsSchema = StructType(Array(
  StructField("userId", IntegerType, nullable = true), 
  StructField("itemId", IntegerType, nullable = true),
  StructField("rating", DoubleType, nullable = true)))

val ratings = spark
  .read
  .format("parquet")
  .schema(ratingsSchema)
  .load("/ratings")
  .cache()

val model = als.fit(ratings)

ratings DataFrame中大约有1.5亿个唯一用户和100万个项目,其中有大约8.5亿行。

基于上述数字,满载时,额定DataFrame应在内存中占据约20 GB的空间。 userFactors数据帧将为150 MM x 150倍= 180 GB(大约)。 itemFactors数据框应仅为1.2GB。

完成这项工作需要很长时间(超过15小时)。我的群集规格如下。

Provider: AWS EMR version 5.14.0
Spark version: 2.3.0
Cluster:
  1 MASTER node: m4.xlarge (8 cores, 16GB mem, 32GB storage)
  2 CORE nodes: i3.xlarge (4 cores, 30GB mem, 950 GB storage)
  20 TASK nodes: r4.4xlarge (16 cores, 122GB mem, 32 GB storage)
  Total TASK cores = 320
  Total TASK memory: 2440 GB

根据上述数字,所有DF都应轻松放入内存中(如果需要,还可以使用TB + HDFS)。

作业配置:

--executor-memory 102g 
--num-executors 20 
--executor-cores 15

我可以看到有20个执行程序正在运行(还有一个驱动程序)。我尝试过缓存DF,也没有缓存。

如果可能,如何调整系统以使其运行更快?

有人对ALS job有见识吗?它会产生很多改组吗?我们如何才能最大程度地减少混洗?

评分矩阵采用parquet格式,其中200个文件存储在S3的存储桶中。

如果我有很多小型实例(例如50个),还是应该得到几个(例如5个)非常大的实例(如r4.16xlarge(64核,488GB内存)),效果会更好?

0 个答案:

没有答案