Лучшая практика для запуска приложений Spark через веб-приложение?

Я хочу открыть приложения Spark для пользователей с помощью веб-приложения.

В принципе, пользователь может решить, какое действие он хочет запустить, и ввести несколько переменных, которые необходимо передать в искровое приложение. Например: Пользователь вводит несколько полей, а затем нажимает кнопку, которая выполняет следующие действия: "Запустите sparkApp1 с параметром min_x, max_x, min_y, max_y".

Приложение искры должно запускаться с параметрами, заданными пользователем. После завершения веб-приложения могут потребоваться для получения результатов (из hdfs или mongodb) и отображения их пользователю. Во время обработки веб-приложение должно отображать статус приложения Spark.

Мой вопрос:

  • Как веб-приложение может запустить приложение Spark? Возможно, он сможет запустить его из командной строки под капотом, но может быть лучший способ сделать это.
  • Как веб-приложение может получить доступ к текущему статусу приложения Spark? Извлекает ли статус из Spark WebUI REST API путь?

Я запускаю группу Spark 1.6.1 с YARN/Mesos (еще не уверен) и MongoDB.

Ответ 1

Очень простой ответ:

В принципе вы можете использовать класс SparkLauncher для запуска приложений Spark и добавления некоторых слушателей для отслеживания прогресса.

Однако вам может быть интересен сервер Livy, который является RESTful Sever для Spark. Насколько я знаю, Цеппелин использует Livy для отправки заданий и получения статуса.

Вы также можете использовать интерфейс Spark REST для проверки состояния, тогда информация будет более точной. Здесь есть пример, как отправить задание через REST API

У вас есть 3 варианта, ответ - проверка самостоятельно;) Это очень зависит от вашего проекта и требований. Оба основных варианта:

  • Интерфейс SparkLauncher + Spark REST
  • Ливийский сервер

Должно быть хорошо для вас, и вы должны просто проверить, что проще и лучше использовать в вашем проекте

Расширенный ответ

Вы можете использовать Spark из своего приложения по-разному, в зависимости от того, что вам нужно и что вы предпочитаете.

SparkLauncher

SparkLauncher - это класс из артефакта spark-launcher. Он используется для запуска уже подготовленных заданий Spark, как и от Spark Submit.

Типичное использование:

1) Создайте проект с помощью задания Spark и скопируйте файл JAR на все узлы 2) Из вашего клиентского приложения, то есть веб-приложения, создайте SparkLauncher, который указывает на подготовленный JAR файл

SparkAppHandle handle = new SparkLauncher()
    .setSparkHome(SPARK_HOME)
    .setJavaHome(JAVA_HOME)
    .setAppResource(pathToJARFile)
    .setMainClass(MainClassFromJarWithJob)
    .setMaster("MasterAddress
    .startApplication();
    // or: .launch().waitFor()

startApplication создает SparkAppHandle, который позволяет добавлять слушателей и останавливать приложение. Он также предоставляет возможность getAppId.

SparkLauncher следует использовать с API-интерфейсом Spark REST. Вы можете запросить http://driverNode:4040/api/v1/applications/*ResultFromGetAppId*/jobs, и у вас будет информация о текущем состоянии приложения.

API-интерфейс Spark REST

Существует также возможность отправлять задания Spark напрямую через API RESTful. Использование очень похоже на SparkLauncher, но это сделано в чистом RESTful пути.

Пример запроса - кредиты для этой статьи:

curl -X POST http://spark-master-host:6066/v1/submissions/create --header "Content-Type:application/json;charset=UTF-8" --data '{
  "action" : "CreateSubmissionRequest",
  "appArgs" : [ "myAppArgument1" ],
  "appResource" : "hdfs:///filepath/spark-job-1.0.jar",
  "clientSparkVersion" : "1.5.0",
  "environmentVariables" : {
    "SPARK_ENV_LOADED" : "1"
  },
  "mainClass" : "spark.ExampleJobInPreparedJar",
  "sparkProperties" : {
    "spark.jars" : "hdfs:///filepath/spark-job-1.0.jar",
    "spark.driver.supervise" : "false",
    "spark.app.name" : "ExampleJobInPreparedJar",
    "spark.eventLog.enabled": "true",
    "spark.submit.deployMode" : "cluster",
    "spark.master" : "spark://spark-cluster-ip:6066"
  }
}'

Эта команда отправит задание в класс ExampleJobInPreparedJar для кластера с данным Spark Master. В ответе у вас будет поле submissionId, которое будет полезно для проверки статуса приложения - просто вызовите другую услугу: curl http://spark-cluster-ip:6066/v1/submissions/status/submissionIdFromResponse. Что это, ничего более, чтобы закодировать

Сервер ливня REST и сервер Spark Job

Livy REST Server и Spark Job Server являются RESTful приложений, которые позволяют отправлять задания через веб-службу RESTful. Одно существенное различие между этими двумя и интерфейсом Spark REST заключается в том, что Livy и SJS не требуют, чтобы задания были подготовлены ранее и упакованы в JAR файл. Вы просто отправляете код, который будет выполнен в Spark.

Использование очень простое. Коды берутся из репозитория Livy, но с некоторыми сокращениями, чтобы улучшить удобочитаемость.

1) Случай 1: отправка задания, которое помещается на локальную машину

// creating client
LivyClient client = new LivyClientBuilder()
  .setURI(new URI(livyUrl))
  .build();

try {
  // sending and submitting JAR file
  client.uploadJar(new File(piJar)).get();
  // PiJob is a class that implements Livy Job
  double pi = client.submit(new PiJob(samples)).get();
} finally {
  client.stop(true);
}

2) Случай 2: создание и выполнение динамических заданий

// example in Python. Data contains code in Scala, that will be executed in Spark
data = {
  'code': textwrap.dedent("""\
    val NUM_SAMPLES = 100000;
    val count = sc.parallelize(1 to NUM_SAMPLES).map { i =>
      val x = Math.random();
      val y = Math.random();
      if (x*x + y*y < 1) 1 else 0
    }.reduce(_ + _);
    println(\"Pi is roughly \" + 4.0 * count / NUM_SAMPLES)
    """)
}

r = requests.post(statements_url, data=json.dumps(data), headers=headers)
pprint.pprint(r.json()) 

Как вы можете видеть, возможны как предварительно скомпилированные задания, так и специальные запросы к Spark.

Минус гидросферы

Другое приложение "Спарк как услуга". Mist очень прост и похож на Livy и Spark Job Server.

Использование очень похоже

1) Создать файл задания:

import io.hydrosphere.mist.MistJob

object MyCoolMistJob extends MistJob {
    def doStuff(parameters: Map[String, Any]): Map[String, Any] = {
        val rdd = context.parallelize()
        ...
        return result.asInstance[Map[String, Any]]
    }
} 

2) Загрузите файл задания в JAR 3) Отправить запрос туман:

curl --header "Content-Type: application/json" -X POST http://mist_http_host:mist_http_port/jobs --data '{"path": "/path_to_jar/mist_examples.jar", "className": "SimpleContext$", "parameters": {"digits": [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]}, "namespace": "foo"}'

Одна сильная вещь, которую я могу видеть в Mist, заключается в том, что она имеет встроенную поддержку для потоковых заданий через MQTT,

Apache Toree

Apache Toree был создан для обеспечения легкой интерактивной аналитики для Spark. Он не требует создания JAR. Он работает через протокол IPython, но поддерживается не только Python.

В настоящее время документация сосредоточена на поддержке ноутбуков Jupyter, но также существует API REST-стиля.

Сравнение и выводы

Я перечисл несколько вариантов:

  • SparkLauncher
  • API-интерфейс Spark REST
  • Сервер ливня REST и сервер Spark Job
  • Гидросферный туман
  • Apache Toree

Все они хороши для разных случаев использования. Я могу выделить несколько категорий:

  • Инструменты, требующие JAR файлов с заданием: Spark Launcher, Spark REST API
  • Инструменты для интерактивных и предварительно упакованных заданий: Livy, SJS, Mist
  • Инструменты, ориентированные на интерактивные аналитики: Toree (однако может быть некоторая поддержка предварительно упакованных заданий, в настоящее время документация не публикуется)

SparkLauncher очень прост и является частью проекта Spark. Вы записываете конфигурацию заданий в виде простого кода, поэтому его легче создавать, чем объекты JSON.

Для полного представления в стиле RESTful рассмотрите API-интерфейс Spark REST, Livy, SJS и Mist. Три из них - это стабильные проекты, которые имеют некоторые производственные варианты использования. REST API также требует, чтобы задания были предварительно упакованы, а Livy и SJS - нет. Однако помните, что Spark REST API по умолчанию используется в каждом дистрибутиве Spark, а Livy/SJS - нет. Я не очень разбираюсь в Mist, но через некоторое время - это должен быть очень хороший инструмент для интеграции всех типов заданий Spark.

Toree фокусируется на интерактивных заданиях. Он все еще находится в инкубации, но даже сейчас вы можете проверить его возможности.

Зачем использовать пользовательскую дополнительную службу REST при наличии встроенного REST API? SaaS, как и Livy, является одной точкой входа в Spark. Он управляет контекстом Spark и находится только на одном node, чем в другом месте, кроме кластера. Они также позволяют интерактивную аналитику. Apache Zeppelin использует Livy для отправки кода пользователя в Spark

Ответ 2

Вот пример SparkLauncher T.Gawęda упоминается:

SparkAppHandle handle = new SparkLauncher()
    .setSparkHome(SPARK_HOME)
    .setJavaHome(JAVA_HOME)
    .setAppResource(SPARK_JOB_JAR_PATH)
    .setMainClass(SPARK_JOB_MAIN_CLASS)
    .addAppArgs("arg1", "arg2")
    .setMaster("yarn-cluster")
    .setConf("spark.dynamicAllocation.enabled", "true")
    .startApplication();

Здесь вы можете найти пример веб-приложения java с заданием Spark, объединенным в один проект. Через SparkLauncher вы можете получить SparkAppHandle, который вы можете использовать для получения информации о статусе работы. Если вам нужен статус прогресса, вы можете использовать Spark rest-api:

http://driverHost:4040/api/v1/applications/[app-id]/jobs

Единственная зависимость, которая вам понадобится для SparkLauncher:

<dependency>
    <groupId>org.apache.spark</groupId>
    <artifactId>spark-launcher_2.10</artifactId>
    <version>2.0.1</version>
</dependency>

Ответ 3

Вы можете использовать PredictionIO PredictionIO, сервер машинного обучения для разработчиков и инженеров ML.   https://github.com/apache/predictionio