Разница между фреймом данных (в 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.

depreated method toSchemaRDD

да.. преобразование между Dataframe и RDD вполне возможно.

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

  • df.rdd и RDD[Row]

Ниже приведены некоторые из вариантов создания таблицы данных.

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

  • 2) с помощью createDataFrame контекста sql

    val df = spark.createDataFrame(rddOfRow, schema)

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

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

image description

на самом деле теперь есть 3 Apache Spark API..

enter image description here

  1. 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)
  1. DataFrame API

Spark 1.3 представила новый DataFrame API в рамках проекта Вольфрам инициатива, которая направлена на повышение производительности и масштабируемость искры. The DataFrame 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--> работает из коробки, потому что они реализуют этот интерфейс.

  1. 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 : enter image description here

дальнейшее чтение... 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 vs DataFrame vs DataSet

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

RDD

RDD отказоустойчивое собрание элементов которые можно эксплуатировать дальше параллельно.

таблицы данных

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

Dataset

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


Примечание:

набор данных строк (Dataset[Row]) в Scala/Java часто ссылаются как фреймы данных.


хорошее сравнение всех из них с фрагментом кода

RDD vs DataFrame vs DataSet with code

источник


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

как преобразовать объект rdd в dataframe в spark


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


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

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


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

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

надеюсь, это поможет!


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


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