spark and mill - создайте дополнительную задачу, которая создаст отфильтрованную сборку - PullRequest
1 голос
/ 23 февраля 2020

Я хочу создать задание mill, которое позволит мне разрабатывать и запускать задание Spark локально либо с помощью SparkSample.run, либо иметь полную толстую банку для локальных тестов. В какой-то момент я хотел бы отправить его как отфильтрованную сборку (т.е. без всех связанных со свечами библиотек, но со всеми проектными библиотеками) в кластер с работающим Spark Context.

В настоящее время я использую эту 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)
}

Для работы и создания полной жирной банки я сохраняю все как есть.

Для создания отфильтрованной сборки я комментирую строку ivyDeps в разделе "STANDALONE APP" и раскомментирую все, что ниже "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?

1 Ответ

0 голосов
/ 23 февраля 2020

Вы не можете переопределить определения в задачах. Простое локальное определение некоторых 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
  }
}

Чтобы создать JAR-файл Spark Cluster, выполните: mill SparkSample.assembly

Чтобы создать автономный JAR-прогон : mill SparkSample.standalone.assembly

Чтобы создать оба, просто запустите: mill __.assembly

...