#java #scala #apache-spark
#java #scala #apache-spark
Вопрос:
У меня есть действительно большие данные, доступные только для чтения, которые я хочу, чтобы все исполнители на одном узле использовали. Возможно ли это в Spark. Я знаю, вы можете передавать переменные, но можете ли вы передавать действительно большие массивы. Под капотом ли он разделяет данные между исполнителями на одном узле? Как это позволяет обмениваться данными между JVM исполнителей, работающих на одном узле?
Комментарии:
1. Как данные привязаны к исполнителю? Не могли бы вы описать проблему, которую вы пытаетесь решить?
2. В принципе, у меня есть данные только для чтения, которые составляют около 6 ГБ. Эти данные должны время от времени считываться каждым исполнителем, поскольку это своего рода таблица поиска. Каждый исполнитель должен иметь доступ ко всей справочной таблице. Я не хочу выделять столько памяти каждому исполнителю. Я хочу, чтобы эта память была разделена между исполнителями, работающими на одном узле, чтобы я мог обойтись без предоставления небольшого объема памяти каждому исполнителю.
3. Похоже, для этого вы могли бы использовать какую-нибудь локальную службу. Например. Загрузите эти данные в локальный Redis (или аналогичную базу данных / кэш в памяти) и используйте одноэлементный объект JVM из задания Spark для обращения к локальному экземпляру. Вам также понадобится служба управления, которая выполняет обновление. Я не думаю, что существует готовое решение Spark для достижения того, чего вы хотите.
4. Как насчет широковещательных переменных. Как они работают? Разве они также не являются общими для исполнителей на одном узле?
5. Широковещательные переменные позволяют обмениваться данными между задачами, выполняемыми на одной и той же виртуальной машине-исполнителе, поэтому данные необходимо загружать только один раз для каждого исполнителя.
Ответ №1:
Да, вы могли бы использовать широковещательные переменные, если учесть, что ваши данные доступны только для чтения (неизменяемые). широковещательная переменная должна удовлетворять следующим свойствам.
- Поместиться в памяти
- Неизменяемый
- Распространяется по кластеру
Итак, здесь единственным условием является то, что ваши данные должны умещаться в памяти на одном узле. Это означает, что данные не должны быть какими-либо сверхбольшими или выходить за пределы памяти, например, массивной таблицы.
Каждый исполнитель получает копию широковещательной переменной, и все задачи в этом конкретном исполнителе считывают / используют эти данные. Это похоже на отправку больших данных, доступных только для чтения, на все рабочие узлы в кластере. т. Е. отправка каждому работнику только один раз, а не с каждой задачей, и исполнители (это задачи) считывают данные.
Комментарии:
1. @pythonic спросил, как «обмениваться данными между JVM».
2. @LostInOverflow Я считаю, что вопрос создает некоторую путаницу. В OP используется неправильная формулировка. 2 исполнителя ! = 2 JVM приложения
3. Хорошо, да. ответ на совместное использование JVM заключается в том, что Apache Spark — это платформа распределенной обработки данных. Итак, здесь вы не можете совместно использовать задания / приложения / tasks или RDD. Единственный способ совместного использования данных возможен через постоянное хранилище, такое как HDFS. Apache Ignite, фреймворк, который предоставляет абстракцию поверх RDD под названием IgniteRDD, представляет собой реализацию встроенных API Spark RDD и DataFrame, которые разделяют состояние RDD между другими заданиями, приложениями и рабочими.
4. @eliasah Я думаю, вы имеете в виду 2 потока исполнителя! = 2 JVM приложения?
5. Как упоминалось ранее, мы не можем обмениваться данными между исполнителями, а исполнители выполняются на разных JVM. 2 потока исполнителя всегда выполняются на одной и той же JVM для приложения.
Ответ №2:
Я предполагаю, вы спрашиваете, как исполнители могут совместно использовать изменяемое состояние. если вам нужно только поделиться неизменяемыми данными, то вы можете просто обратиться к ответу @Stanislav .
если вам нужно изменяемое состояние между исполнителями, существует довольно много подходов:
- общая внешняя FS / DB
- потоковая передача с сохранением состояния databricks doc
- изменяемый распределенный общий кэш Ignite RDD