spark and mill - 创建一个额外的任务来创建一个过滤的程序集
spark and mill - create an additional task that creates a filtered assembly
我想构建一个 mill
作业,允许我通过 SparkSample.run
在本地开发和 运行 一个 Spark 作业,或者有一个完整的 fat jar 用于本地测试。
在某个时间点,我想将它作为过滤后的程序集(即没有所有 spark 相关库,但包含所有项目库)发送到具有 运行ning Spark 上下文的集群。
我目前使用这个build.sc
import mill._, scalalib._
import mill.modules.Assembly
object SparkSample extends ScalaModule {
def scalaVersion = "2.12.10"
def scalacOptions =
Seq("-encoding", "utf-8", "-explaintypes", "-feature", "-deprecation")
def ivySparkDeps = Agg(
ivy"org.apache.spark::spark-sql:2.4.5"
.exclude("org.slf4j" -> "slf4j-log4j12"),
ivy"org.slf4j:slf4j-api:1.7.16",
ivy"org.slf4j:slf4j-log4j12:1.7.16"
)
def ivyBaseDeps = Agg(
ivy"com.lihaoyi::upickle:0.9.7"
)
// STANDALONE APP
def ivyDeps = ivyBaseDeps ++ ivySparkDeps
// REMOTE SPARK CLUSTER
// def ivyDeps = ivyBaseDeps
// def compileIvyDeps = ivySparkDeps
// def assemblyRules =
// Assembly.defaultRules ++
// Seq(
// "scala/.*",
// "org.slf4j.*",
// "org.apache.log4j.*"
// ).map(Assembly.Rule.ExcludePattern.apply)
}
为了 运行构建一个完整的 fat jar,我保持原样。
为了创建过滤程序集,我在 "STANDALONE APP" 下注释 ivyDeps
行并取消注释 "REMOTE SPARK CLUSTER".
下的所有内容
我觉得为新任务编辑构建文件不是很优雅,所以我尝试添加一个单独的任务到build.sc
def assembly2 = T {
def ivyDeps = ivyBaseDeps
def compileIvyDeps = ivySparkDeps
def assemblyRules =
Assembly.defaultRules ++
Seq(
"scala/.*",
"org.slf4j.*",
"org.apache.log4j.*"
).map(Assembly.Rule.ExcludePattern.apply)
super.assembly
}
但是当我 运行 SparkSample.assembly2
它仍然得到一个完整的程序集而不是一个过滤的程序集。似乎覆盖 ivyDeps
等。阿尔。在任务中不起作用。
这在 mill
中可行吗?
您不能覆盖任务中的定义。仅在本地定义一些 ivyDeps
和 compileIvyDeps
不会神奇地使 super.assembly
使用它们。
当然,您可以通过查看 super.assembly
在 JavaModule
中的定义来创建该任务,但您最终会复制和调整更多目标(upstreamAssembly
、upstreamAssemblyClasspath
、transitiveLocalClasspath
等)并使您的构建文件难以阅读。
更好的方法是将较轻的依赖项和组装规则设置为默认值,并将独立 JAR 的创建移动到子模块中。
import mill._, scalalib._
import mill.modules.Assembly
object SparkSample extends ScalaModule { outer =>
def scalaVersion = "2.12.10"
def scalacOptions =
Seq("-encoding", "utf-8", "-explaintypes", "-feature", "-deprecation")
def ivySparkDeps = Agg(
ivy"org.apache.spark::spark-sql:2.4.5"
.exclude("org.slf4j" -> "slf4j-log4j12"),
ivy"org.slf4j:slf4j-api:1.7.16",
ivy"org.slf4j:slf4j-log4j12:1.7.16"
)
def ivyDeps = Agg(
ivy"com.lihaoyi::upickle:0.9.7"
)
def compileIvyDeps = ivySparkDeps
def assemblyRules =
Assembly.defaultRules ++
Seq(
"scala/.*",
"org.slf4j.*",
"org.apache.log4j.*"
).map(Assembly.Rule.ExcludePattern.apply)
object standalone extends ScalaModule {
def scalaVersion = outer.scalaVersion
def moduleDeps = Seq(outer)
def ivyDeps = outer.ivySparkDeps
}
}
创建 Spark 集群 JAR 运行:mill SparkSample.assembly
创建独立 JAR 运行:mill SparkSample.standalone.assembly
要创建两者,您只需 运行:mill __.assembly
我想构建一个 mill
作业,允许我通过 SparkSample.run
在本地开发和 运行 一个 Spark 作业,或者有一个完整的 fat jar 用于本地测试。
在某个时间点,我想将它作为过滤后的程序集(即没有所有 spark 相关库,但包含所有项目库)发送到具有 运行ning Spark 上下文的集群。
我目前使用这个build.sc
import mill._, scalalib._
import mill.modules.Assembly
object SparkSample extends ScalaModule {
def scalaVersion = "2.12.10"
def scalacOptions =
Seq("-encoding", "utf-8", "-explaintypes", "-feature", "-deprecation")
def ivySparkDeps = Agg(
ivy"org.apache.spark::spark-sql:2.4.5"
.exclude("org.slf4j" -> "slf4j-log4j12"),
ivy"org.slf4j:slf4j-api:1.7.16",
ivy"org.slf4j:slf4j-log4j12:1.7.16"
)
def ivyBaseDeps = Agg(
ivy"com.lihaoyi::upickle:0.9.7"
)
// STANDALONE APP
def ivyDeps = ivyBaseDeps ++ ivySparkDeps
// REMOTE SPARK CLUSTER
// def ivyDeps = ivyBaseDeps
// def compileIvyDeps = ivySparkDeps
// def assemblyRules =
// Assembly.defaultRules ++
// Seq(
// "scala/.*",
// "org.slf4j.*",
// "org.apache.log4j.*"
// ).map(Assembly.Rule.ExcludePattern.apply)
}
为了 运行构建一个完整的 fat jar,我保持原样。
为了创建过滤程序集,我在 "STANDALONE APP" 下注释 ivyDeps
行并取消注释 "REMOTE SPARK CLUSTER".
我觉得为新任务编辑构建文件不是很优雅,所以我尝试添加一个单独的任务到build.sc
def assembly2 = T {
def ivyDeps = ivyBaseDeps
def compileIvyDeps = ivySparkDeps
def assemblyRules =
Assembly.defaultRules ++
Seq(
"scala/.*",
"org.slf4j.*",
"org.apache.log4j.*"
).map(Assembly.Rule.ExcludePattern.apply)
super.assembly
}
但是当我 运行 SparkSample.assembly2
它仍然得到一个完整的程序集而不是一个过滤的程序集。似乎覆盖 ivyDeps
等。阿尔。在任务中不起作用。
这在 mill
中可行吗?
您不能覆盖任务中的定义。仅在本地定义一些 ivyDeps
和 compileIvyDeps
不会神奇地使 super.assembly
使用它们。
当然,您可以通过查看 super.assembly
在 JavaModule
中的定义来创建该任务,但您最终会复制和调整更多目标(upstreamAssembly
、upstreamAssemblyClasspath
、transitiveLocalClasspath
等)并使您的构建文件难以阅读。
更好的方法是将较轻的依赖项和组装规则设置为默认值,并将独立 JAR 的创建移动到子模块中。
import mill._, scalalib._
import mill.modules.Assembly
object SparkSample extends ScalaModule { outer =>
def scalaVersion = "2.12.10"
def scalacOptions =
Seq("-encoding", "utf-8", "-explaintypes", "-feature", "-deprecation")
def ivySparkDeps = Agg(
ivy"org.apache.spark::spark-sql:2.4.5"
.exclude("org.slf4j" -> "slf4j-log4j12"),
ivy"org.slf4j:slf4j-api:1.7.16",
ivy"org.slf4j:slf4j-log4j12:1.7.16"
)
def ivyDeps = Agg(
ivy"com.lihaoyi::upickle:0.9.7"
)
def compileIvyDeps = ivySparkDeps
def assemblyRules =
Assembly.defaultRules ++
Seq(
"scala/.*",
"org.slf4j.*",
"org.apache.log4j.*"
).map(Assembly.Rule.ExcludePattern.apply)
object standalone extends ScalaModule {
def scalaVersion = outer.scalaVersion
def moduleDeps = Seq(outer)
def ivyDeps = outer.ivySparkDeps
}
}
创建 Spark 集群 JAR 运行:mill SparkSample.assembly
创建独立 JAR 运行:mill SparkSample.standalone.assembly
要创建两者,您只需 运行:mill __.assembly