Мне просто интересно, какая разница между RDD
и DataFrame
(Spark 2.0.0 DataFrame - простой псевдоним типа для Dataset[Row]
) в Apache Spark?
Можете ли вы преобразовать один в другой?
Мне просто интересно, какая разница между RDD
и DataFrame
(Spark 2.0.0 DataFrame - простой псевдоним типа для Dataset[Row]
) в Apache Spark?
Можете ли вы преобразовать один в другой?
A DataFrame
хорошо определен с поиском google для определения "DataFrame":
Кадр данных представляет собой таблицу или двухмерную структуру, подобную массиву, в каждый столбец содержит измерения по одной переменной, и каждая строка содержит один случай.
Таким образом, DataFrame
имеет дополнительные метаданные из-за своего табличного формата, что позволяет Spark выполнять определенные оптимизации по завершенному запросу.
An RDD
, с другой стороны, представляет собой просто R esilient D istributed D ataset, который больше представляет собой черный ящик данные, которые не могут быть оптимизированы как операции, которые могут быть выполнены против него, не так ограничены.
Однако вы можете перейти от DataFrame к RDD
с помощью метода RDD
, и вы можете перейти от RDD
к 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
как описано в 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:API
RDD
(Resilient Distributed Dataset) находится в Spark с версии 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
Spark 1.3 представил новый API
DataFrame
в рамках инициативы Project Tungsten, которая направлена на повышение производительности и масштабируемости Spark. APIDataFrame
представляет концепцию схемы для описания данных, позволяя Spark управлять схемой и передавать данные только между узлами гораздо более эффективным способом, чем при использовании сериализации Java.API
DataFrame
кардинально отличается от APIRDD
поскольку это API для построения плана реляционных запросов, который затем может выполнить оптимизатор Sparks Catalyst. API является естественным для разработчиков, которые знакомы с построением планов запросов
Пример стиля SQL:
df.filter("age > 21");
Ограничения: поскольку код ссылается на атрибуты данных по имени, компилятор не может отследить какие-либо ошибки. Если имена атрибутов неверны, ошибка будет обнаружена только во время выполнения, когда создается план запроса.
Еще одним недостатком API DataFrame
является то, что он очень ориентирован на DataFrame
и хотя он поддерживает Java, поддержка ограничена.
Например, при создании DataFrame
из существующего RDD
Java-объектов оптимизатор Sparks Catalyst не может вывести схему и предполагает, что любые объекты в DataFrame реализуют интерфейс scala.Product
. case class
Scala работает, потому что они реализуют этот интерфейс.
Dataset
API
Dataset
, выпущенный как предварительный просмотр API в Spark 1.6, призван обеспечить лучшее из обоих миров; знакомый объектно-ориентированный стиль программирования и безопасность типов во время компиляции APIRDD
но с преимуществами производительности оптимизатора запросов Catalyst. Наборы данных также используют тот же эффективный механизм хранения вне кучи, что и APIDataFrame
.Когда дело доходит до сериализации данных, API
Dataset
имеет концепцию кодеров, которые преобразуют между представлениями (объектами) JVM и внутренним двоичным форматом Sparks. Spark имеет встроенные кодеры, которые очень продвинуты в том, что они генерируют байт-код для взаимодействия с данными вне кучи и предоставляют доступ по требованию к отдельным атрибутам без необходимости десериализации всего объекта. Spark пока не предоставляет API для реализации пользовательских кодеров, но это планируется в будущем выпуске.Кроме того, API
Dataset
разработан для одинаковой работы как с Java, так и с Scala. При работе с объектами Java важно, чтобы они были полностью совместимы с компонентами.
Пример API Dataset
стиле SQL:
dataset.filter(_.age < 21);
Оценки разн. между DataFrame
и DataSet
:
Читать далее... статья о блоке данных - Повесть о трех API-интерфейсах Apache Spark: СДР против фреймов данных и наборов данных
Apache Spark предоставляет три типа API
Вот сравнение API между RDD, Dataframe и Dataset.
Основная абстракция Spark обеспечивает гибкий распределенный набор данных (RDD), который представляет собой набор элементов, разбитых по узлам кластера, которые могут работать параллельно.
Распределенная коллекция:
RDD использует операции MapReduce, которые широко используются для обработки и создания больших наборов данных с параллельным распределенным алгоритмом на кластере. Это позволяет пользователям писать параллельные вычисления, используя набор операторов высокого уровня, не беспокоясь о распределении работы и отказоустойчивости.
Необязательные: RDD, состоящие из набора разделяемых записей. Раздел является базовой единицей parallelism в RDD, и каждый раздел представляет собой одно логическое разделение данных, которое является неизменным и создается посредством некоторых преобразований на существующих разделах. Возможность использования помогает достичь согласованности в вычислениях.
Отказоустойчивость: В случае, если мы потеряем некоторый раздел RDD, мы можем воспроизвести преобразование этого раздела в линии, чтобы достичь того же вычисления, а не выполнять репликацию данных на нескольких узлах. Эта характеристика является самым большим преимуществом RDD, поскольку она экономит много усилия по управлению данными и репликации и тем самым ускоряют вычисления.
ленивые оценки: Все преобразования в Spark ленивы, поскольку они не сразу вычисляют их результаты. Вместо этого они просто помнят преобразования, применяемые к некоторому базовому набору данных. Преобразования вычисляются только тогда, когда действие требует, чтобы результат возвращался в программу драйвера.
Функциональные преобразования: RDD поддерживают два типа операций: преобразования, которые создают новый набор данных из существующего, и действия, которые возвращают значение программе драйвера после выполнения вычисления в наборе данных.
Форматы обработки данных:
Он может легко и эффективно обрабатывать данные, которые структурированы, а также неструктурированные данные.
Поддерживаемые языки программирования:
RDD API доступен в Java, Scala, Python и R.
Нет встроенного механизма оптимизации: При работе со структурированными данными RDD не могут воспользоваться преимуществами оптимизаторов Sparks, включая оптимизатор катализаторов и двигатель исполнения вольфрама. Разработчикам необходимо оптимизировать каждый RDD на основе его атрибутов.
Обработка структурированных данных: В отличие от Dataframe и наборов данных, RDD не выводят схему проглатываемых данных и требуют, чтобы пользователь указал ее.
Spark представил Dataframes в выпуске Spark 1.3. Dataframe преодолевает основные проблемы, с которыми сталкиваются RDD.
DataFrame - это распределенный набор данных, организованный в именованные столбцы. Он концептуально эквивалентен таблице в реляционной базе данных или R/Python Dataframe. Наряду с Dataframe, Spark также представил оптимизатор катализаторов, который использует расширенные возможности программирования для создания расширяемого оптимизатора запросов.
Распределенная коллекция объекта Row: DataFrame представляет собой распределенный сбор данных, организованный в именованные столбцы. Он концептуально эквивалентен таблице в реляционной базе данных, но с более богатыми оптимизациями под капотом.
Обработка данных: Обработка структурированных и неструктурированных форматов данных (Avro, CSV, эластичный поиск и Cassandra) и систем хранения (таблицы HDFS, HIVE, MySQL и т.д.). Он может читать и писать из всех этих различных источников данных.
Оптимизация с использованием оптимизатора катализатора: Он поддерживает как SQL-запросы, так и API DataFrame. 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.
Совместимость улья:Используя Spark SQL, вы можете запускать немодифицированные запросы Hive на существующих складах Hive. Он повторно использует интерфейс "Привет" и MetaStore и дает вам полную совместимость с существующими данными, запросами и UDF для Hive.
Вольфрам: 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 (реляционная модель, оптимизация запросов, выполнение вольфрама, сортировка и перетасовка)
кодеры: С помощью Encoders легко преобразовать любой объект JVM в набор данных, позволяя пользователям работать как с структурированными, так и с неструктурированными данными, в отличие от Dataframe.
Поддерживаемые языки программирования: API Datasets в настоящее время доступен только в Scala и Java. В настоящее время Python и R не поддерживаются в версии 1.6. Поддержка Python для версии 2.0.
Тип безопасности: API-интерфейс Datasets обеспечивает безопасность времени компиляции, которая недоступна в Dataframes. В приведенном ниже примере мы видим, как Dataset может работать с объектами домена с компилируемыми лямбда-функциями.
Пример:
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, Datasets поддерживает только Scala и Java. Поддержка Python будет представлена в Spark 2.0.
API Datasets API обладает несколькими преимуществами по сравнению с существующими API RDD и Dataframe с улучшенным безопасным типом и функциональным программированием. С проблемой требований к типу литья в API вы все равно не будете требовать безопасности типа и сделаете ваш код хрупким.
Основная абстракция Spark обеспечивает гибкий распределенный набор данных (RDD), который представляет собой набор элементов, разбитых по узлам кластера, которые могут работать параллельно.
Распределенная коллекция:
RDD использует операции MapReduce, которые широко используются для обработки и создания больших наборов данных с параллельным распределенным алгоритмом на кластере. Это позволяет пользователям писать параллельные вычисления, используя набор операторов высокого уровня, не беспокоясь о распределении работы и отказоустойчивости.
Необязательные: RDD, состоящие из набора разделяемых записей. Раздел является базовой единицей parallelism в RDD, и каждый раздел представляет собой одно логическое разделение данных, которое является неизменным и создается посредством некоторых преобразований на существующих разделах. Возможность использования помогает достичь согласованности в вычислениях.
Отказоустойчивость: В случае, если мы потеряем некоторый раздел RDD, мы можем воспроизвести преобразование этого раздела в линии, чтобы достичь того же вычисления, а не выполнять репликацию данных на нескольких узлах. Эта характеристика является самым большим преимуществом RDD, поскольку она экономит много усилия по управлению данными и репликации и тем самым ускоряют вычисления.
ленивые оценки: Все преобразования в Spark ленивы, поскольку они не сразу вычисляют их результаты. Вместо этого они просто помнят преобразования, применяемые к некоторому базовому набору данных. Преобразования вычисляются только тогда, когда действие требует, чтобы результат возвращался в программу драйвера.
Функциональные преобразования: RDD поддерживают два типа операций: преобразования, которые создают новый набор данных из существующего, и действия, которые возвращают значение программе драйвера после выполнения вычисления в наборе данных.
Форматы обработки данных:
Он может легко и эффективно обрабатывать данные, которые структурированы, а также неструктурированные данные.
Нет встроенного механизма оптимизации: При работе со структурированными данными RDD не могут воспользоваться преимуществами оптимизаторов Sparks, включая оптимизатор катализаторов и двигатель исполнения вольфрама. Разработчикам необходимо оптимизировать каждый RDD на основе его атрибутов.
Обработка структурированных данных: В отличие от Dataframe и наборов данных, RDD не выводят схему проглатываемых данных и требуют, чтобы пользователь указал ее.
Spark представил Dataframes в выпуске Spark 1.3. Dataframe преодолевает основные проблемы, с которыми сталкиваются RDD.
DataFrame - это распределенный набор данных, организованный в именованные столбцы. Он концептуально эквивалентен таблице в реляционной базе данных или R/Python Dataframe. Наряду с Dataframe, Spark также представил оптимизатор катализаторов, который использует расширенные возможности программирования для создания расширяемого оптимизатора запросов.
Распределенная коллекция объекта Row: DataFrame представляет собой распределенный сбор данных, организованный в именованные столбцы. Он концептуально эквивалентен таблице в реляционной базе данных, но с более богатыми оптимизациями под капотом.
Обработка данных: Обработка структурированных и неструктурированных форматов данных (Avro, CSV, эластичный поиск и Cassandra) и систем хранения (таблицы HDFS, HIVE, MySQL и т.д.). Он может читать и писать из всех этих различных источников данных.
Оптимизация с использованием оптимизатора катализатора: Он поддерживает как SQL-запросы, так и API DataFrame. 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.
Совместимость улья: Используя Spark SQL, вы можете запускать немодифицированные запросы Hive на существующих складах Hive. Он повторно использует интерфейс "Привет" и MetaStore и дает вам полную совместимость с существующими данными, запросами и UDF для Hive.
Вольфрам: Tungsten обеспечивает физическое исполняющее устройство, которое явно управляет памятью и динамически генерирует байт-код для оценки выражения.
Поддерживаемые языки программирования:
API Dataframe доступен в Java, Scala, Python и R.
Пример:
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
Это особенно важно, когда вы работаете с несколькими шагами преобразования и агрегации.
Пример:
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]
Dataset API - это расширение для DataFrames, которое обеспечивает безопасный по типу объект-ориентированный интерфейс программирования. Это сильно типизированная, неизменяемая коллекция объектов, которые отображаются в реляционную схему.
В основе набора данных API - это новая концепция, называемая кодировщиком, которая отвечает за преобразование объектов JVM и табличного представления. Табличное представление хранится с использованием внутреннего двоичного формата Spark во дворе, позволяющего работать с сериализованными данными и улучшать использование памяти. Spark 1.6 поставляется с поддержкой автоматического генерации кодировщиков для самых разных типов, включая примитивные типы (например, String, Integer, Long), классы классов Scala и Java Beans.
Обеспечивает лучшее из RDD и Dataframe: RDD (функциональное программирование, безопасный тип), DataFrame (реляционная модель, оптимизация запросов, выполнение вольфрама, сортировка и перетасовка)
кодеры: С помощью Encoders легко преобразовать любой объект JVM в набор данных, позволяя пользователям работать как с структурированными, так и с неструктурированными данными, в отличие от Dataframe.
Поддерживаемые языки программирования: API Datasets в настоящее время доступен только в Scala и Java. В настоящее время Python и R не поддерживаются в версии 1.6. Поддержка Python для версии 2.0.
Тип безопасности: API-интерфейс Datasets обеспечивает безопасность времени компиляции, которая недоступна в Dataframes. В приведенном ниже примере мы видим, как 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]
Пример:
ds.select(col("name").as[String], $"age".as[Int]).collect()
Нет поддержки для Python и R: начиная с версии 1.6, Datasets поддерживает только Scala и Java. Поддержка Python будет представлена в Spark 2.0.
API Datasets API обладает несколькими преимуществами по сравнению с существующими API RDD и Dataframe с улучшенным безопасным типом и функциональным программированием. С проблемой требований к типу литья в API вы все равно не будете требовать безопасности типа и сделаете ваш код хрупким.
RDD
RDD
представляет собой отказоустойчивый набор элементов, которые могут работать параллельно.
DataFrame
DataFrame
- это набор данных, организованный в именованные столбцы. это концептуально эквивалентно таблице в реляционной базе данных или данным кадр в R/Python, , но с большим количеством оптимизаций под капотом.
Dataset
Dataset
представляет собой распределенный сбор данных. Набор данных - это новый интерфейс, добавленный в Spark 1.6, который обеспечивает преимущества СДР(строгая типизация, возможность использовать мощные лямбда-функции) с преимущества оптимизированного механизма исполнения Spark SQL.
Note:
Dataset of Rows (
Dataset[Row]
) in Scala/Java will often refer as 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
Просто 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
.
Поскольку 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]
.
Большинство ответов верны, только хотите добавить одну точку здесь
В Spark 2.0 два API (DataFrame + DataSet) будут объединены вместе в один API.
"Унификация DataFrame и набора данных: в Scala и Java, DataFrame и Dataset были унифицированы, то есть DataFrame - это просто псевдоним типа для набора данных из строки. В Python и R, учитывая отсутствие безопасности типов, DataFrame является основной программный интерфейс."
Наборы данных похожи на RDD, однако вместо использования сериализации Java или Kryo они используют специализированный Encoder для сериализации объектов для обработки или передачи по сети.
Spark SQL поддерживает два разных метода преобразования существующих RDD в Datasets. Первый метод использует отражение для вывода схемы RDD, которая содержит конкретные типы объектов. Этот подход, основанный на анализе, приводит к более сжатому коду и хорошо работает, когда вы уже знаете схему при написании приложения Spark.
Второй способ создания наборов данных - это программный интерфейс, который позволяет вам построить схему, а затем применить ее к существующему RDD. Хотя этот метод более подробен, он позволяет создавать наборы данных, когда столбцы и их типы неизвестны до времени выполнения.
Здесь вы можете найти ответ RDD tof Datap >
DataFrame эквивалентен таблице в СУБД, а также можно манипулировать аналогично "родным" распределенным коллекциям в RDD. В отличие от RDD, Dataframes отслеживает схему и поддерживает различные реляционные операции, которые приводят к более оптимизированному исполнению. Каждый объект DataFrame представляет собой логический план, но из-за их "ленивой" природы выполнение не выполняется до тех пор, пока пользователь не вызовет определенную "операцию вывода".
A Dataframe - это RDD объектов Row, каждый из которых представляет запись. Dataframe также знает схему (т.е. Поля данных) своих строк. В то время как Dataframes выглядят как обычные RDD, внутренне они хранят данные более эффективным образом, используя их схему. Кроме того, они предоставляют новые операции, недоступные для RDD, такие как возможность запуска SQL-запросов. Данные могут создаваться из внешних источников данных, из результатов запросов или из обычных RDD.
Ссылка: Zaharia M., et al. Learning Spark (O'Reilly, 2015)
Я надеюсь, что это помогает!
Вы можете использовать RDD со структурированными и неструктурированными, где, поскольку Dataframe/Dataset может обрабатывать только структурированные и полуструктурированные данные (имеет правильную схему)
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
-
A DataFrame - это RDD, у которого есть схема. Вы можете рассматривать это как таблицу реляционных баз данных, поскольку каждый столбец имеет имя и известный тип. Сила DataFrames исходит из того факта, что при создании DataFrame из структурированного набора данных (Json, Parquet..) Spark может вывести схему, сделав проход по всему набору данных (Json, Parquet..), который загружается. Затем при вычислении плана выполнения Spark может использовать схему и существенно улучшить оптимизацию вычислений. Обратите внимание, что DataFrame назывался SchemaRDD до Spark v1.3.0
Все отличные ответы и использование каждого API имеет некоторый компромисс. Набор данных построен как супер API для решения многих проблем, но много раз RDD по-прежнему работает лучше, если вы понимаете свои данные и если алгоритм обработки оптимизирован для выполнения многих задач за один проход для больших данных, тогда RDD кажется лучшим вариантом.
Агрегация с использованием API набора данных по-прежнему потребляет память и со временем будет улучшаться.