Разница между фреймом данных (в Spark 2.0 i.E DataSet[Row]) и RDD в Spark
мне просто интересно, в чем разница между RDD
и DataFrame
(Spark 2.0.0 DataFrame - это простой псевдоним типа для Dataset[Row]
) в Apache Spark?
можете ли вы конвертировать один в другой?
11 ответов
A DataFrame
хорошо определяется с помощью поиска google для "определения фрейма данных":
фрейм данных-это таблица или двумерная структура, подобная массиву, в в котором каждый столбец содержит измерения по одной переменной, а каждая строка содержит один случай.
Итак, a DataFrame
имеет дополнительные метаданные из-за его табличного формата, который позволяет Spark запускать определенные оптимизации в завершенном запросе.
An RDD
, С другой стороны, просто R esilient Distributed Dataset, который является больше черным ящиком данных, которые не могут быть оптимизированы как операции, которые могут быть выполнены против него, не так ограничены.
однако вы можете перейти от фрейма данных к RDD
через rdd
метод, и вы можете перейти от RDD
до DataFrame
(Если RDD находится в табличном формате) через toDF
метод
в общем рекомендуется используйте DataFrame
где это возможно из-за встроенной оптимизации запросов.
первое-это
DataFrame
складывалась изSchemaRDD
.
да.. преобразование между Dataframe
и RDD
вполне возможно.
Ниже приведены некоторые примеры фрагментов кода.
-
df.rdd
иRDD[Row]
Ниже приведены некоторые из вариантов создания таблицы данных.
1)
yourrddOffrow.toDF
преобразуетDataFrame
.-
2) с помощью
createDataFrame
контекста sqlval df = spark.createDataFrame(rddOfRow, schema)
где схема может быть из некоторых ниже опций как описано nice so post..
Из класса case scala и api отражения scalaimport org.apache.spark.sql.catalyst.ScalaReflection val schema = ScalaReflection.schemaFor[YourScalacaseClass].dataType.asInstanceOf[StructType]
или с помощью
Encoders
import org.apache.spark.sql.Encoders val mySchema = Encoders.product[MyCaseClass].schema
как описано схемой также может быть создан с помощью
StructType
иStructField
val schema = new StructType() .add(StructField("id", StringType, true)) .add(StructField("col1", DoubleType, true)) .add(StructField("col2", DoubleType, true)) etc...
на самом деле теперь есть 3 Apache Spark API..
RDD
API:
на
RDD
(Resilient Distributed Dataset) API был в Spark с тех пор выпуск 1.0.на
RDD
API предоставляет множество методов преобразования, таких какmap
(),filter
() иreduce
() для выполнения вычислений над данными. Каждый из этих методов получается новыйRDD
представление преобразованного данные. Однако эти методы просто определяют операции, которые должны быть выполнено и преобразования не выполняются до действия вызывается метод. Примерами методов действий являютсяcollect
() иsaveAsObjectFile
().
пример RDD:
rdd.filter(_.age > 21) // transformation
.map(_.last)// transformation
.saveAsObjectFile("under21.bin") // action
пример: фильтр по атрибуту с помощью RDD
rdd.filter(_.age > 21)
DataFrame
API
Spark 1.3 представила новый
DataFrame
API в рамках проекта Вольфрам инициатива, которая направлена на повышение производительности и масштабируемость искры. TheDataFrame
API вводит понятие схема для описания данных, позволяющая Spark управлять схемой и только передайте данные между узлы, гораздо более эффективным способом, чем использование Сериализации Java.на
DataFrame
API радикально отличается отRDD
API, потому что это это API для создания реляционной план запроса, что катализатор СПАРК оптимизатор может затем выполнить. API является естественным для разработчиков, которые знаком с планами построения запросов
пример стиля SQL:
df.filter("age > 21");
ограничения : Поскольку код ссылается на атрибуты данных по имени, компилятор не может поймать какие-либо ошибки. Если имена атрибутов неверны, то ошибка будет обнаружена только во время выполнения при создании плана запроса.
еще один недостаток с DataFrame
API заключается в том, что он очень ориентирован на scala, и хотя он поддерживает Java, поддержка ограничена.
например, при создании DataFrame
из существующего RDD
объектов Java оптимизатор Catalyst Spark не может вывести схему и предполагает, что любые объекты в фрейме данных реализуют scala.Product
интерфейс. Скала!--38--> работает из коробки, потому что они реализуют этот интерфейс.
Dataset
API
на
Dataset
API, выпущенный в качестве предварительного просмотра API в Spark 1.6, направлен на обеспечить лучшее из обоих миров; знакомый объектно-ориентированный стиль программирования и тип времени компиляции-безопасностьRDD
API, но с преимущества производительности оптимизатора запросов Catalyst. Набор данных также используйте такой же эффективный механизм хранения вне кучи какDataFrame
API-интерфейс.когда дело доходит до сериализации данных
Dataset
API имеет концепцию энкодеры которые переводят между представлениями JVM (объектами) и Внутренний двоичный формат Spark. Искра имеет встроенные датчики, которые очень продвинутый в том, что они генерируют байтовый код для взаимодействия с данные вне кучи и обеспечивают доступ по требованию к отдельным атрибутам без необходимости де-сериализации целого объекта. Spark пока нет предоставьте API для реализации пользовательских кодеров, но это планируется для будущего выпуска.кроме того,
Dataset
API предназначен для работы одинаково хорошо с в Java и Scala. При работе с объектами Java это важно что они полностью совместимы с бобами.
пример Dataset
API SQL стиль:
dataset.filter(_.age < 21);
оценки diff. между DataFrame
& DataSet
:
дальнейшее чтение... databricks статьи
RDD
основная абстракция Spark обеспечивает упругий распределенный набор данных (RDD), который представляет собой набор элементов, секционированных по узлам кластера, которые могут работать параллельно.
RDD особенности: -
распределенного сбора:
RDD использует операции MapReduce, которые широко используются для обработки и генерации больших наборов данных с параллельным, распределенным алгоритма на кластере. Это позволяет пользователям писать параллельные вычисления, используя набор операторов высокого уровня, не беспокоясь о распределении работы и отказоустойчивости.неизменяемые: RDDs состоит из коллекции записей, которые разделены. Раздел является базовой единицей параллелизма в RDD, и каждый раздел является одним логическим разделением данных, которое является неизменяемым и создается с помощью некоторых преобразований на существующих перекрытия.Неизменность помогает достичь согласованности в вычислениях.
отказоустойчивость: В случае потери некоторого раздела RDD мы можем воспроизвести преобразование на этом разделе в lineage для достижения того же вычисления, а не выполнять репликацию данных через несколько узлов.Эта характеристика самое большое преимущество RDD потому что она сохраняет много усилия в управлении данными и репликации и таким образом достигает более быстро вычисления.
ленивых вычислений: все преобразования в Spark ленивы, поскольку они не вычисляют свои результаты сразу. Вместо этого они просто запоминают преобразования, применяемые к некоторому базовому набору данных . Преобразования вычисляются только тогда, когда действие требует, чтобы результат был возвращен в программу драйвера.
функциональные преобразования: RDDs поддерживает два типа операций: преобразования, создающие новый набор данных из существующего, и действия, возвращающие значение программе драйвера после выполнения вычисления в наборе данных.
форматы обработки данных:
он может легко и эффективно обрабатывать данные, которые являются структурированным и неструктурированным данным.
-
поддерживаемые языки программирования:
API RDD доступен в Java, Scala, Питон и Р.--20-->
ограничения RDD: -
нет встроенного движка оптимизации: При работе со структурированными данными RDDs не может использовать преимущества передовых оптимизаторов Spark, включая Catalyst optimizer и Tungsten execution engine. Разработчикам необходимо оптимизировать каждый RDD на основе его атрибутов.
обработка структурированных данных: В отличие от Dataframe и datasets, RDDs не выводят схемы из полученных данных, и требует от пользователя указать его.
таблицы данных
Spark представил фреймы данных в выпуске Spark 1.3. Dataframe преодолевает ключевые проблемы, которые были у RDDs.
фрейм данных-это распределенная коллекция данных, организованная в именованные столбцы. Он концептуально эквивалентен таблице в реляционной базе данных или фрейму данных R / Python. Наряду с Dataframe, Spark также представила оптимизатор catalyst, который использует расширенные возможности программирования для создания расширяемого оптимизатора запросов.
Dataframe Особенности: -
распределенная коллекция объекта строки: Фрейм данных-это распределенная коллекция данных, организованная в именованные столбцы. Он концептуально эквивалентен таблице в реляционной базе данных, но с более богатой оптимизацией под капотом.
Обработка Данных: Обработка структурированные и неструктурированные форматы данных (Avro, CSV, elastic search и Cassandra) и системы хранения (HDFS, HIVE tables, MySQL и т. д.). Он может читать и писать из всех этих различных источников данных.
-
оптимизация с помощью Catalyst optimizer: Он питает как SQL-запросы, так и API DataFrame. Dataframe используйте Catalyst tree transformation framework в четыре фазы,
1.Analyzing a logical plan to resolve references 2.Logical plan optimization 3.Physical planning 4.Code generation to compile parts of the query to Java bytecode.
Hive Совместимость: С помощью Spark SQL, вы можете запускать немодифицированные запросы Hive на существующих складах Hive. Он повторно использует интерфейс Hive и MetaStore и дает вам полную совместимость с существующими данными Hive, запросами и UDFs.
Вольфрам: Вольфрам обеспечивает бэкэнд физического выполнения, который неявно управляет памятью и динамически генерирует байт-код для оценки выражения.
Языки Программирования поддерживается:
API Dataframe доступен в Java, Scala, Python и R.
Таблицы Данных Ограничений:-
- безопасность типа времени компиляции: Как обсуждалось, API Dataframe не поддерживает безопасность времени компиляции, которая ограничивает вас от манипулирования данными, когда структура не известна. Следующий пример работает во время компиляции. Однако при выполнении этого вы получите исключение среды выполнения код.
пример:
case class Person(name : String , age : Int)
val dataframe = sqlContect.read.json("people.json")
dataframe.filter("salary > 10000").show
=> throws Exception : cannot resolve 'salary' given input age , name
это особенно сложно, когда вы работаете с несколькими шагами преобразования и агрегации.
- невозможно работать с объектом домена (потерянный объект домена): Как только вы преобразовали объект домена в dataframe, вы не можете восстановить его из него. В следующем примере, как только мы создадим personDF из personRDD, мы не будем восстанавливать исходный RDD класса Person (RDD[человек]).
пример:
case class Person(name : String , age : Int)
val personRDD = sc.makeRDD(Seq(Person("A",10),Person("B",20)))
val personDF = sqlContect.createDataframe(personRDD)
personDF.rdd // returns RDD[Row] , does not returns RDD[Person]
API наборов данных
Dataset API-это расширение для фреймов данных, которое обеспечивает типобезопасный, объектно-ориентированный интерфейс программирования. Это строго типизированная неизменяемая коллекция объектов, сопоставленных с реляционной схемой.
в основе набора данных API-это новая концепция, называемая кодировщиком, которая отвечает за преобразование между объектами JVM и табличным представлением. Табличное представление хранится в двоичном формате Spark internal Tungsten, что позволяет выполнять операции с сериализованными данными и улучшает использование памяти. Spark 1.6 поставляется с поддержкой автоматического создания кодеров для самых разных типов, включая примитивные типы (например, String, Integer, Long), классы Scala case и Java Beans.
Особенности Набора Данных: -
обеспечивает лучшее из RDD и Dataframe: RDD (функциональное программирование, type safe), DataFrame (реляционная модель, оптимизация запросов , выполнение вольфрама, сортировка и перетасовка)
шифраторы: С помощью кодировщиков легко преобразовать любой объект JVM в набор данных, что позволяет пользователям работать как со структурированными, так и с неструктурированными данными в отличие от Dataframe.
поддерживаемые языки программирования: API наборов данных в настоящее время доступен только в Scala и Java. Python и R в настоящее время не поддерживаются в версии 1.6. Поддержка Python предназначен для версии 2.0.
Тип Безопасности: API наборов данных обеспечивает безопасность времени компиляции, которая недоступна в кадрах данных. В приведенном ниже примере мы видим, как Dataset может работать с объектами домена с лямбда-функциями компиляции.
пример:
case class Person(name : String , age : Int)
val personRDD = sc.makeRDD(Seq(Person("A",10),Person("B",20)))
val personDF = sqlContect.createDataframe(personRDD)
val ds:Dataset[Person] = personDF.as[Person]
ds.filter(p => p.age > 25)
ds.filter(p => p.salary > 25)
// error : value salary is not a member of person
ds.rdd // returns RDD[Person]
- совместимость: наборы данных позволяет чтобы легко конвертировать существующие Rdds и Dataframes в наборы данных без шаблонного кода.
ограничение API наборов данных: -
- требуется тип литья в строку: Запрос данных из наборов данных в настоящее время требует указания полей в классе в виде строки. После того, как мы запросили данные, мы вынуждены привести столбец к требуемому типу данных. С другой стороны, если мы используем операцию map для наборов данных, он не будет использовать Catalyst оптимизатор.
пример:
ds.select(col("name").as[String], $"age".as[Int]).collect()
нет поддержки Python и R: начиная с версии 1.6, наборы данных поддерживают только Scala и Java. Поддержка Python будет представлена в Spark 2.0.
API наборов данных приносит несколько преимуществ по сравнению с существующими API RDD и Dataframe с лучшей безопасностью типов и функциональным программированием.С проблемой требований к кастингу типов в API, вы все равно не требуете безопасности типа и сделаете свой код хрупкий.
все(RDD, DataFrame и DataSet) в одном изображении
RDD
RDD
отказоустойчивое собрание элементов которые можно эксплуатировать дальше параллельно.
таблицы данных
DataFrame
- Это набор данных, организованный в именованные столбцы. Это концептуальный эквивалент таблицы в реляционной базе данных или данных рама в R / Python,но с более богатой оптимизацией под капотом.
Dataset
Dataset
- это распределенный сбор данных. Dataset-это новый интерфейс, добавленный в Spark 1.6, который предоставляет преимущества RDDs (сильный печатать, способность использовать мощные функции lambda) с преимущества оптимизированного механизма выполнения Spark SQL.
Примечание:
набор данных строк (
Dataset[Row]
) в Scala/Java часто ссылаются как фреймы данных.
хорошее сравнение всех из них с фрагментом кода
Q: можете ли вы преобразовать один в другой, как RDD в DataFrame или наоборот?
да, оба возможно
1. RDD
to DataFrame
С .toDF()
val rowsRdd: RDD[Row] = sc.parallelize(
Seq(
Row("first", 2.0, 7.0),
Row("second", 3.5, 2.5),
Row("third", 7.0, 5.9)
)
)
val df = spark.createDataFrame(rowsRdd).toDF("id", "val1", "val2")
df.show()
+------+----+----+
| id|val1|val2|
+------+----+----+
| first| 2.0| 7.0|
|second| 3.5| 2.5|
| third| 7.0| 5.9|
+------+----+----+
дополнительно образом: преобразование объекта RDD в фрейм данных в Spark
2. DataFrame
/DataSet
to RDD
С .rdd()
метод
val rowsRdd: RDD[Row] = df.rdd() // DataFrame to RDD
просто RDD
является основным компонентом, но DataFrame
- это API, введенный в spark 1.30.
RDD
сбор разделов данных называется RDD
. Эти RDD
должно следовать нескольким свойствам, таким как:
- неизменяемый,
- Отказоустойчивость,
- распределение.
- больше.
здесь RDD
является структурированным или неструктурированный.
таблицы данных
DataFrame
- API, доступный в Scala, Java, Python и R. Он позволяет обрабатывать любой тип структурированных и полуструктурированных данных. Для определения DataFrame
коллекция распределенных данных организованы в именованные столбцы под названием DataFrame
. Вы можете легко оптимизировать RDDs
на DataFrame
.
Вы можете обрабатывать данные JSON, parquet data, hiveql одновременно с помощью DataFrame
.
val sampleRDD = sqlContext.jsonFile("hdfs://localhost:9000/jsondata.json")
val sample_DF = sampleRDD.toDF()
здесь Sample_DF рассматривать как DataFrame
. sampleRDD
is (raw data) называется RDD
.
большинство ответов являются правильными только хочу добавить один пункт здесь
в Spark 2.0 два API (DataFrame +DataSet) будут объединены в один API.
"объединение фрейма данных и набора данных: в Scala и Java фрейм данных и набор данных были унифицированы, т. е. фрейм данных-это просто псевдоним типа для набора данных строки. В Python и R, учитывая отсутствие безопасности типов, DataFrame является основным интерфейсом программирования."
наборы данных похожи на RDDs, однако, вместо использования сериализации Java или Kryo они используют специализированный кодировщик для сериализации объектов для обработки или передачи по сети.
Spark SQL поддерживает два разных метода преобразования существующих RDDs в наборы данных. Первый метод использует отражение для вывода схемы RDD, содержащей определенные типы объектов. Этот подход на основе отражения приводит к более сжатому коду и хорошо работает, когда вы уже знаете схему при написании Spark приложение.
второй метод создания наборов данных - программный интерфейс, который позволяет построить схему, а затем применить ее к существующему RDD. Хотя этот метод является более подробным, он позволяет создавать наборы данных для столбцов и их типы неизвестны до времени выполнения.
здесь вы можете найти RDD TOF data frame conversation answer
фрейм данных эквивалентен таблице в СУБД и может также управляться аналогично" собственным " распределенным коллекциям в RDDs. В отличие от RDDs, фреймы данных отслеживают схему и поддерживают различные реляционные операции, которые приводят к более оптимальному выполнению. Каждый объект DataFrame представляет логический план, но из-за их" ленивой "природы выполнение не происходит, пока пользователь не вызовет определенную"операцию вывода".
фрейм данных - это RDD объектов строк, каждый из которых представляет запись. Ля Dataframe также знает схему (т. е. поля данных) своих строк. В То Время Как Dataframes выглядят как обычные RDDs, внутренне они хранят данные более эффективно, используя преимущества своей схемы. Кроме того, они предоставляют новые операции, недоступные на RDDs, такие как возможность выполнения SQL-запросов. Фреймы данных могут быть созданы из внешних источников данных, из результатов запросов или из обычных RDDs.
ссылка: Zaharia M., et al. Learning Spark (O'Reilly, 2015)
несколько идей с точки зрения использования, RDD vs DataFrame:
- RDDs удивительны! как они дают нам возможность заниматься практически любые данные; неструктурированные, частично структурированные и структурированные данные. Поскольку данные часто не готовы к помещению в фрейм данных (даже JSON), RDDs можно использовать для предварительной обработки данных, чтобы они могли поместиться в фрейм данных. RDDs-это абстракция основных данных в Spark.
- не все преобразования, которые возможны на RDD возможны на фреймах данных, например, subtract () для RDD vs except () для DataFrame.
- поскольку фреймы данных похожи на реляционную таблицу, они следуют строгим правилам при использовании преобразований set/relational theory, например, если вы хотите объединить два фрейма данных, требование состоит в том, что оба dfs имеют одинаковое количество столбцов и связанных типов данных столбцов. Имена столбцов могут быть разными. Эти правила не применяются к RDDs. вот хороший учебник объяснения этих факты.
- есть повышение производительности при использовании фреймов данных, как другие уже объяснили подробно.
- используя фреймы данных, вам не нужно передавать произвольную функцию, как при программировании с помощью RDDs.
- вам нужен SQLContext/HiveContext для программирования фреймов данных, поскольку они лежат в области SparkSQL эко-системы spark, но для RDD вам нужен только SparkContext / JavaSparkContext, которые лежат в библиотеках Spark Core.
- вы можете создать df из RDD, если для него можно определить схему.
- вы также можете конвертировать df в rdd и rdd в df.
надеюсь, это поможет!
вы можете использовать RDD со структурированными и неструктурированными, где как Dataframe / Dataset может обрабатывать только структурированные и полуструктурированные данные (он имеет правильную схему)
A таблицы данных - это RDD, который имеет схему. Вы можете думать об этом как таблицы реляционной базы данных, в которой каждый столбец имеет имя и тип. Сила таблицы данных происходит из того, что при создании фрейма данных из структурированного набора данных (Json, Parquet..), Spark может вывести схему, сделав проход по всему (JSON, Parquet..) загружаемый набор данных. Затем при расчете плана выполнения Spark может использовать схему и делать существенно лучшие оптимизации вычислений. Обратите внимание, что таблицы данных был вызван SchemaRDD перед Spark v1.3.0