Как я могу запустить оболочку Apache Spark удаленно?
У меня есть настройка Spark-кластера с одним мастером и тремя рабочими. У меня также есть Spark, установленный на виртуальной машине CentOS. Я пытаюсь запустить оболочку Spark из моей локальной виртуальной машины, которая будет подключаться к ведущему, и разрешить мне выполнить простой код Scala. Итак, вот команда, которую я запускаю на своей локальной виртуальной машине:
bin/spark-shell --master spark://spark01:7077
Среда запускается до точки, где я могу ввести код Scala. В нем говорится, что исполнители были предоставлены (x3 - по одному для каждого работника). Если я заглядываю в главный пользовательский интерфейс, я могу увидеть одно запущенное приложение, оболочку Spark. Все работники ALIVE, имеют 2/2 ядра, и выделили 512 МБ (из 5 ГБ) для приложения. Итак, я пытаюсь выполнить следующий Scala код:
sc.parallelize(1 to 100).count
К сожалению, команда не работает. Оболочка будет печатать одно и то же предупреждение бесконечно:
INFO SparkContext: Starting job: count at <console>:13
INFO DAGScheduler: Got job 0 (count at <console>:13) with 2 output partitions (allowLocal=false)
INFO DAGScheduler: Final stage: Stage 0(count at <console>:13) with 2 output partitions (allowLocal=false)
INFO DAGScheduler: Parents of final stage: List()
INFO DAGScheduler: Missing parents: List()
INFO DAGScheduler: Submitting Stage 0 (Parallel CollectionRDD[0] at parallelize at <console>:13), which has no missing parents
INFO DAGScheduler: Submitting 2 missing tasts from Stage 0 (ParallelCollectionRDD[0] at parallelize at <console>:13)
INFO TaskSchedulerImpl: Adding task set 0.0 with 2 tasks
WARN TaskSchedulerImpl: Initial job has not accepted any resources; check your cluster UI to ensure that workers are registered and have sufficient memory
WARN TaskSchedulerImpl: Initial job has not accepted any resources; check your cluster UI to ensure that workers are registered and have sufficient memory
WARN TaskSchedulerImpl: Initial job has not accepted any resources; check your cluster UI to ensure that workers are registered and have sufficient memory
После моего исследования проблемы я подтвердил, что основной URL-адрес, который я использую, идентичен тому, который находится в веб-интерфейсе. Я могу ping и ssh в обоих направлениях (кластер для локальной виртуальной машины и наоборот). Более того, я играл с параметром памяти исполнителя (как с увеличением, так и с уменьшением памяти) безрезультатно. Наконец, я попытался отключить брандмауэр (iptables) с обеих сторон, но я все равно получаю ту же ошибку. Я использую Spark 1.0.2.
TL; DR Можно ли удаленно запускать оболочку Apache Spark (и по сути отправлять приложения удаленно)? Если да, то что мне не хватает?
EDIT: я взглянул на рабочие журналы и обнаружил, что у рабочих возникли проблемы с поиском Spark:
ERROR org.apache.spark.deploy.worker.ExecutorRunner: Error running executor
java.io.IOException: Cannot run program "/usr/bin/spark-1.0.2/bin/compute-classpath.sh" (in directory "."): error=2, No such file or directory
...
Spark установлен в другом каталоге на моей локальной виртуальной машине, чем в кластере. Путь, который пытается найти рабочий, находится на моей локальной виртуальной машине. Есть ли способ указать этот путь? Или они должны быть одинаковыми во всем мире?
На данный момент я скорректировал свои каталоги, чтобы обойти эту ошибку. Теперь моя Spark Shell потерпит неудачу, прежде чем я получу возможность ввести команду count (Master removed our application: FAILED
). Все рабочие имеют ту же ошибку:
ERROR akka.remote.EndpointWriter: AssociationError [akka.tcp://[email protected]:7078] -> [akka.tcp://[email protected]:53633]:
Error [Association failed with [akka.tcp://[email protected]:53633]]
[akka.remote.EndpointAssociationException: Association failed with [akka.tcp://[email protected]:53633]
Caused by: akka.remote.transport.netty.NettyTransport$$anonfun$associate$1$$annon2: Connection refused: spark02/192.168.64.2:53633
Как я уже подозревал, у меня проблемы с сетью. На что я должен смотреть сейчас?
Ответы
Ответ 1
Я решаю эту проблему на моем искровом клиенте и искровом кластере.
Проверьте свою сеть, клиент A может ping кластер друг друга! Затем добавьте две строки config в ваш spark-env.sh на клиенте A.
сначала
export SPARK_MASTER_IP=172.100.102.156
export SPARK_JAR=/usr/spark-1.1.0-bin-hadoop2.4/lib/spark-assembly-1.1.0-hadoop2.4.0.jar
Второй
Проверьте свою искровую оболочку в режиме кластера!
Ответ 2
Эта проблема может быть вызвана сетевой конфигурацией. Похоже, что ошибка TaskSchedulerImpl: Initial job has not accepted any resources
может иметь немало причин (см. Также этот ответ):
- нехватка фактических ресурсов
- нарушение связи между мастером и работниками
- нарушение связи между мастером/работниками и драйвером.
Самый простой способ исключить первые возможности - запустить тест с помощью оболочки Spark, запущенной непосредственно на главном компьютере. Если это работает, то связь с кластером внутри самого кластера прекрасна, и проблема возникает из-за связи с хостом драйвера. Чтобы продолжить анализ проблемы, она помогает заглянуть в рабочие журналы, которые содержат записи типа
16/08/14 09:21:52 INFO ExecutorRunner: Launch command:
"/usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java"
...
"--driver-url" "spark://[email protected]:37752"
...
и проверьте, может ли рабочий установить соединение с IP-портом драйвера. Кроме общих проблем межсетевого экрана и переадресации портов, возможно, что драйвер привязан к неправильному сетевому интерфейсу. В этом случае вы можете экспортировать SPARK_LOCAL_IP
в драйвер перед запуском оболочки Spark для привязки к другому интерфейсу.
Некоторые дополнительные ссылки:
Ответ 3
Я бы предложил написать простую программу Scala или Java, создав проект в вашей среде IDE.
Скажем, вы создали проект под названием "simpleapp", который имеет такую структуру каталогов.
simpleapp
- src/main/java
- org.apache.spark.examples
-SimpleApp.java
- lib
- dependent.jars (you can put all dependent jars inside lib directory)
- target
- simpleapp.jar (after compiling your source)
Создайте объекты SparkConf и SparkContext в вашем "SimpleApp.java".
SparkConf conf = new SparkConf().setAppName(appName).setMaster("local[2]");
JavaSparkContext sc = new JavaSparkContext(conf);
Создайте JAR файл, используя следующую команду. Файл SimpleApp.class можно найти в папке "target/classes". cd в этот каталог.
jar cfve file.jar SimpleApp.class
Поместите этот JAR файл в ваш проект в целевой каталог. Этот JAR файл содержит зависимость вашего класса SimpleApp при отправке задания Spark.
Теперь идите в свою искровую директорию. Я использую spark-1.4.0-bin-hadoop2.6. Ваш cmd выглядит следующим образом.
spark-1.4.0-bin-hadoop2.6>
Запустите мастер и рабочий, используя следующие команды.
spark-1.4.0-bin-hadoop2.6> ./sbin/start-all.sh
Если это не сработает, запустите master и slaves отдельно.
spark-1.4.0-bin-hadoop2.6> ./sbin/start-master.sh
spark-1.4.0-bin-hadoop2.6> ./sbin/start-slaves.sh
Отправьте свою искровую программу, используя Spark Submit. Если у вас есть структура, как я объяснил, передайте этот аргумент в классе.
--class org.apache.spark.examples.SimpleApp
еще
--class SimpleApp
Наконец, отправьте свою искровую программу.
spark-1.4.0-bin-hadoop2.6>./bin/spark-submit --class SimpleApp --master local[2] /home/hadoopnod/Spark_Java/target/file.jar