Разница между DataFrame (в Spark 2.0, то есть DataSet ) и RDD в Spark

Мне просто интересно, какая разница между RDD и DataFrame (Spark 2.0.0 DataFrame – простой псевдоним типа для Dataset[Row] ) в Apache Spark?

Можете ли вы преобразовать один в другой?

DataFrame хорошо определен с поиском google для определения «DataFrame»:

Кадр данных представляет собой таблицу или двухмерную структуру, подобную массиву, в которой каждый столбец содержит измерения для одной переменной, и каждая строка содержит один случай.

Таким образом, DataFrame имеет дополнительные метаданные из-за его табличного формата, что позволяет Spark выполнять определенные оптимизации по завершенному запросу.

С другой стороны, RDD представляет собой просто R- ориентированный D- атрибут D ataset, который представляет собой более черный ящик данных, которые невозможно оптимизировать как операции, которые могут быть выполнены против него, не так ограничены.

Однако вы можете перейти от DataFrame к RDD помощью своего метода rdd , и вы можете перейти от RDD к DataFrame (если RDD находится в табличном формате) с помощью метода toDF

В общем случае рекомендуется использовать DataFrame где это возможно, благодаря встроенной оптимизации запросов.

Во-первых, DataFrame развивается из SchemaRDD .

сниженный метод toSchemaRDD

Да .. конвертация между Dataframe и RDD абсолютно возможна.

Ниже приведены некоторые примеры fragmentов кода.

  • df.rddRDD[Row]

Ниже приведены некоторые варианты создания dataframe.

  • 1) yourrddOffrow.toDF преобразуется в DataFrame .

  • 2) Использование createDataFrame из sql-контекста

    val df = spark.createDataFrame(rddOfRow, schema)

где схема может быть из некоторых из нижеперечисленных опций, как описано nice SO post ..
Из classа scala case и scala reflection api

 import 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.

введите описание изображения здесь

  1. RDD API:

API RDD (Resilient Distributed Dataset) находится в Spark с момента выпуска 1.0.

API RDD предоставляет множество методов преобразования, таких как map (), filter () и reduce () для выполнения вычислений по данным. Каждый из этих методов приводит к новому RDD представляющему преобразованные данные. Однако эти методы просто определяют операции, которые должны выполняться, и преобразования не выполняются до тех пор, пока не будет вызван метод действия. Примерами методов действий являются collect () и saveAsObjectFile ().

Пример RDD:

 rdd.filter(_.age > 21) // transformation .map(_.last)// transformation .saveAsObjectFile("under21.bin") // action 

Пример: Фильтровать по атрибуту с помощью RDD

 rdd.filter(_.age > 21) 
  1. API DataFrame

Spark 1.3 представила новый API DataFrame в рамках инициативы Project Tungsten, которая направлена ​​на повышение производительности и масштабируемости Spark. API DataFrame представляет концепцию схемы для описания данных, позволяя Spark управлять схемой и только передавать данные между узлами гораздо более эффективным способом, чем использование сериализации Java.

API DataFrame радикально отличается от API RDD поскольку он представляет собой API для построения реляционного плана запросов, который затем может выполнять оптимизатор Catalyst Spark. API является естественным для разработчиков, знакомых с построением планов запросов

Пример стиля SQL:

df.filter("age > 21");

Ограничения: поскольку код относится к атрибутам данных по имени, компилятор не может поймать какие-либо ошибки. Если имена атрибутов неверны, ошибка будет обнаружена только во время выполнения, когда будет создан план запроса.

Еще одним недостатком API DataFrame является то, что он очень scala-centric, и хотя он поддерживает Java, поддержка ограничена.

Например, при создании DataFrame из существующего RDD объектов Java оптимизатор Catalyst Spark не может вывести схему и предполагает, что любые объекты в DataFrame реализуют интерфейс scala.Product . case class Scala case class окно, потому что они реализуют этот интерфейс.

  1. API Dataset

API Dataset , выпущенный как предварительный просмотр API в Spark 1.6, призван обеспечить лучшее из обоих миров; знакомый объектно-ориентированный стиль программирования и тип времени в RDD API, но с преимуществами производительности оптимизатора запросов Catalyst. Наборы данных также используют тот же эффективный механизм хранения кучи, что и API DataFrame .

Когда дело доходит до сериализации данных, API-интерфейс Dataset имеет концепцию кодировщиков, которые транслируют между представлениями JVM (объектов) и внутренним двоичным форматом Spark. У Spark есть встроенные энкодеры, которые очень продвинуты в том, что они генерируют байт-код для взаимодействия с данными без кучи и обеспечивают доступ по требованию к отдельным атрибутам без необходимости де-сериализации целого объекта. Spark еще не предоставляет API для реализации пользовательских кодеров, но это планируется для будущей версии.

Кроме того, API Dataset разработан так, чтобы работать одинаково хорошо с Java и Scala. При работе с объектами Java важно, чтобы они были полностью совместимы с bean-совместимыми.

Пример API-интерфейс Dataset :

 dataset.filter(_.age < 21); 

Оценки разн. между DataFrame & DataSet : введите описание изображения здесь

РДД

Основная абстракция Spark обеспечивает гибкий распределенный dataset (RDD), который представляет собой набор элементов, разбитых по узлам кластера, которые могут работать параллельно.

Особенности RDD: –

  • Распределенная коллекция:
    RDD использует операции MapReduce, которые широко используются для обработки и создания больших наборов данных с параллельным распределенным алгоритмом на кластере. Это позволяет пользователям писать параллельные вычисления, используя набор операторов высокого уровня, не беспокоясь о распределении работы и отказоустойчивости.

  • Неизменяемость: RDD состоят из набора записей, которые разделены. Раздел является базовой единицей параллелизма в RDD, и каждый раздел представляет собой одно логическое разделение данных, которое является неизменным и создается посредством некоторых преобразований на существующих разделах. Возможность использования помогает добиться согласованности вычислений.

  • Отказоустойчивость: в случае потери некоторого раздела RDD мы можем воспроизвести преобразование этого раздела в линии, чтобы добиться того же вычисления, а не выполнять репликацию данных на нескольких узлах. Эта характеристика является самым большим преимуществом RDD, поскольку она экономит много усилий в управлении данными и репликации и, таким образом, обеспечивает более быстрые вычисления.

  • Ленивые оценки: все преобразования в Spark ленивы, поскольку они не сразу вычисляют их результаты. Вместо этого они просто помнят преобразования, применяемые к некоторому базовому набору данных. Преобразования вычисляются только тогда, когда действие требует, чтобы результат возвращался в программу драйвера.

  • Функциональные преобразования: RDD поддерживают два типа операций: преобразования, которые создают новый dataset из существующего, и действия, которые возвращают значение программе драйвера после выполнения вычисления в наборе данных.

  • Форматы обработки данных:

Он может легко и эффективно обрабатывать данные, которые структурированы, а также неструктурированные данные.

  • Поддерживаемые языки программирования:
    RDD API доступен в Java, Scala, Python и R.

Ограничения RDD: –

  • Нет встроенного механизма оптимизации: при работе со структурированными данными RDD не могут воспользоваться преимуществами усовершенствованных оптимизаторов Spark, включая оптимизатор катализатора и механизм выполнения вольфрама. Разработчикам необходимо оптимизировать каждый RDD на основе его атрибутов.

  • Обработка структурированных данных. В отличие от Dataframe и наборов данных, RDD не выводят схему проглатываемых данных и требуют от пользователя ее указания.

Dataframes

Spark представил Dataframes в выпуске Spark 1.3. Dataframe преодолевает ключевые проблемы, с которыми сталкиваются RDD.

DataFrame представляет собой распределенный сбор данных, организованный в именованные столбцы. Он концептуально эквивалентен таблице в реляционной базе данных или R / Python Dataframe. Наряду с Dataframe, Spark также представил оптимизатор катализатора, который использует расширенные возможности программирования для создания расширяемого оптимизатора запросов.

Функции Dataframe: –

  • Распределенная коллекция объекта 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. 
  • Совместимость с hive. Используя Spark SQL, вы можете запускать немодифицированные запросы на кусты на существующих складах Hive. Он повторно использует интерфейсы Hive и MetaStore и дает вам полную совместимость с существующими данными, запросами и UDF.

  • Вольфрам: Tungsten обеспечивает материальный бэкэнд, который быстро управляет памятью и динамически генерирует байт-код для оценки выражения.

  • Поддерживаемые языки программирования:
    API Dataframe доступен в Java, Scala, Python и R.

Ограничения Dataframe: –

  • Безопасность типа компиляции: как обсуждалось, API Dataframe не поддерживает безопасность времени компиляции, которая ограничивает вас манипулированием данными, когда структура не знает. Следующий пример работает во время компиляции. Однако при выполнении этого кода вы получите исключение Runtime.

Пример:

 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, мы не будем восстанавливать исходный class RDD classа Person (RDD [Person]).

Пример:

 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-интерфейс Datasets

API-интерфейс Dataset – это расширение для DataFrames, которое обеспечивает безопасный и объектно-ориентированный интерфейс программирования. Это сильно типизированная, неизменяемая коллекция объектов, которые сопоставляются с реляционной схемой.

В основе набора данных API – это новая концепция, называемая кодировщиком, которая отвечает за преобразование объектов JVM и табличного представления. Табличное представление хранится с использованием внутреннего двоичного формата Spark во дворе, позволяющего работать с сериализованными данными и улучшать использование памяти. Spark 1.6 поддерживает автоматическую генерацию кодировщиков для самых разных типов, включая примитивные типы (например, String, Integer, Long), classы classов Scala и Java Beans.

Возможности набора данных: –

  • Обеспечивает лучшее из RDD и Dataframe: RDD (функциональное программирование, безопасный тип), DataFrame (реляционная модель, оптимизация запросов, выполнение вольфрама, сортировка и перетасовка)

  • Кодеры: с помощью Encoders легко преобразовать любой объект JVM в dataset, позволяя пользователям работать как с структурированными, так и с неструктурированными данными, в отличие от Dataframe.

  • Поддерживаемые языки программирования: API наборов данных в настоящее время доступен только в Scala и Java. В настоящее время Python и R не поддерживаются в версии 1.6. Поддержка Python для версии 2.0.

  • Тип Безопасность: API-интерфейс набора данных обеспечивает безопасность времени компиляции, которая не была доступна в Dataframes. В приведенном ниже примере мы видим, как Dataset может работать с объектами домена с компилируемыми lambda-функциями.

Пример:

 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] 
  • Взаимодействие: наборы данных позволяют легко преобразовывать существующие RDD и Dataframes в массивы данных без кода шаблона.

Ограничения API набора данных: –

  • Требуется листинг типов для String: запрос данных из наборов данных в настоящее время требует от нас указать поля в classе как строку. Как только мы запросили данные, мы вынуждены использовать столбцы для требуемого типа данных. С другой стороны, если мы используем операцию отображения на наборах данных, он не будет использовать оптимизатор Catalyst.

Пример:

 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 API вы все равно не будете нуждаться в безопасности типа и сделаете ваш код хрупким.

Просто RDD является основным компонентом, но DataFrame представляет собой API, внедренный в искру 1.30.

РДД

Сбор разделов данных под названием RDD . Эти RDD должны следовать нескольким свойствам, таким как:

  • Неизменный,
  • Отказоустойчивой,
  • Распределенная
  • Больше.

Здесь RDD либо структурирован, либо неструктурирован.

DataFrame

DataFrame – это API, ansible в Scala, Java, Python и R. Он позволяет обрабатывать любые типы структурированных и полуструктурированных данных. Чтобы определить DataFrame , набор распределенных данных, организованный в именованные столбцы, называемые DataFrame . Вы можете легко оптимизировать RDDs в DataFrame . Вы можете обрабатывать данные JSON, данные паркета, данные DataFrame за раз, используя DataFrame .

 val sampleRDD = sqlContext.jsonFile("hdfs://localhost:9000/jsondata.json") val sample_DF = sampleRDD.toDF() 

Здесь Sample_DF рассматривается как DataFrame . sampleRDD – это (необработанные данные), называемые RDD .

Все (RDD, DataFrame и DataSet) на одном снимке

RDD vs DataFrame vs DataSet

изображение кредитов

РДД

RDD – это отказоустойчивый набор элементов, которые могут работать параллельно.

DataFrame

DataFrame – это dataset, организованный в именованные столбцы. Он концептуально эквивалентен таблице в реляционной базе данных или кадре данных в R / Python, но с более богатыми оптимизациями под капотом .

Dataset

Dataset – это распределенный сбор данных. Dataset – это новый интерфейс, добавленный в Spark 1.6, который обеспечивает преимущества RDD (сильная типизация, возможность использования мощных функций lambda) с преимуществами оптимизированного механизма запуска Spark SQL .


Заметка:

Набор данных строк ( Dataset[Row] ) в Scala / Java часто упоминается как DataFrames .


Хорошее сравнение всех из них с fragmentом кода

RDD vs DataFrame vs DataSet с кодом

источник


В: Можете ли вы преобразовать один из них в другое, например 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 

Большинство ответов верны, только хотите добавить одну точку здесь

В Spark 2.0 оба API (DataFrame + DataSet) будут объединены вместе в один API.

«Унификация DataFrame и набора данных: в Scala и Java, DataFrame и Dataset были унифицированы, то есть DataFrame – это просто псевдоним типа для набора данных. В Python и R, учитывая отсутствие безопасности типов, DataFrame является основным программным интерфейсом».

Однако наборы данных аналогичны RDD, но вместо использования сериализации Java или Kryo они используют специализированный Encoder для сериализации объектов для обработки или передачи по сети.

Spark SQL поддерживает два разных метода преобразования существующих RDD в Datasets. Первый метод использует reflection для вывода схемы RDD, которая содержит конкретные типы объектов. Этот подход, основанный на анализе, приводит к более сжатому коду и хорошо работает, когда вы уже знаете схему при написании приложения Spark.

Второй способ создания наборов данных – это программный интерфейс, который позволяет вам построить схему, а затем применить ее к существующему RDD. Хотя этот метод более подробен, он позволяет создавать наборы данных, когда столбцы и их типы неизвестны до времени выполнения.

Здесь вы можете найти ответ RDD tof Data frame

Как преобразовать объект rdd в dataframe в искру

DataFrame эквивалентен таблице в СУБД, а также можно манипулировать аналогично «родным» распределенным коллекциям в RDD. В отличие от RDD, Dataframes отслеживает схему и поддерживает различные реляционные операции, которые приводят к более оптимизированному исполнению. Каждый объект DataFrame представляет собой логический план, но из-за их «ленивой» природы выполнение не выполняется до тех пор, пока пользователь не назовет конкретную «операцию вывода».

Dataframe – это RDD объектов Row, каждый из которых представляет запись. Dataframe также знает схему (то есть поля данных) своих строк. Хотя Dataframes выглядят как обычные RDD, внутри они хранят данные более эффективным образом, используя их схему. Кроме того, они предоставляют новые операции, недоступные для RDD, такие как возможность запуска SQL-запросов. Данные могут создаваться из внешних источников данных, из результатов запросов или из обычных RDD.

Ссылка: Zaharia M., et al. Learning Spark (O’Reilly, 2015)

Несколько соображений с точки зрения использования, RDD vs DataFrame:

  1. RDD потрясающие! поскольку они дают нам всю гибкость для обработки практически любых данных; неструктурированные, полуструктурированные и структурированные данные. Поскольку, много раз данные не готовы вписываться в DataFrame (даже JSON), RDD можно использовать для предварительной обработки данных, чтобы он мог вставляться в фрейм данных. RDD – это основная абстракция данных в Spark.
  2. Не все преобразования, которые возможны в RDD, возможны на DataFrames, пример subtract () для RDD vs except () для DataFrame.
  3. Поскольку DataFrames подобны реляционной таблице, они следуют строгим правилам при использовании преобразований теории множеств / реляционных теорий, например, если вы хотите объединить два фрейма данных, требование состоит в том, чтобы оба dfs имели одинаковое количество столбцов и связанных типов данных столбцов. Имена столбцов могут быть разными. Эти правила не применяются к RDD. Вот хороший учебник, объясняющий эти факты.
  4. При использовании DataFrames повышается производительность, поскольку другие уже подробно объясняют.
  5. Используя DataFrames, вам не нужно передавать произвольную функцию так же, как при программировании с помощью RDD.
  6. Вам нужен SQLContext / HiveContext для программирования фреймов данных, поскольку они лежат в области SparkSQL искровой экосистемы, но для RDD вам нужен только SparkContext / JavaSparkContext, который находится в библиотеках Spark Core.
  7. Вы можете создать df из RDD, если вы можете определить схему для него.
  8. Вы также можете преобразовать df в rdd и rdd в df.

Я надеюсь, что это помогает!

Вы можете использовать RDD с Structured и неструктурированными, где, поскольку Dataframe / Dataset может обрабатывать только структурированные и полуструктурированные данные (имеет правильную схему)

DataFrame – это RDD, у которого есть схема. Вы можете рассматривать это как таблицу реляционных баз данных, поскольку каждый столбец имеет имя и известный тип. Сила DataFrames исходит из того факта, что при создании DataFrame из структурированного набора данных (Json, Parquet ..) Spark может вывести схему, сделав проход по всему набору данных (Json, Parquet ..), который загружается. Затем при вычислении плана выполнения Spark может использовать схему и существенно улучшить оптимизацию вычислений. Обратите внимание, что DataFrame назывался SchemaRDD до Spark v1.3.0

Давайте будем гением компьютера.