Мне просто интересно, в чем разница между RDD
and и DataFrame
(Spark 2.0.0 DataFrame - просто псевдоним типа Dataset[Row]
) в Apache Spark?
Можете ли вы преобразовать одно в другое?
Мне просто интересно, в чем разница между RDD
and и DataFrame
(Spark 2.0.0 DataFrame - просто псевдоним типа Dataset[Row]
) в Apache Spark?
Можете ли вы преобразовать одно в другое?
Ответы:
A DataFrame
определяется хорошо с поиском Google для «Определение DataFrame»:
Кадр данных представляет собой таблицу или двумерную массивоподобную структуру, в которой каждый столбец содержит измерения по одной переменной, а каждая строка содержит один случай.
Таким образом, a DataFrame
имеет дополнительные метаданные из-за своего табличного формата, который позволяет Spark выполнять определенные оптимизации для завершенного запроса.
RDD
, С другой стороны, это всего лишь R esilient D istributed D ataset , что в большей степени Blackbox данных , которые не могут быть оптимизированы , как операции , которые могут быть выполнены против него, не так ограничен.
Однако вы можете перейти от DataFrame к методу RDD
через его rdd
, и вы можете перейти от a RDD
к a DataFrame
(если RDD в табличном формате) через toDF
метод
В общем, рекомендуется использовать, DataFrame
где это возможно, благодаря встроенной оптимизации запросов.
Первое, что
DataFrame
было развитоSchemaRDD
.
Да .. преобразование между Dataframe
и RDD
абсолютно возможно.
Ниже приведены некоторые примеры кода.
df.rdd
является RDD[Row]
Ниже приведены некоторые варианты создания фрейма данных.
1) yourrddOffrow.toDF
конвертируется в DataFrame
.
2) Использование createDataFrame
контекста sql
val df = spark.createDataFrame(rddOfRow, schema)
где схема может быть из некоторых из приведенных ниже вариантов, как описано в хорошем сообщении SO ..
Из класса случая 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 API Apache Spark.
RDD
API:
RDD
(Эластичные Распределенная Dataset) API был в Спарк с момента выпуска 1.0.
RDD
API предоставляет множество методов трансформации, такие какmap
(),filter
() иreduce
() для выполнения вычислений над данными. Каждый из этих методов приводит к новомуRDD
представлению преобразованных данных. Однако эти методы просто определяют операции, которые должны быть выполнены, и преобразования не выполняются, пока не будет вызван метод действия. Примерами методов действий являютсяcollect
() иsaveAsObjectFile
().
Пример СДР:
rdd.filter(_.age > 21) // transformation
.map(_.last)// transformation
.saveAsObjectFile("under21.bin") // action
Пример: фильтр по атрибуту с помощью RDD
rdd.filter(_.age > 21)
DataFrame
APISpark 1.3 представил новый
DataFrame
API в рамках инициативы Project Tungsten, целью которой является повышение производительности и масштабируемости Spark. ВDataFrame
вводит API понятие схемы для описания данных, что позволяет Спарк управлять схемой и передавать только данные между узлами, в гораздо более эффективным способом , чем при использовании Java сериализации.
DataFrame
API радикально отличается отRDD
API , потому что это API для построения реляционной плана запроса , что Catalyst оптимизатор искры из может затем выполнить. API является естественным для разработчиков, которые знакомы с построением планов запросов
Пример стиля SQL:
df.filter("age > 21");
Ограничения: поскольку код ссылается на атрибуты данных по имени, компилятор не может отловить какие-либо ошибки. Если имена атрибутов неверны, ошибка будет обнаружена только во время выполнения, когда создается план запроса.
Еще одним недостатком DataFrame
API является то, что он очень ориентирован на скалы, и хотя он поддерживает Java, поддержка ограничена.
Например, при создании DataFrame
из существующего RDD
объекта Java оптимизатор Spark Catalyst не может вывести схему и предполагает, что любые объекты в DataFrame реализуют scala.Product
интерфейс. Scala case class
работает на коробке, потому что они реализуют этот интерфейс.
Dataset
API
Dataset
API, выпущенный в качестве API предварительного просмотра в Спарк 1.6, стремится обеспечить лучшее из обоих миров; знакомый объектно-ориентированный стиль программирования и безопасность типов во время компиляцииRDD
API, но с преимуществами производительности оптимизатора запросов Catalyst. Наборы данных также используют тот же эффективный механизм хранения вне кучи, что иDataFrame
API.Когда дело доходит до сериализации данных,
Dataset
API имеет концепцию кодировщиков, которые переводят между представлениями (объектами) JVM и внутренним двоичным форматом Spark. Spark имеет встроенные кодеры, которые очень продвинуты в том, что они генерируют байт-код для взаимодействия с данными вне кучи и предоставляют доступ по требованию к отдельным атрибутам без необходимости десериализации всего объекта. Spark пока не предоставляет API для реализации пользовательских кодеров, но это планируется в будущем выпуске.Кроме того,
Dataset
API разработан так, чтобы одинаково хорошо работать как с Java, так и с Scala. При работе с объектами Java важно, чтобы они были полностью совместимы с компонентами.
Пример Dataset
API-стиля SQL:
dataset.filter(_.age < 21);
Оценки разн. между DataFrame
& DataSet
:
Катализатор уровня потока. . (Демистификация презентации DataFrame и Dataset с искрового саммита)
Читать далее ... статья о блоке данных - Повесть о трех API-интерфейсах Apache Spark: СДР против фреймов данных и наборов данных
df.filter("age > 21");
это можно оценить / проанализировать только во время выполнения. с его строки. Incase of Datasets, Datasets соответствуют требованиям bean. поэтому возраст - это свойство бобов. если в вашем bean-компоненте не указано свойство age, тогда вы узнаете об этом рано, т.е. во время компиляции (т.е. dataset.filter(_.age < 21);
). Ошибка анализа может быть переименована как Ошибка оценки.
Apache Spark предоставляет три типа API
Вот сравнение API между RDD, Dataframe и Dataset.
Основная абстракция, которую предоставляет Spark, - это эластичный распределенный набор данных (RDD), представляющий собой набор элементов, распределенных по узлам кластера, с которыми можно работать параллельно.
Распределенная коллекция:
СДР использует операции MapReduce, которые широко применяются для обработки и создания больших наборов данных с параллельным распределенным алгоритмом в кластере. Это позволяет пользователям писать параллельные вычисления, используя набор операторов высокого уровня, не беспокоясь о распределении работы и отказоустойчивости.
Неизменные: СДР, состоящие из набора записей, которые разделены. Раздел - это базовая единица параллелизма в СДР, и каждый раздел - это одно логическое разделение данных, которое является неизменным и создается с помощью некоторых преобразований в существующих разделах. Неизменность помогает обеспечить согласованность вычислений.
Отказоустойчивость: в случае потери некоторого раздела RDD мы можем воспроизвести преобразование этого раздела в lineage для достижения того же вычисления, а не выполнять репликацию данных на нескольких узлах. Эта характеристика является наибольшим преимуществом RDD, поскольку она экономит много усилий в управлении данными и репликации и, следовательно, обеспечивает более быстрые вычисления.
Ленивые оценки: все преобразования в Spark являются ленивыми, поскольку они не сразу вычисляют свои результаты. Вместо этого они просто запоминают преобразования, примененные к некоторому базовому набору данных. Преобразования вычисляются только тогда, когда действие требует возврата результата в программу драйвера.
Функциональные преобразования: СДР поддерживают два типа операций: преобразования, которые создают новый набор данных из существующего, и действия, которые возвращают значение программе драйвера после выполнения вычисления в наборе данных.
Форматы обработки данных:
он может легко и эффективно обрабатывать как структурированные, так и неструктурированные данные.
Поддерживаемые языки программирования:
RDD API доступен в Java, Scala, Python и R.
Нет встроенного механизма оптимизации: при работе со структурированными данными СДР не могут использовать преимущества передовых оптимизаторов Spark, включая оптимизатор катализаторов и механизм исполнения Tungsten. Разработчики должны оптимизировать каждый RDD на основе его атрибутов.
Обработка структурированных данных: в отличие от Dataframe и наборов данных, RDD не выводят схему загруженных данных и требуют от пользователя ее указания.
Spark представил Dataframes в выпуске Spark 1.3. Датафрейм преодолевает ключевые проблемы, с которыми сталкивались RDD.
DataFrame - это распределенная коллекция данных, организованная в именованные столбцы. Концептуально это эквивалентно таблице в реляционной базе данных или R / Python Dataframe. Наряду с Dataframe Spark также представила оптимизатор катализаторов, который использует расширенные функции программирования для создания расширяемого оптимизатора запросов.
Распределенная коллекция объекта Row: DataFrame - это распределенная коллекция данных, организованная в именованные столбцы. Концептуально это эквивалентно таблице в реляционной базе данных, но с более богатой оптимизацией.
Обработка данных: обработка структурированных и неструктурированных форматов данных (Avro, CSV, эластичный поиск и Cassandra) и систем хранения (HDFS, таблицы HIVE, MySQL и т. Д.). Он может читать и писать из всех этих различных источников данных.
Оптимизация с использованием оптимизатора катализатора: он поддерживает запросы SQL и API DataFrame. Структура данных использует структуру преобразования дерева катализаторов в четыре этапа,
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, запросами и пользовательскими функциями.
Tungsten: Tungsten обеспечивает физический бэкэнд выполнения, который явно управляет памятью и динамически генерирует байт-код для оценки выражения.
Поддерживаемые языки программирования:
API Dataframe доступен в Java, Scala, Python и R.
Пример:
case class Person(name : String , age : Int)
val dataframe = sqlContext.read.json("people.json")
dataframe.filter("salary > 10000").show
=> throws Exception : cannot resolve 'salary' given input age , name
Это особенно сложно, когда вы работаете с несколькими этапами преобразования и агрегирования.
Пример:
case class Person(name : String , age : Int)
val personRDD = sc.makeRDD(Seq(Person("A",10),Person("B",20)))
val personDF = sqlContext.createDataframe(personRDD)
personDF.rdd // returns RDD[Row] , does not returns RDD[Person]
Dataset API - это расширение для DataFrames, которое обеспечивает безопасный для типов интерфейс объектно-ориентированного программирования. Это строго типизированная неизменяемая коллекция объектов, сопоставленных с реляционной схемой.
В основе набора данных API - это новая концепция, называемая кодировщиком, который отвечает за преобразование между объектами JVM и табличным представлением. Табличное представление хранится с использованием внутреннего вольфрамового двоичного формата Spark, что позволяет выполнять операции с сериализованными данными и улучшает использование памяти. Spark 1.6 поставляется с поддержкой автоматической генерации кодировщиков для широкого спектра типов, включая примитивные типы (например, String, Integer, Long), классы случаев Scala и Java Beans.
Обеспечивает лучшее как RDD, так и Dataframe: RDD (функциональное программирование, типобезопасность), DataFrame (реляционная модель, оптимизация запросов, выполнение вольфрама, сортировка и перемешивание)
Кодировщики. С помощью кодировщиков легко преобразовать любой объект JVM в набор данных, что позволяет пользователям работать как с структурированными, так и с неструктурированными данными в отличие от Dataframe.
Поддерживаемые языки программирования: API наборов данных в настоящее время доступен только в Scala и Java. Python и R в настоящее время не поддерживаются в версии 1.6. Поддержка Python намечена для версии 2.0.
Безопасность типов: API наборов данных обеспечивает безопасность времени компиляции, которая не была доступна в Dataframes. В приведенном ниже примере мы можем увидеть, как набор данных может работать с объектами домена с помощью компиляции лямбда-функций.
Пример:
case class Person(name : String , age : Int)
val personRDD = sc.makeRDD(Seq(Person("A",10),Person("B",20)))
val personDF = sqlContext.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]
Пример:
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 вы все равно не будете обеспечивать требуемую безопасность типов и сделаете свой код хрупким.
Dataset
не является LINQ и лямбда-выражение не может быть интерпретировано как деревья выражений. Таким образом, существуют черные ящики, и вы теряете почти все (если не все) преимущества оптимизатора. Небольшое подмножество возможных недостатков: Набор данных Spark 2.0 против DataFrame . Кроме того, просто чтобы повторить то, что я говорил несколько раз - в целом сквозная проверка типов невозможна с Dataset
API. Объединения являются лишь наиболее ярким примером.
RDD
RDD
представляет собой отказоустойчивый набор элементов, которые могут работать параллельно.
DataFrame
DataFrame
это набор данных, организованный в именованные столбцы. Концептуально он эквивалентен таблице в реляционной базе данных или фрейму данных в R / Python, но с большей оптимизацией под капотом .
Dataset
Dataset
это распределенная коллекция данных. Набор данных - это новый интерфейс, добавленный в Spark 1.6, который обеспечивает преимущества RDD (строгая типизация, возможность использовать мощные лямбда-функции) с преимуществами оптимизированного механизма исполнения Spark SQL .
Примечание:
Набор данных Rows (
Dataset[Row]
) в Scala / Java часто называется DataFrames .
Nice comparison of all of them with a code snippet.
В: Можете ли вы преобразовать одно в другое, например, в RDD, в DataFrame или наоборот?
1. RDD
чтобы 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 в Dataframe в Spark
2. DataFrame
/ DataSet
с RDD
с .rdd()
методом
val rowsRdd: RDD[Row] = df.rdd() // DataFrame to RDD
Потому что DataFrame
он слабо типизирован, и разработчики не получают преимуществ системы типов. Например, предположим, что вы хотите прочитать что-то из SQL и выполнить на нем агрегацию:
val people = sqlContext.read.parquet("...")
val department = sqlContext.read.parquet("...")
people.filter("age > 30")
.join(department, people("deptId") === department("id"))
.groupBy(department("name"), "gender")
.agg(avg(people("salary")), max(people("age")))
Когда вы говорите people("deptId")
, вы не получаете обратно Int
или Long
, вы получаете Column
объект, с которым вам нужно работать. В языках с богатыми системами типов, таких как Scala, вы теряете всю безопасность типов, что увеличивает количество ошибок времени выполнения для вещей, которые могут быть обнаружены во время компиляции.
Напротив, DataSet[T]
набрано. когда вы делаете:
val people: People = val people = sqlContext.read.parquet("...").as[People]
Вы на самом деле возвращаете People
объект, который deptId
является фактическим целочисленным типом, а не типом столбца, таким образом, используя преимущества системы типов.
Начиная с Spark 2.0, API-интерфейсы DataFrame и DataSet будут унифицированы, где DataFrame
будет псевдоним типа DataSet[Row]
.
DataFrame
заключалась в том, чтобы не нарушать изменения API. Во всяком случае, просто хотел указать на это. Спасибо за редактирование и upvote от меня.
Просто RDD
является ключевым компонентом, но DataFrame
это API, представленный в версии 1.30.
Сбор данных разделов называется RDD
. Они RDD
должны следовать нескольким свойствам, таким как:
Здесь RDD
либо структурированные, либо неструктурированные.
DataFrame
это API, доступный в Scala, Java, Python и R. Он позволяет обрабатывать любые типы структурированных и полуструктурированных данных. Чтобы определить DataFrame
, коллекция распределенных данных, организованных в именованные столбцы называется DataFrame
. Вы можете легко оптимизировать RDDs
в DataFrame
. Вы можете обрабатывать данные JSON, данные паркета, данные HiveQL одновременно, используя DataFrame
.
val sampleRDD = sqlContext.jsonFile("hdfs://localhost:9000/jsondata.json")
val sample_DF = sampleRDD.toDF()
Здесь Sample_DF считают как DataFrame
. sampleRDD
называется (необработанные данные) RDD
.
Большинство ответов верны, хочу добавить только один балл
В Spark 2.0 два API (DataFrame + DataSet) будут объединены в единый API.
«Объединение DataFrame и Dataset: в Scala и Java DataFrame и Dataset были унифицированы, т.е. DataFrame - это просто псевдоним типа для Dataset of Row. В Python и R, учитывая отсутствие безопасности типов, DataFrame является основным интерфейсом программирования».
Наборы данных аналогичны RDD, однако вместо сериализации Java или Kryo они используют специализированный кодер для сериализации объектов для обработки или передачи по сети.
Spark SQL поддерживает два разных метода для преобразования существующих RDD в наборы данных. Первый метод использует отражение, чтобы вывести схему RDD, которая содержит определенные типы объектов. Этот основанный на отражении подход приводит к более лаконичному коду и хорошо работает, когда вы уже знаете схему при написании приложения Spark.
Второй метод создания наборов данных - через программный интерфейс, который позволяет создать схему и затем применить ее к существующему СДР. Хотя этот метод более многословен, он позволяет создавать наборы данных, когда столбцы и их типы неизвестны до времени выполнения.
Здесь вы можете найти ответ RDD на фрейм Data.
DataFrame эквивалентен таблице в RDBMS и может также управляться аналогично «родным» распределенным коллекциям в RDD. В отличие от RDD, Dataframes отслеживают схему и поддерживают различные реляционные операции, которые ведут к более оптимизированному выполнению. Каждый объект DataFrame представляет логический план, но из-за своей «ленивой» природы выполнение не происходит, пока пользователь не вызовет определенную «операцию вывода».
Я надеюсь, что это помогает!
Dataframe - это RDD объектов Row, каждый из которых представляет запись. Dataframe также знает схему (т. Е. Полей данных) своих строк. Хотя датафреймы выглядят как обычные RDD, внутри они хранят данные более эффективно, используя преимущества своей схемы. Кроме того, они предоставляют новые операции, недоступные на RDD, такие как возможность выполнения запросов SQL. Кадры данных могут быть созданы из внешних источников данных, из результатов запросов или из обычных RDD.
Ссылка: Захария М. и соавт. Изучая Искру (О'Рейли, 2015)
Spark RDD (resilient distributed dataset)
:
RDD является основным API абстракции данных и доступен с самого первого выпуска Spark (Spark 1.0). Это низкоуровневый API для управления распределенным сбором данных. API RDD предоставляет некоторые чрезвычайно полезные методы, которые можно использовать для получения очень жесткого контроля над базовой физической структурой данных. Это неизменяемая (только для чтения) коллекция разделенных данных, распределенных на разных компьютерах. RDD позволяет выполнять вычисления в памяти на больших кластерах, чтобы ускорить обработку больших данных отказоустойчивым способом. Для обеспечения отказоустойчивости СДР использует DAG (направленный ациклический граф), который состоит из набора вершин и ребер. Вершины и ребра в DAG представляют RDD и операцию, которая должна применяться к этому RDD соответственно. Преобразования, определенные в RDD, являются ленивыми и выполняются только при вызове действия.
Spark DataFrame
:
Spark 1.3 представил два новых API абстракции данных - DataFrame и DataSet. API-интерфейсы DataFrame организуют данные в именованные столбцы, например, таблицы в реляционной базе данных. Это позволяет программистам определять схему для распределенного сбора данных. Каждая строка в DataFrame имеет строку типа объекта. Как и таблица SQL, каждый столбец должен иметь одинаковое количество строк в DataFrame. Короче говоря, DataFrame - это лениво оцененный план, который определяет операции, которые необходимо выполнить с распределенным сбором данных. DataFrame также является неизменной коллекцией.
Spark DataSet
:
В качестве расширения API DataFrame Spark 1.3 также представил API DataSet, которые предоставляют строго типизированный и объектно-ориентированный интерфейс программирования в Spark. Это неизменный, безопасный тип распределенных данных. Как и DataFrame, API-интерфейсы DataSet также используют механизм Catalyst для обеспечения оптимизации выполнения. DataSet является расширением API DataFrame.
Other Differences
-
DataFrame является РДД , который имеет схему. Вы можете думать об этом как о таблице реляционной базы данных, в которой каждый столбец имеет имя и известный тип. Мощь DataFrames проистекает из того факта, что когда вы создаете DataFrame из структурированного набора данных (Json, Parquet ..), Spark может вывести схему, обойдя весь набор данных (Json, Parquet ..), который загружается. Затем, при расчете плана выполнения, Spark может использовать схему и существенно улучшить оптимизацию вычислений. Обратите внимание, что DataFrame назывался SchemaRDD до Spark v1.3.0
Spark RDD -
СДР обозначает отказоустойчивые распределенные наборы данных. Это только для чтения раздел коллекции записей. СДР является фундаментальной структурой данных Spark. Это позволяет программисту выполнять вычисления в памяти на больших кластерах отказоустойчивым способом. Таким образом, ускорить задачу.
Spark Dataframe -
В отличие от RDD, данные организованы в именованные столбцы. Например, таблица в реляционной базе данных. Это неизменный распределенный набор данных. DataFrame в Spark позволяет разработчикам навязывать структуру распределенному набору данных, обеспечивая абстракцию более высокого уровня.
Набор данных Spark -
Наборы данных в Apache Spark являются расширением API DataFrame, которое обеспечивает безопасный для типов интерфейс объектно-ориентированного программирования. Набор данных использует преимущества оптимизатора Spark Catalyst, предоставляя выражения и поля данных планировщику запросов.
Все отличные ответы и использование каждого API имеет некоторый компромисс. Набор данных построен как супер API для решения многих проблем, но много раз RDD по-прежнему работает лучше, если вы понимаете свои данные и если алгоритм обработки оптимизирован для выполнения многих задач за один проход для больших данных, тогда RDD кажется лучшим вариантом.
Агрегация с использованием API набора данных по-прежнему потребляет память и со временем будет улучшаться.