Как мне войти в свой собственный Spark JAR - PullRequest
0 голосов
/ 16 июня 2020

Scala / JVM noob здесь, который хочет больше узнать о ведении журнала, особенно при использовании Apache Spark.

Я написал библиотеку в Scala, которая зависит от группы библиотек Spark, вот мои зависимости:

import sbt._

object Dependencies {

  object Version {
    val spark = "2.2.0"
    val scalaTest = "3.0.0"
  }

  val deps = Seq(
    "org.apache.spark" %% "spark-core" % Version.spark,
    "org.scalatest" %% "scalatest" % Version.scalaTest,
    "org.apache.spark" %% "spark-hive" % Version.spark,
    "org.apache.spark" %% "spark-sql" % Version.spark,
    "com.holdenkarau" %% "spark-testing-base" % "2.2.0_0.8.0" % "test",
    "ch.qos.logback" % "logback-core" % "1.2.3",
    "ch.qos.logback" % "logback-classic" % "1.2.3",
    "com.typesafe.scala-logging" %% "scala-logging" % "3.8.0",
    "com.typesafe" % "config" % "1.3.2"
  )
  val exc = Seq(
    ExclusionRule("org.slf4j", "slf4j-log4j12")
  )
}

(по общему признанию, я скопировал много этого из другого места).

Я могу упаковать свой код как JAR, используя sbt package, который я затем могу вызвать из Spark, поместив JAR в ${SPARK_HOME}/jars. Это отлично работает.

Теперь я хочу реализовать ведение журнала из моего кода, поэтому я делаю это:

import com.typesafe.scalalogging.Logger
/*
 * stuff stuff stuff
 */
  val logger : Logger = Logger("name")
  logger.info("stuff")

однако, когда я пытаюсь вызвать свою библиотеку (что я делаю из Python, я не думаю, что это здесь актуально) Я получаю сообщение об ошибке:

py4j.protocol.Py4JJavaError: произошла ошибка при вызове z: com.company.package.class.function.
E: java .lang.NoClassDefFoundError: com / typesafe / scalalogging / Logger $

Очевидно, это потому, что библиотеки com.typesafe.scala-logging нет в моем JAR. Я знаю, что могу решить эту проблему, упаковав с помощью sbt assembly, но я не хочу этого делать, потому что он будет включать все другие зависимости и приведет к тому, что мой JAR будет огромным.

Есть ли способ выборочно включать библиотеки (com.typesafe.scala-logging в данном случае) в моем JAR? В качестве альтернативы, следует ли мне пытаться войти в систему другим методом, возможно, используя регистратор, который включен в Spark?


Благодаря pasha701 в комментариях я попытался упаковать свои зависимости, используя sbt assembly, а не sbt package.

import sbt._

object Dependencies {

  object Version {
    val spark = "2.2.0"
    val scalaTest = "3.0.0"
  }

  val deps = Seq(
    "org.apache.spark" %% "spark-core" % Version.spark % Provided,
    "org.scalatest" %% "scalatest" % Version.scalaTest,
    "org.apache.spark" %% "spark-hive" % Version.spark % Provided,
    "org.apache.spark" %% "spark-sql" % Version.spark % Provided,
    "com.holdenkarau" %% "spark-testing-base" % "2.2.0_0.8.0" % "test",
    "ch.qos.logback" % "logback-core" % "1.2.3",
    "ch.qos.logback" % "logback-classic" % "1.2.3",
    "com.typesafe.scala-logging" %% "scala-logging" % "3.8.0",
    "com.typesafe" % "config" % "1.3.2"
  )

  val exc = Seq(
    ExclusionRule("org.slf4j", "slf4j-log4j12")
  )

}

К сожалению, даже при указании зависимостей искры как Provided мой JAR изменился с 324 КБ до 12 МБ, поэтому я решил использовать вместо него println(). Вот мое сообщение о фиксации:

журнал с использованием println

Я выбрал опцию println, потому что она сохраняет размер JAR маленьким.

Я пробовал использовать com.typesafe.scalalogging.Logger, но мои тесты завершились неудачно с ошибкой:

java .lang.NoClassDefFoundError: com / typesafe / scalalogging / Logger

, потому что этого нет в Spark. Я попытался использовать сборку sbt вместо пакета sbt, но это привело к тому, что размер JAR-файла увеличился до go с 324 КБ до 12 МБ, даже если для зависимостей искры установлено значение «Предоставлено». 12M JAR не стоит компромисса только для использования scalaLogging, поэтому вместо этого используется println. . Мы будем очень признательны за любые советы по использованию log4j из Scala при написании библиотеки Spark.

1 Ответ

0 голосов
/ 16 июня 2020

Как вы сказали, 'sbt assembly' будет включать все зависимости в ваш jar.

Если вы хотите использовать определенные два варианта:

  1. Загрузите logback-core и logback-classi c и добавьте их в команду --jar spark2-submit
  2. Укажите указанные выше зависимости в параметре --packages spark2-submit
...