添加一些依赖项后,sbt程序集任务运行缓慢

时间:2013-10-23 13:48:42

标签: scala deployment sbt apache-spark sbt-assembly

我对scala中的部署有点新意,我配置了sbt-assembly插件,一切运行良好。

前几天我添加了hadoop,spark和其他一些依赖项,然后assembly任务变得非常慢(8到10分钟),在此之前,它是< 30秒。 大部分时间用于生成程序集jar(jar需要几秒钟才能生成1MB大小)。

我发现存在很多合并冲突,这些冲突由first策略解决。这会影响装配速度吗?

我玩sbt的-Xmx选项(添加-Xmx4096m),但它没有帮助。

我正在使用sbt 12.4和sbt-assembly。有关优化此任务的建议或指示吗?

2 个答案:

答案 0 :(得分:6)

所以0__的评论是正确的:

  

您是否阅读过Readme。它明确建议您更改cacheUnzipcacheOutput设置。我试试看。

cacheUnzip是一项优化功能,但cacheOutput并非如此。 cacheOutput的目的是让您在源未更改时获得相同的jar。对于某些人来说,输出罐子不必要地改变是非常重要的。需要注意的是,它检查所有* .class文件的SHA-1哈希值。自述文件说:

  

如果有大量的类文件,这可能需要很长时间

据我所知,合并策略的解压缩和应用需要大约一两分钟,但SHA-1的检查似乎需要永远。这里关闭了输出缓存的assembly.sbt

import AssemblyKeys._ // put this at the top of the file

assemblySettings

mergeStrategy in assembly <<= (mergeStrategy in assembly) { (old) =>  {
    case PathList("javax", "servlet", xs @ _*)         => MergeStrategy.first
    case PathList("org", "apache", "commons", xs @ _*) => MergeStrategy.first // commons-beanutils-core-1.8.0.jar vs commons-beanutils-1.7.0.jar
    case PathList("com", "esotericsoftware", "minlog", xs @ _*) => MergeStrategy.first // kryo-2.21.jar vs minlog-1.2.jar
    case "about.html"                                  => MergeStrategy.rename
    case x => old(x)
  }
}

assemblyCacheOutput in assembly := false

组装在清洁后58秒内完成,第二次运行没有清洁需要15秒。虽然有些跑步也需要200多秒。

查看来源,我可能会优化cacheOutput,但是现在,关闭它应该会使装配更快。

修改

我已根据此问题添加了#96 Performance degradation when adding library dependencies,并在sbt-assembly 0.10.1为sbt 0.13添加了一些修正。

  

sbt-assembly 0.10.1避免了依赖库jar的解压缩项的内容散列。它还跳过sbt完成的jar缓存,因为sbt-assembly已经缓存了输出。

     

这些更改使装配任务运行更加一致。使用deps-heavy spark作为样本项目,在一个小的源更改后,组装任务运行了15次。 sbt-assembly 0.10.0需要19 +/- 157秒(大多数在20秒内,但是运行时间超过150+秒26%)。另一方面,sbt-assembly 0.10.1耗时16 +/- 1秒。

答案 1 :(得分:0)

对于每个添加的库依赖项,组装过程都必须解压缩所有档案,然后将内容重新打包到一个胖的jar中。

此过程的I / O繁重,如果您有防病毒软件,它将扫描每个文件。

对我有用的是将项目目录添加为防病毒设置中的排除的文件夹,这将汇编时间从60秒更改为12秒。

此外,如果在前面带有〜的情况下运行汇编命令,则:

sbt ~assembly

然后sbt将等待项目中的源更改,然后执行打包而无需重新加载JVM。

这将汇编时间从12s减少到8s(具有两个库依赖项的小型项目)。