2013-10-23 36 views
6

我對scala中的部署很陌生,我配置了sbt-assembly插件,運行良好。前幾天我加了hadoop,spark和一些其他的依賴關係,然後assembly任務變得非常慢(8到10分鐘),在此之前,它是< 30秒。 大部分時間用於生成組裝jar(jar需要幾秒鐘的時間才能增加1MB大小)。sbt程序集任務在添加一些依賴項後運行緩慢

我觀察到有很多合併衝突,這些衝突由first策略解決。這會影響組裝的速度嗎?

我已經玩過sbt的-Xmx選項(add -Xmx4096m),但它沒有幫助。我使用sbt 12.4和sbt-assembly。任何建議或指針用於優化此任務?

+2

你看過[Readme](https://github.com/sbt/sbt-assembly)嗎?它特別暗示您可能會更改'cacheUnzip'和'cacheOutput'設置。我會試試看。 –

+0

@ 0__我讀過它,但似乎所有的優化選項默認打開 – darkjh

+0

是的,但它們是_options_。可能值得嘗試切換每個緩存選項_off_以查看它是否有所作爲。 –

回答

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避免了從屬庫罐的解壓縮項的內容散列。它也會跳過由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秒。