Отладка приложений Spark
Я пытаюсь отладить приложение Spark в кластере, используя мастер и несколько рабочих узлов. Мне удалось настроить мастер node и рабочие узлы с помощью автономного менеджера кластеров Spark. Я загрузил искровую папку двоичными файлами и использовал следующие команды для настройки рабочих и основных узлов. Эти команды выполняются из справочника искры.
для запуска мастера
./sbin/start-master.sh
для запуска рабочего node
./bin/spark-class org.apache.spark.deploy.worker.Worker master-URL
для отправки приложения
./sbin/spark-submit --class Application --master URL ~/app.jar
Теперь я хотел бы понять поток управления через исходный код Spark на рабочих узлах, когда я отправляю свое приложение (я просто хочу использовать один из приведенных примеров, которые используют reduce()). Я предполагаю, что должен установить Spark на Eclipse. Ссылка Eclipse на веб-сайте Apache Spark кажется сломанной. Я был бы признателен за некоторые рекомендации по настройке Spark и Eclipse, чтобы обеспечить возможность перехода на исходный код Spark на рабочих узлах.
Спасибо!
Ответы
Ответ 1
Важно различать отладку программы драйвера и отладку одного из исполнителей. Они требуют различных параметров, переданных spark-submit
Для отладки драйвера вы можете добавить следующую команду spark-submit
. Затем установите ваш удаленный отладчик для подключения к node, на котором была запущена ваша программа драйверов.
--driver-java-options -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005
В этом примере был указан порт 5005, но вам может потребоваться настроить его, если что-то уже запущено на этом порту.
Соединение с исполнителем аналогично, добавьте следующие параметры в команду spark-submit
.
--num-executors 1 --executor-cores 1 --conf "spark.executor.extraJavaOptions=-agentlib:jdwp=transport=dt_socket,server=n,address=wm1b0-8ab.yourcomputer.org:5005,suspend=n"
Замените адрес локальным компьютером. (Это хорошая идея проверить, что вы можете получить к нему доступ из своего искрового кластера).
В этом случае запустите свой отладчик в режиме прослушивания, затем запустите свою искровую программу и дождитесь, когда исполнитель подключится к вашему отладчику. Важно установить количество исполнителей в 1 или несколько исполнителей, все будут пытаться подключиться к вашему отладчику, что может вызвать проблемы.
Эти примеры предназначены для работы с sparkMaster
, установленными как yarn-client
, хотя они также могут работать при работе в режиме мезо. Если вы используете режим yarn-cluster
, вам может потребоваться установить драйвер для прикрепления к вашему отладчику, а не прикреплять ваш отладчик к драйверу, так как вы не будете знать заранее, что node драйвер будет выполняться на.
Ответ 2
Вы можете запустить приложение Spark в локальном режиме, если вам просто нужно отлаживать логику ваших преобразований. Это можно запустить в среде IDE, и вы сможете отлаживать, как и любое другое приложение:
val conf = new SparkConf().setMaster("local").setAppName("myApp")
Вы, конечно, не распространяете проблему с этой настройкой. Распространение проблемы так же просто, как изменение мастера, чтобы указать на ваш кластер.
Ответ 3
Пробовали ли вы передавать удаленные параметры отладки на рабочий JVM?
Я думаю, что это что-то вроде spark.executor.extraJavaOptions.
Затем вы сможете подключиться к JVM удаленного рабочего стола из Eclipse.
Посмотрите, поможет ли это.
https://abrv8.wordpress.com/2014/10/06/debugging-java-spark-applications/
Ответ 4
Когда вы запускаете искровое приложение на пряжу, есть такой вариант:
YARN_OPTS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5455 $YARN_OPTS"
Вы можете добавить его в yarn-env.sh
, а удаленная отладка будет доступна через port 5455
.
Если вы используете искру в автономном режиме, я считаю, что это может помочь:
export SPARK_JAVA_OPTS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
Ответ 5
Я выполнил те же шаги, чтобы настроить искровой автономный кластер. Я смог отладить драйвер, мастер, работающий и исполнитель JVM.
Мастер и рабочий node настроены на машине класса сервера. Машина имеет 12 ядер процессора. Исходный код Spark -2.2.0 был клонирован из Spark Git Repo.
ШАГОВ:
1] Команда запуска мастер-JVM:
[email protected]:~/spark-2.2.0-bin-hadoop2.7/bin#
./spark-class -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8787 org.apache.spark.deploy.master.Master
Исходный класс script используется для запуска мастера вручную. Первыми аргументами являются JVM args, запускающие мастер в режиме отладки. JVM заблокирован и ожидает, что IDE сделает удаленное соединение.
Ниже приведены скриншоты, показывающие конфигурацию IDE для удаленной отладки:
2] Команда запуска JVM рабочего:
[email protected]:~/spark-2.2.0-bin-hadoop2.7/bin# ./spark-class -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8788 org.apache.spark.deploy.worker.Worker spark://10.71.220.34:7077
То же, что и главный, последний аргумент указывает адрес мастера искры. Отладочный порт для рабочего - 8788.
В рамках запуска рабочий регистрируется с мастером.
Скриншот
3] Основное приложение java с основным методом скомпилировано и завернуто в банку uber/fat. Это объясняется в тексте "Исследуя искру". В основном, куба Убер содержит все транзитивные зависимости.
Создан при запуске пакета mvn в следующем каталоге:
[email protected]:/home/customer/Documents/Texts/Spark/learning-spark-master# mvn package
Вышеописанное создает банку в папке. /target
снимок экрана ниже - это приложение java, которое будет отправлено в Spark Cluster:
4] Команда для отправки команды автономному кластеру
[email protected]:/home/customer/Documents/Texts/Spark/learning-spark-master# /home/customer/spark-2.2.0-bin-hadoop2.7/bin/spark-submit --master spark://10.71.220.34:7077
--conf "spark.executor.extraJavaOptions=-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8790"
--conf "spark.executor.extraClassPath=/home/customer/Documents/Texts/Spark/
learning-spark-master/target/java-0.0.2.jar"
--class com.oreilly.learningsparkexamples.java.BasicMapToDouble
--name "MapToDouble"
./target/java-0.0.2.jar
spark://10.71.220.34:7077 → Argument to the java program →
com.oreilly.learningsparkexamples.java.BasicMapToDouble
. Вышеприведенная команда принадлежит клиенту node, который запускает приложение с основным методом в нем. Однако преобразования выполняются в JVM удаленного исполнителя.
-
Параметры -conf важны. Они используются для настройки
исполнитель JVM. JVMS-исполнитель запускается во время выполнения с помощью JVM Worker.
. Первый параметр conf указывает, что JVM-исполнитель должен
запускаться в отладке режиме и приостановлено сразу. Он появляется на порту 8790.
. Второй параметр conf указывает, что путь класса исполнителя
должны содержать конкретные банки, которые
исполнителя. На распределенной установке эти банки необходимо перенести на
машина JVM Executor.
. Последний аргумент используется клиентским приложением для подключения к
искровой мастер.
Чтобы понять, как клиентское приложение подключается к кластеру Spark,
нам нужно отладить клиентское приложение и пройти его. Для этого нам нужно настроить его для запуска в режиме отладки.
Чтобы отладить клиент, нам нужно отредактировать script spark-submit следующим образом:
Содержание от spark-submit
exec "${SPARK_HOME}"/bin/spark-class -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8789 org.apache.spark.deploy.SparkSubmit "[email protected]"
5] После регистрации клиента рабочий запускает исполнитель во время выполнения в другом потоке.
Снимок экрана ниже показывает класс ExecutorRunner.scala
6] Теперь мы подключаемся к forked executor JVM с помощью IDE. Исполнитель JVM запускает функции преобразования в нашем представленном приложении.
JavaDoubleRDD result = rdd.mapToDouble( → ***Transformation function/lambda***
new DoubleFunction<Integer>() {
public double call(Integer x) {
double y = (double) x;
return y * y;
}
});
7] Функция преобразования выполняется, только когда действие "собирать" будет вызываться.
8] Снимок экрана ниже отображает представление Executor, когда функция mapToDouble вызывается параллельно по нескольким элементам списка. JVM-исполнитель выполняет функцию в 12 потоках, так как имеется 12 ядер. Поскольку количество ядер не было установлено в командной строке, рабочий JVM по умолчанию задает параметр: -cores = 12.
9] Снимок экрана с представленным клиентом кодом [maptodouble()]
работает в удаленной раздвоенной JVM-исполнителе.
10] После выполнения всех задач выйдет из строя JVM Executor. После выхода клиентского приложения рабочий node разблокируется и ждет следующего представления.
Ссылки
Я создал блог, в котором описываются шаги по отладке этих подсистем. Надеюсь, это поможет другим.
Блог, в котором описываются этапы:
https://sandeepmspark.blogspot.com/2018/01/spark-standalone-cluster-internals.html