Я использую набор данных MovieLens в Apache Pyspark. Чтобы поместить данные в Spark DataFrames, я использовал два метода:
spark.read.load()
-> Работает нормальноdataframeList[table] = spark.read.format("jdbc"). \
options(
url = 'jdbc:postgresql://localhost:5432/movielens_dataset',
dbtable = table,
user = 'postgres',
password = 'postgres',
driver = 'org.postgresql.Driver').\
load()
Этот код находится в for loop для чтения 6 таблиц.
Этот метод не работает, когда я вызываю show(5) для большого df. Он сталкивается с
ERROR Executor: Exception in task 0.0 in stage 1.0 (TID 1)
java.lang.OutOfMemoryError: Java heap space
Я попытался увеличить память драйвера и установить ее на 4/5/6 г, но это привело к сбою и выключению Chrome.
sparkConf.setAppName("My app")
.set("spark.jars", "postgresql-42.5.0.jar")
.set("spark.driver.memory", "6g")
spark = SparkSession.builder.config(conf=sparkConf).getOrCreate()
Я запускаю этот код в ноутбуке Jupyter в Google Chrome, а на моем ноутбуке 8 ГБ ОЗУ. Я не могу понять, почему это не работает в этом случае, поскольку в обоих случаях они по сути являются DataFrames. Просто они создаются разными методами.
Может кто-нибудь объяснить, почему это происходит, а также, как я могу решить эту проблему? Может ли кто-нибудь также порекомендовать хороший ресурс для понимания переменных конфигурации Spark (ядро драйвера/исполнителя, память, memoryOverhead и т. д.) и того, как их настройка может помочь в различных ситуациях? Большое спасибо!
Именно, это было show(5). Как я могу показать только выборку данных? Кроме того, я буду использовать эти кадры данных для машинного обучения, поэтому не будет ли это вычисление проблемой из-за большого набора данных?
@AvaniJindal Мой ответ поможет вам решить вашу проблему?
@JonathanLam Я увлекся другой курсовой работой. Я, вероятно, вернусь на этой неделе! :) Спасибо за объяснение.
Когда вы используете JDBC для подключения внешней базы данных, в вашем случае это Postgresql, увеличение памяти драйвера не поможет решить вашу ошибку, поскольку выборка данных выполняется исполнителем. Ваша ошибка также показывает, что ошибка OOM пространства кучи Java возникает во время задачи 0.0 на этапе 1.0 в вашем исполнителе.
Судя по предоставленному вами коду и конфигурации, вы не настроили никакое свойство соединения, и все параметры используют значения по умолчанию. Поэтому, когда вы читаете большой набор данных из Postgresql, ваше приложение spark может использовать только один исполнитель для обработки этого действия. В этом случае, не зная, как настроить исполнителя, он может вызвать ошибку OOM при получении большого набора данных.
Когда мы используем JDBC в Spark, параллелизм является одной из наиболее важных частей для производительности вашего приложения Spark. Увеличение количества исполнителей — это лишь один из способов увеличить параллелизм, а также количество разделов. Рядом, значение batchsize, lowerBound и upperBound для повышения производительности и увеличения параллелизма.
Лучший способ понять конфигурацию Spark — просмотреть документы Spark: https://spark.apache.org/docs/latest/configuration.html , для частей JDBC вы можете проверить это: https:// spark.apache.org/docs/latest/sql-data-sources-jdbc.html. Кроме того, я рекомендую вам посмотреть этот пост, так как это хорошее введение в оптимизацию искры при чтении JDBC.
Не существует стандартного решения или параметров, которые подходят и оптимизируются в другом случае, поскольку на производительность будут влиять база данных, конструкция JDBC, сеть, диск, который использует база данных, и т. д. Лучший способ найти подходящие параметры — методом проб и ошибок.
Мне удалось заставить работать «чтение из большой базы данных в Spark». Но теперь я сталкиваюсь с накладными расходами исполнителя OOM/GC на более поздних этапах при обучении с использованием ALS.
Если ваш завершенный набор данных достаточно велик, его нельзя будет загрузить в память при вызове .show(). Может быть, попробовать и просто показать образец данных, а не все это. На самом деле ничего не произойдет с точки зрения загрузки фрейма данных, пока вы не вызовете что-то, связанное с ним, например. .Показать(). Вот почему это может работать без .show()