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

问题描述 投票:7回答:2

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

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

我观察到有很多合并冲突,这些冲突由first策略解决。这会影响装配速度吗?

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

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

scala deployment sbt apache-spark sbt-assembly
2个回答
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秒。


0
投票

对于每个添加的库依赖项,程序集进程必须解压缩所有存档,然后将内容重新打包到胖jar中。

这个过程是I / O很重,如果你有防病毒软件,它会扫描每个文件。

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

此外,如果使用前面的〜运行assembly命令:

sbt ~assembly

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

这将组装时间从12秒减少到8秒(具有两个库依赖性的小项目)。

© www.soinside.com 2019 - 2024. All rights reserved.