Функция Numpy Rate на большом наборе данных, возвращающая нули

Путь классов Apache Spark построен динамически (для размещения кода пользователя для каждого приложения), что делает его уязвимым для таких проблем. @ user7337271 ответ правильный, но есть еще несколько проблем, в зависимости от используемого вами менеджера кластера («мастер»).

Во-первых, приложение Spark состоит из из этих компонентов (каждый из них является отдельным JVM, поэтому потенциально содержит разные классы в его пути к классам):

  1. Драйвер: это ваше приложение, создающее SparkSession (или SparkContext) и подключение к диспетчеру кластера для выполнения фактической работы
  2. Диспетчер кластеров: служит в качестве «точки входа» в кластер, которому поручено выделить исполнителей для каждого заявление. В Spark есть несколько разных типов: автономный, YARN и Mesos, которые мы опишем ниже.
  3. Исполнители: это процессы на узлах кластера, выполняющие фактическую работу (запуск Spark Задачи )

Соотношение между ними описано на этой диаграмме из обзора режима кластера Apache Spark :

Теперь - какие классы должны находиться в каждом из этих компонентов?

На это может ответить следующая диаграмма:

Давайте разберем это медленно:

  1. Spark Code - это библиотеки Spark. Они должны существовать в ALL трех компонентах, так как они включают клей, который позволяет Spark выполнять связь между ними. Кстати, авторы Spark внесли дизайнерское решение включить код для ВСЕХ компонентов во ВСЕХ компонентах (например, включить код, который должен запускаться только в Executor в драйвере), чтобы упростить это - так что «толстая банка Spark» (в версиях до 1.6 ) или «архив» (в версии 2.0, ниже) содержат необходимый код для всех компонентов и должны быть доступны во всех них.
  2. Код только для драйверов - это код пользователя, который не содержит ничего, что должно используется для исполнителей, то есть кода, который не используется при каких-либо преобразованиях в RDD / DataFrame / Dataset. Это необязательно должно быть отделено от распределенного кода пользователя, но это может быть.
  3. Распределенный код - это код пользователя, который скомпилирован с кодом драйвера, но также должен выполняться на исполнителях - все используемые фактические преобразования должны быть включены в эту банку.

Теперь, когда мы получили это прямо, как мы получаем, чтобы классы правильно загружались в каждом компоненте, и какими правилами они должны следовать?

  1. Spark Code : как утверждают предыдущие ответы, вы должны использовать те же версии Scala и Spark для всех компонентов. 1.1 В автономном режиме существует «ранее существовавшая» установка Spark, к которой могут подключаться приложения (драйверы). Это означает, что все драйверы должны использовать ту же версию Spark, что и на главном и исполнительном устройствах. 1.2 В YARN / Mesos каждое приложение может использовать другую версию Spark, но все компоненты одного и того же приложения должны использовать один и тот же. Это означает, что если вы использовали версию X для компиляции и упаковки вашего приложения-драйвера, вы должны предоставить такую ​​же версию при запуске SparkSession (например, через spark.yarn.archive или spark.yarn.jars параметры при использовании YARN). Банки / архив, которые вы предоставляете, должны включать все зависимости Spark (включая транзитивные зависимости), и они будут отправляться диспетчером кластера каждому исполнителю при запуске приложения.
  2. Код драйвера: это полностью до - драйвер код может быть отправлен в виде кучи банок или «толстой банки», если он включает все зависимости Spark + весь код пользователя
  3. Распределенный код: помимо присутствия в драйвере этот код должен быть отправлены исполнителям (опять же, вместе со всеми его транзитивными зависимостями). Это делается с использованием параметра spark.jars.

Подводя итог, рассмотрим предлагаемый подход к созданию и развертыванию Spark Application (в данном случае - с использованием YARN):

  • Создайте библиотеку с вашим распределенным кодом, упакуйте ее как «регулярную» банку (с файлом .pom, описывающим ее зависимости), так и как «живую банку» (со всеми включенными транзитными зависимостями).
  • Создайте приложение драйвера с зависимостями компиляции в вашей распределенной библиотеке кодов и Apache Spark (с определенной версией).
  • Пакет приложения драйвера в жирную банку, которая будет развернута в driver
  • Передайте правильную версию вашего распределенного кода в качестве значения параметра spark.jars при запуске SparkSession
  • Передайте местоположение файла архива (например, gzip), содержащего все банки в папке lib/ загруженных двоичных файлов Spark в качестве значения spark.yarn.archive

0
задан SarahD 28 March 2019 в 20:00
поделиться