我对scala中的部署有点新意,我配置了sbt-assembly
插件,一切运行良好。
前几天我添加了hadoop,spark和其他一些依赖项,然后assembly
任务变得非常慢(8到10分钟),在此之前,它是< 30秒。 大部分时间用于生成程序集jar(jar需要几秒钟才能生成1MB大小)。
我发现存在很多合并冲突,这些冲突由first
策略解决。这会影响装配速度吗?
我玩sbt的-Xmx选项(添加-Xmx4096m),但它没有帮助。
我正在使用sbt
12.4和sbt-assembly
。有关优化此任务的建议或指示吗?
答案 0 :(得分:6)
所以0__的评论是正确的:
您是否阅读过Readme。它明确建议您更改
cacheUnzip
和cacheOutput
设置。我试试看。
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(具有两个库依赖项的小型项目)。