PySpark позволяет запускать Python-код на Apache Spark - фреймворке на базе JVM.
Как это возможно?

Модель выполнения PySpark

Разделение между Python и JVM на высоком уровне заключается в следующем:

  • Обработкой данных занимаются процессы Python.
  • Сохранение и передача данных осуществляется процессами Spark JVM.

Программа-драйвер Python взаимодействует с локальной JVM, на которой запущен Spark, через Py4J.
Схема:
image

SparkContext и Py4J

Программа драйвера PySpark начинается с инициализации SparkContext; либо напрямую либо косвенно с помощью SparkSession:
image

Что на самом деле делает pyspark.SparkContext?

Давайте посмотрим на его официальную документацию: Основная точка входа в функциональность Spark. SparkContext представляет собой соединение с кластером Spark и может использоваться для создания RDD и широковещательных переменных на этом кластере.
Это немного вводит в заблуждение. Единственное, что действительно делает SparkContext в Python, - это подключается к сетевому порту на вашем компьютере и через этот порт связывается с объектом SparkContext в программе JVM (Spark). Затем ваш Python SparkContext сообщает Java SparkContext, что вы хотите сделать.
Представьте, что вы летите на своем частном самолете и говорите своему помощнику Джону Смиту, что хотите отправиться в Найроби, Кения. Джон Смит идет в кабину и говорит с пилотом (тоже Джоном Смитом). Затем пилот направляет самолет в Найроби. Они называются одинаково, но реальный полет выполняет только Джон Смит-пилот.
Аналогично, SparkContext в Java - это тот, кто на самом деле делает все крутые, тяжелые вещи Spark, такие как запуск заданий и получение результатов. Объект Python - это, по сути, телефон, через который вы говорите с объектом Java.
Аналогично, вся библиотека PySpark - это тонкий слой Python на тяжелом механизме Java.

Как PySpark общается с процессом Java?

PySpark может делать что-то внутри процесса JVM благодаря библиотеке Python под названием Py4J.
Py4J позволяет программам на Python:

  • открывать порт для прослушивания (по дефолту 25334)
  • запустить программу в JVM
  • заставить JVM-программу слушать другой сетевой порт (по дефолту 25333)
  • посылать команды процессу Java и прослушивать ответы

Главным минусом Py4J является скорость передачи данных между Python и Java, так как взаимодействие происходит через сокеты. Представьте, что вы загружаете в Python pandas датафрейм размером 5 ГБ, что-то с ним делаете, а затем отправляете в Spark. Этот датафрейм нужно будет сериализовать (в питоне это называется pickling) в поток байтов, передать через сокет в JVM, который затем десериализует его... А затем Spark должен будет снова сериализовать результаты, чтобы вернуть их в Python.


Published

Category

Theory

Contact