Różnica między DataFrame, zestawem danych i RDD w Spark


Odpowiedzi:


232

A DataFramejest dobrze zdefiniowane w wyszukiwaniu w Google „Definicja DataFrame”:

Ramka danych jest tabelą lub dwuwymiarową strukturą tablicową, w której każda kolumna zawiera pomiary jednej zmiennej, a każdy wiersz zawiera jeden przypadek.

A zatem, DataFramema dodatkowe metadane ze względu na swój format tabelaryczny, który pozwala Sparkowi uruchomić pewne optymalizacje na sfinalizowanym zapytaniu.

RDD, Z drugiej strony, jest jedynie R esilient D istributed D ataset to bardziej Blackboksie danych, które nie mogą być zoptymalizowane do operacji, które można wykonać na nim, nie są ograniczone.

Można jednak przejść z DataFrame do metody RDDpoprzez rdd, i można przejść z metody RDDdo do DataFrame(jeśli RDD ma format tabelaryczny) tą toDFmetodą

Zasadniczo zaleca się stosowanie tam, DataFramegdzie to możliwe, ze względu na wbudowaną optymalizację zapytań.


6
Odpowiedź nie zawiera wyjaśnień dotyczących zestawów danych. Zgodnie z Przewodnikiem definitywnym Spark zbiór danych jest bezpiecznym strukturalnym interfejsem API. Możesz więc wcześniej podać typ swojego schematu.
Chintan Pandya

3
Dzięki - oryginalny tytuł i opis zostały zredagowane dobrze po oryginalnych pytaniach (które nie obejmowały zestawów danych)
Justin Pihony

219

Pierwszą rzeczą jest, DataFrameod której ewoluowałem SchemaRDD.

nieaktualna metoda toSchemaRDD

Tak .. konwersja pomiędzy Dataframei RDDjest absolutnie możliwa.

Poniżej kilka przykładowych fragmentów kodu.

  • df.rdd jest RDD[Row]

Poniżej znajdują się niektóre opcje tworzenia ramki danych.

  • 1) yourrddOffrow.toDFkonwertuje na DataFrame.

  • 2) Korzystanie createDataFramez kontekstu sql

    val df = spark.createDataFrame(rddOfRow, schema)

gdzie schemat może pochodzić z niektórych z poniższych opcji, jak opisano w ładnym wpisie SO.
Z klasy case scala i apli refleksji scala

import org.apache.spark.sql.catalyst.ScalaReflection
val schema = ScalaReflection.schemaFor[YourScalacaseClass].dataType.asInstanceOf[StructType]

LUB używając Encoders

import org.apache.spark.sql.Encoders
val mySchema = Encoders.product[MyCaseClass].schema

zgodnie z opisem schematu można również utworzyć za pomocą StructTypei StructField

val schema = new StructType()
  .add(StructField("id", StringType, true))
  .add(StructField("col1", DoubleType, true))
  .add(StructField("col2", DoubleType, true)) etc...

opis obrazu

W rzeczywistości istnieją teraz 3 interfejsy API Apache Spark.

wprowadź opis zdjęcia tutaj

  1. RDD API:

RDD(Elastycznym Ukazuje zbiorów danych) API została w Spark od wydania 1.0.

RDDAPI dostarcza wielu metod transformacji, takie jak map() filter() i reduce() do przeprowadzania obliczeń na danych. Każda z tych metod skutkuje nowym RDDreprezentowaniem przekształconych danych. Jednak metody te definiują tylko operacje, które należy wykonać, a transformacje nie są wykonywane, dopóki nie zostanie wywołana metoda akcji. Przykładami metod akcji są collect() i saveAsObjectFile().

Przykład RDD:

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

Przykład: Filtruj według atrybutu za pomocą RDD

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

Spark 1.3 wprowadził nowy DataFrameinterfejs API w ramach inicjatywy Project Tungsten, która ma na celu poprawę wydajności i skalowalności Spark. Do DataFramewprowadza API pojęcie schematu opisać dane, pozwalając Spark zarządzać schematu i tylko przekazywanie danych między węzłami, w znacznie bardziej efektywny sposób niż za pomocą serializacji Java.

DataFrameAPI jest radykalnie różny od RDDAPI, ponieważ jest to API do tworzenia relacyjnej planu kwerend ta iskra Catalyst optymalizator może następnie wykonać. Interfejs API jest naturalny dla programistów znających się na tworzeniu planów zapytań

Przykładowy styl SQL:

df.filter("age > 21");

Ograniczenia: Ponieważ kod odnosi się do atrybutów danych według nazwy, kompilator nie może wykryć żadnych błędów. Jeśli nazwy atrybutów są niepoprawne, błąd zostanie wykryty tylko w czasie wykonywania, gdy tworzony jest plan zapytań.

Inną wadą DataFrameinterfejsu API jest to, że jest bardzo scentralizowany i chociaż obsługuje Javę, obsługa jest ograniczona.

Na przykład podczas tworzenia DataFramez istniejących RDDobiektów Java optymalizator Catalyst Spark nie może wywnioskować schematu i zakłada, że ​​dowolne obiekty w DataFrame implementują scala.Productinterfejs. Scala case classdziała od razu, ponieważ implementuje ten interfejs.

  1. Dataset API

DatasetAPI, wydany jako podgląd API w Spark 1.6 ma zapewnić najlepsze z obu światów; znany zorientowany obiektowo styl programowania i bezpieczeństwo typu RDDAPI w czasie kompilacji, ale z korzyściami wynikającymi z optymalizatora zapytań Catalyst. Zestawy danych korzystają również z tego samego wydajnego mechanizmu przechowywania poza stertą, co DataFrameinterfejs API.

Jeśli chodzi o serializację danych, DatasetAPI ma pojęcie koderów, które tłumaczą między reprezentacjami (obiektami) JVM a wewnętrznym formatem binarnym Spark. Spark ma wbudowane kodery, które są bardzo zaawansowane, ponieważ generują kod bajtowy do interakcji z danymi ze stosu i zapewniają dostęp na żądanie do poszczególnych atrybutów bez konieczności serializacji całego obiektu. Spark nie zapewnia jeszcze interfejsu API do implementacji niestandardowych koderów, ale jest to planowane w przyszłej wersji.

Ponadto Datasetinterfejs API został zaprojektowany tak, aby działał równie dobrze z Javą i Scalą. Podczas pracy z obiektami Java ważne jest, aby były one w pełni zgodne z komponentami bean.

Przykładowy Datasetstyl API SQL:

dataset.filter(_.age < 21);

Oceny różnią się pomiędzy DataFramei DataSet: wprowadź opis zdjęcia tutaj

Przepływ poziomu katalizatora. . (Demystifying DataFrame i prezentacja zestawu danych z Spark Summit) wprowadź opis zdjęcia tutaj

Więcej informacji ... artykuł o bazach danych - Tale of Three Apache Spark APIs: RDDs vs DataFrames and Datasets


Czym jest silnie typowana struktura Zestaw danych? Czym różni się od DataFrame?
Arvind Kumar

Jakiego rodzaju błędy analizy są objęte zestawami danych?
Neeleshkumar S

5
@ neelesh-srinivasan: weź przykład w składni ramki danych, którą df.filter("age > 21");można ocenić / przeanalizować tylko w czasie wykonywania. od jego ciągu. W przypadku zestawów danych zestawy danych są zgodne z komponentami bean. więc wiek jest własnością fasoli. jeśli nie ma własności wieku w twojej fasoli, to poznasz ją wcześnie, tj. w czasie kompilacji (tj dataset.filter(_.age < 21);.). Błąd analizy można zmienić na „Błędy oceny”.
Ram Ghadiyaram

@NeeleshSrinivasan: więcej informacji i szczegółów patrz porównanie apache-spark-api
Ram Ghadiyaram

Pierwsze zdjęcie jest mylące. Zestawy danych nie są dostępne w Pythonie
Yeikel

135

Apache Spark zapewnia trzy typy interfejsów API

  1. RDD
  2. Ramka danych
  3. Zestaw danych

Porównanie interfejsów API RDD, Dataframe i Dataset

Oto porównanie interfejsów API między RDD, ramką danych i zestawem danych.

RDD

Główną abstrakcją, którą zapewnia Spark, jest odporny rozproszony zestaw danych (RDD), który jest zbiorem elementów podzielonych między węzły klastra, na których można operować równolegle.

Funkcje RDD: -

  • Kolekcja rozproszona:
    RDD korzysta z operacji MapReduce, która jest powszechnie stosowana do przetwarzania i generowania dużych zestawów danych za pomocą równoległego, rozproszonego algorytmu w klastrze. Umożliwia użytkownikom pisanie obliczeń równoległych przy użyciu zestawu operatorów wysokiego poziomu, bez martwienia się o rozkład pracy i odporność na uszkodzenia.

  • Niezmienny: RDD złożone ze zbioru rekordów podzielonych na partycje. Partycja jest podstawową jednostką równoległości w RDD, a każda partycja jest jednym logicznym podziałem danych, który jest niezmienny i utworzony przez pewne przekształcenia istniejących partycji. Niezmienność pomaga osiągnąć spójność obliczeń.

  • Odporny na awarie: w przypadku utraty części partycji RDD możemy odtworzyć transformację na tej partycji w linii, aby osiągnąć to samo obliczenie, zamiast wykonywać replikację danych w wielu węzłach. Ta cecha jest największą zaletą RDD, ponieważ oszczędza wiele wysiłku w zakresie zarządzania danymi i replikacji, a tym samym osiągania szybszych obliczeń.

  • Leniwe oceny: wszystkie transformacje w Spark są leniwe, ponieważ nie obliczają od razu swoich wyników. Zamiast tego pamiętają po prostu transformacje zastosowane do jakiegoś podstawowego zestawu danych. Transformacje są obliczane tylko wtedy, gdy akcja wymaga zwrócenia wyniku do programu sterownika.

  • Transformacje funkcjonalne: RDD obsługują dwa typy operacji: transformacje, które tworzą nowy zestaw danych z istniejącego, oraz akcje, które zwracają wartość do programu sterownika po uruchomieniu obliczeń w zestawie danych.

  • Formaty przetwarzania danych:
    może łatwo i wydajnie przetwarzać zarówno dane ustrukturyzowane, jak i nieustrukturyzowane.

  • Obsługiwane języki programowania:
    API RDD jest dostępne w Javie, Scali, Python i R.

Ograniczenia RDD: -

  • Brak wbudowanego silnika optymalizacyjnego: podczas pracy z danymi strukturalnymi RDD nie mogą korzystać z zaawansowanych optymalizatorów Spark, w tym optymalizatora katalizatora i silnika wykonawczego wolframu. Programiści muszą zoptymalizować każdy RDD na podstawie jego atrybutów.

  • Obsługa danych strukturalnych: W przeciwieństwie do ramek danych i zestawów danych, RDD nie wywnioskują schematu pobieranych danych i wymagają od użytkownika ich określenia.

Ramki danych

Spark wprowadził Dataframes w wersji Spark 1.3. Ramka danych pozwala przezwyciężyć kluczowe wyzwania związane z RDD.

DataFrame to rozproszony zbiór danych zorganizowany w nazwane kolumny. Jest to koncepcyjnie ekwiwalent tabeli w relacyjnej bazie danych lub ramce danych R / Python. Wraz z Dataframe, Spark wprowadził także optymalizator katalizatora, który wykorzystuje zaawansowane funkcje programowania do budowy rozszerzalnego optymalizatora zapytań.

Funkcje ramki danych: -

  • Rozproszony zbiór obiektu Row: DataFrame to rozproszony zbiór danych zorganizowany w nazwane kolumny. Jest to koncepcyjnie odpowiednik tabeli w relacyjnej bazie danych, ale z bogatszymi optymalizacjami pod maską.

  • Przetwarzanie danych: Przetwarzanie ustrukturyzowanych i nieustrukturyzowanych formatów danych (Avro, CSV, wyszukiwanie elastyczne i Cassandra) oraz systemów pamięci masowej (HDFS, tabele HIVE, MySQL itp.). Może czytać i pisać ze wszystkich tych różnych źródeł danych.

  • Optymalizacja za pomocą optymalizatora katalizatora: obsługuje zarówno zapytania SQL, jak i interfejs DataFrame API. Ramka danych wykorzystuje szkielet transformacji drzewa katalizatora w czterech fazach,

     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.
    
  • Zgodność gałęzi: Korzystając ze Spark SQL, możesz uruchamiać niezmodyfikowane zapytania Hive w istniejących magazynach Hive. Ponownie wykorzystuje interfejs Hive i interfejs MetaStore i zapewnia pełną zgodność z istniejącymi danymi Hive, zapytaniami i UDF.

  • Tungsten: Tungsten zapewnia fizyczny backend wykonawczy, który jawnie zarządza pamięcią i dynamicznie generuje kod bajtowy do oceny wyrażenia.

  • Obsługiwane języki programowania:
    Dataframe API jest dostępne w Javie, Scali, Python i R.

Ograniczenia ramki danych: -

  • Bezpieczeństwo typu kompilacji: Jak omówiono, interfejs API Dataframe nie obsługuje bezpieczeństwa kompilacji w czasie, co ogranicza manipulowanie danymi, gdy struktura nie jest znana. Poniższy przykład działa podczas kompilacji. Jednak podczas wykonywania tego kodu pojawi się wyjątek Runtime.

Przykład:

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

Jest to szczególnie trudne, gdy pracujesz z kilkoma etapami transformacji i agregacji.

  • Nie można operować na obiekcie domeny (utracony obiekt domeny): po przekształceniu obiektu domeny w ramkę danych nie można go ponownie wygenerować. W poniższym przykładzie, po utworzeniu personDF z personRDD, nie odzyskamy oryginalnego RDD klasy Person (RDD [Person]).

Przykład:

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]

Interfejs API zestawów danych

Dataset API to rozszerzenie DataFrames, które zapewnia bezpieczny dla obiektów, zorientowany obiektowo interfejs programowania. Jest to mocno wpisana, niezmienna kolekcja obiektów, które są odwzorowane na schemat relacyjny.

U podstaw zestawu danych API jest nowa koncepcja zwana enkoderem, która odpowiada za konwersję między obiektami JVM i reprezentacją tabelaryczną. Reprezentacja tabelaryczna jest przechowywana przy użyciu wewnętrznego formatu binarnego Tungsten Spark, co pozwala na operacje na danych szeregowych i lepsze wykorzystanie pamięci. Spark 1.6 zapewnia obsługę automatycznego generowania koderów dla wielu różnych typów, w tym typów pierwotnych (np. String, Integer, Long), klas przypadków Scala i Java Beans.

Funkcje zestawu danych: -

  • Zapewnia najlepsze cechy zarówno RDD, jak i Dataframe: RDD (programowanie funkcjonalne, bezpieczny typ), DataFrame (model relacyjny, optymalizacja zapytania, wykonanie wolframu, sortowanie i tasowanie)

  • Enkodery: Za pomocą Enkoderów łatwo jest przekonwertować dowolny obiekt JVM na zestaw danych, umożliwiając użytkownikom pracę z danymi zarówno strukturalnymi, jak i nieustrukturyzowanymi, w przeciwieństwie do Dataframe.

  • Obsługiwane języki programowania: zestawy danych API są obecnie dostępne tylko w Scali i Javie. Python i R nie są obecnie obsługiwane w wersji 1.6. Obsługa języka Python jest przewidziana dla wersji 2.0.

  • Bezpieczeństwo typu: Zestaw danych API zapewnia bezpieczeństwo czasu kompilacji, które nie było dostępne w ramkach danych. W poniższym przykładzie możemy zobaczyć, jak zestaw danych może działać na obiektach domeny z kompilowanymi funkcjami lambda.

Przykład:

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]
  • Interoperacyjność: zestawy danych pozwalają na łatwą konwersję istniejących RDD i ramek danych na zestawy danych bez kodu płyty wzorcowej.

Ograniczenia API zestawów danych: -

  • Wymaga rzutowania typu na String: Kwerenda danych z zestawów danych wymaga obecnie, abyśmy określili pola w klasie jako string. Po zapytaniu o dane jesteśmy zmuszeni rzutować kolumnę na wymagany typ danych. Z drugiej strony, jeśli użyjemy operacji mapy na zestawach danych, nie użyje ona optymalizatora Catalyst.

Przykład:

ds.select(col("name").as[String], $"age".as[Int]).collect()

Brak obsługi Python i R: Od wersji 1.6 zestawy danych obsługują tylko Scala i Java. Obsługa języka Python zostanie wprowadzona w Spark 2.0.

Interfejs API zestawów danych ma kilka zalet w porównaniu z istniejącym interfejsem RDD i interfejsem Dataframe API, zapewniając lepsze bezpieczeństwo typów i funkcjonalne programowanie. W przypadku wymagań związanych z rzutowaniem typów w interfejsie API nadal nie będzie wymagane bezpieczeństwo typów i spowoduje to, że kod będzie kruchy.


2
Od spark.apache.org/docs/latest/… W interfejsie API Scala DataFrame jest po prostu typem aliasu zestawu danych [Row].
Dean Chen

więc czy można powiedzieć, że dzięki zestawowi danych zyskujemy bezpieczeństwo typu i tracimy optymalizator?
Khoa

@BlueSky zyskujesz bezpieczeństwo typu i nadal masz optymalizator
Gabber

@AmitDubey To po prostu nieprawda. Datasetnie jest LINQ, a wyrażenia lambda nie można interpretować jako drzewa wyrażeń. Dlatego istnieją czarne skrzynki i tracisz prawie wszystkie (jeśli nie wszystkie) korzyści związane z optymalizacją. Tylko niewielki podzbiór możliwych wad: Spark 2.0 Dataset vs. DataFrame . Ponadto, aby powtórzyć coś, co powiedziałem wiele razy - ogólnie rzecz biorąc, kompletne sprawdzanie typu nie jest możliwe z DatasetAPI. Połączenia są tylko najbardziej znanym przykładem.
zero323

52

Wszystko (RDD, DataFrame i DataSet) na jednym zdjęciu.

RDD vs DataFrame vs DataSet

kredyty graficzne

RDD

RDD to odporny na uszkodzenia zbiór elementów, na których można operować równolegle.

DataFrame

DataFrameto zestaw danych zorganizowany w nazwane kolumny. Jest to koncepcyjnie ekwiwalent tabeli w relacyjnej bazie danych lub ramki danych w R / Python, ale z bogatszymi optymalizacjami pod maską .

Dataset

Datasetto rozproszony zbiór danych. Zestaw danych to nowy interfejs dodany w Spark 1.6, który zapewnia zalety RDD (silne pisanie, możliwość korzystania z potężnych funkcji lambda) z korzyściami zoptymalizowanego silnika wykonawczego Spark SQL .


Uwaga:

Zestaw danych Rows ( Dataset[Row]) w Scala / Java będzie często określany jako DataFrames .


Nice comparison of all of them with a code snippet.

RDD vs DataFrame vs DataSet z kodem

źródło


P: Czy możesz przekonwertować jeden na drugi, np. RDD na DataFrame lub odwrotnie?

Tak, oba są możliwe

1. RDDdo DataFramez.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|
+------+----+----+

więcej sposobów: Konwertuj obiekt RDD na ramkę danych w Spark

2 DataFrame/ DataSetdo RDDz .rdd()Sposób

val rowsRdd: RDD[Row] = df.rdd() // DataFrame to RDD

27

Ponieważ DataFramejest słabo wpisany, a programiści nie czerpią korzyści z tego systemu. Załóżmy na przykład, że chcesz przeczytać coś z SQL i uruchomić na nim agregację:

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")))

Kiedy mówisz people("deptId"), że nie odzyskujesz Intani Longnie odzyskujesz Columnobiektu, na którym musisz operować. W językach z bogatym systemem typów, takim jak Scala, tracisz bezpieczeństwo typu, co zwiększa liczbę błędów w czasie wykonywania dla rzeczy, które można wykryć w czasie kompilacji.

Przeciwnie, DataSet[T]jest wpisany. kiedy to zrobisz:

val people: People = val people = sqlContext.read.parquet("...").as[People]

W rzeczywistości odzyskujesz Peopleobiekt, w którym deptIdjest to rzeczywisty typ całkowy, a nie typ kolumny, wykorzystując w ten sposób system typów.

Począwszy od Spark 2.0, interfejsy API DataFrame i DataSet zostaną ujednolicone, gdzie DataFramebędzie alias typu DataSet[Row].


5
Mówiąc dokładniej, jak w przypadku Spark 2.0, Dataframe to tylko pseudonim dlaDataset[Row]
zero323

1
@ zero323 Tak, rzeczywiście, ale to wciąż słabo napisane, to właśnie starałem się przekazać.
Yuval Itzchakov

Tak, ale to bardziej kwestia przechowywanych wartości niż samego kontenera. Nawet w wersji 1.6 te dwa były technicznie identyczne, a głównym powodem, aby się rozdzielić, DataFramebyło uniknięcie łamania zmian API. W każdym razie chciałem tylko to podkreślić. Dzięki za edycję i głosowanie ode mnie.
zero323

25

Po prostu RDDjest podstawowym składnikiem, ale DataFramejest API wprowadzonym w wersji 1.30.

RDD

Zbiór partycji danych o nazwie RDD. Te RDDmuszą przestrzegać kilka właściwości taki jest:

  • Niezmienny,
  • Odporne na uszkodzenia,
  • Rozpowszechniane,
  • Więcej.

Tutaj RDDjest albo ustrukturyzowany, albo nieustrukturyzowany.

Ramka danych

DataFramejest interfejsem API dostępnym w Scali, Javie, Pythonie i R. Pozwala na przetwarzanie dowolnego typu danych strukturalnych i częściowo ustrukturyzowanych. Aby zdefiniować DataFrame, zbiór danych rozproszonych zorganizowanych w nazwane kolumny o nazwie DataFrame. Możesz łatwo zoptymalizować RDDsw DataFrame. Możesz przetwarzać dane JSON, dane parkietu, dane HiveQL jednocześnie za pomocą DataFrame.

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

val sample_DF = sampleRDD.toDF()

Tutaj Sample_DF uważa się za DataFrame. sampleRDDnazywa się (surowe dane) RDD.


12

Większość odpowiedzi jest poprawnych, chcę tu dodać tylko jeden punkt

W Spark 2.0 dwa interfejsy API (DataFrame + DataSet) zostaną zjednoczone w jeden interfejs API.

„Unifikacja DataFrame i zestawu danych: W Scali i Javie DataFrame i zestaw danych zostały ujednolicone, tzn. DataFrame jest tylko aliasem typu dla zestawu danych Row. W Pythonie i R, ze względu na brak bezpieczeństwa typu, DataFrame jest głównym interfejsem programistycznym”.

Zestawy danych są podobne do RDD, jednak zamiast serializacji Java lub Kryo używają specjalizowanego enkodera do serializacji obiektów do przetwarzania lub transmisji przez sieć.

Spark SQL obsługuje dwie różne metody konwertowania istniejących RDD na zestawy danych. Pierwsza metoda wykorzystuje odbicie do wnioskowania o schemacie RDD, który zawiera określone typy obiektów. To podejście oparte na refleksji prowadzi do bardziej zwięzłego kodu i działa dobrze, gdy znasz już schemat podczas pisania aplikacji Spark.

Drugą metodą tworzenia zestawów danych jest interfejs programistyczny, który pozwala skonstruować schemat, a następnie zastosować go do istniejącego RDD. Chociaż ta metoda jest bardziej szczegółowa, umożliwia ona tworzenie zestawów danych, gdy kolumny i ich typy nie są znane aż do czasu wykonania.

Tutaj można znaleźć odpowiedź na konwersję z ramką danych RDD

Jak przekonwertować obiekt rdd na ramkę danych w iskrze


8

DataFrame jest odpowiednikiem tabeli w RDBMS i może być również manipulowany w podobny sposób jak „natywne” kolekcje rozproszone w RDD. W przeciwieństwie do RDD, ramki danych śledzą schemat i obsługują różne operacje relacyjne, które prowadzą do bardziej zoptymalizowanego wykonania. Każdy obiekt DataFrame reprezentuje logiczny plan, ale ze względu na jego „leniwą” naturę wykonywanie nie następuje, dopóki użytkownik nie wywoła określonej „operacji wyjściowej”.


2
Nawiasem mówiąc, RDD są również leniwe.
kon psych

6

Kilka spostrzeżeń z perspektywy użytkowania, RDD vs DataFrame:

  1. RDD są niesamowite! ponieważ dają nam pełną elastyczność w radzeniu sobie z prawie każdym rodzajem danych; nieustrukturyzowane, częściowo ustrukturyzowane i uporządkowane dane. Ponieważ wiele razy dane nie są gotowe do umieszczenia w ramce danych (nawet JSON), RDD można wykorzystać do wstępnego przetwarzania danych, aby zmieściły się w ramce danych. RDD są podstawową abstrakcją danych w Spark.
  2. Nie wszystkie transformacje, które są możliwe na RDD, są możliwe na DataFrame, przykładowe odejmowanie () jest dla RDD w porównaniu z wyjątkiem () dla DataFrame.
  3. Ponieważ DataFrames są jak tabela relacyjna, podczas korzystania z transformacji teorii zestawów / relacji stosują się do ścisłych zasad, na przykład jeśli chcesz połączyć dwie ramki danych, wymagane jest, aby oba dfs miały taką samą liczbę kolumn i powiązane typy danych kolumn. Nazwy kolumn mogą być różne. Te zasady nie dotyczą RDD. Oto dobry samouczek wyjaśniający te fakty.
  4. Korzystanie z DataFrames przynosi wzrost wydajności, jak inni już szczegółowo wyjaśnili.
  5. Korzystając z DataFrames, nie musisz przekazywać dowolnej funkcji, tak jak robisz to podczas programowania z RDD.
  6. Potrzebujesz SQLContext / HiveContext do programowania ramek danych, ponieważ leżą one w obszarze SparkSQL w ekosystemie Spark, ale do RDD potrzebujesz tylko SparkContext / JavaSparkContext, które znajdują się w bibliotekach Spark Core.
  7. Możesz utworzyć plik df z RDD, jeśli możesz zdefiniować dla niego schemat.
  8. Możesz także przekonwertować plik df na rdd i rdd na df.

Mam nadzieję, że to pomoże!


5

Ramka danych to RDD obiektów Row, z których każdy reprezentuje rekord. Ramka danych zna również schemat (tj. Pola danych) swoich wierszy. Podczas gdy ramki danych wyglądają jak zwykłe RDD, wewnętrznie przechowują dane w bardziej wydajny sposób, wykorzystując ich schemat. Ponadto zapewniają nowe operacje niedostępne na RDD, takie jak możliwość uruchamiania zapytań SQL. Ramki danych można tworzyć z zewnętrznych źródeł danych, z wyników zapytań lub ze zwykłych RDD.

Odnośnik: Zaharia M., i in. Learning Spark (O'Reilly, 2015)


1

Spark RDD (resilient distributed dataset) :

RDD jest podstawowym interfejsem API do pozyskiwania danych i jest dostępny od pierwszego wydania Spark (Spark 1.0). Jest to interfejs API niższego poziomu do manipulowania rozproszonym zbieraniem danych. Interfejsy API RDD ujawniają niektóre niezwykle przydatne metody, których można użyć, aby uzyskać bardzo ścisłą kontrolę nad fizyczną strukturą danych. Jest to niezmienny (tylko do odczytu) zbiór podzielonych na partycje danych dystrybuowanych na różnych komputerach. RDD umożliwia obliczenia w pamięci dużych klastrów, aby przyspieszyć przetwarzanie dużych danych w sposób odporny na uszkodzenia. Aby włączyć odporność na uszkodzenia, RDD używa DAG (Directed Acyclic Graph), który składa się z zestawu wierzchołków i krawędzi. Wierzchołki i krawędzie w DAG reprezentują odpowiednio RDD i operację, którą należy zastosować na tym RDD. Transformacje zdefiniowane na RDD są leniwe i są wykonywane tylko po wywołaniu akcji

Spark DataFrame :

Spark 1.3 wprowadził dwa nowe interfejsy API do pozyskiwania danych - DataFrame i DataSet. Interfejsy API DataFrame organizują dane w nazwane kolumny jak tabela w relacyjnej bazie danych. Umożliwia programistom zdefiniowanie schematu na rozproszonym zbiorze danych. Każdy wiersz w ramce danych ma wiersz typu obiektu. Podobnie jak tabela SQL, każda kolumna musi mieć taką samą liczbę wierszy w ramce danych. W skrócie, DataFrame to leniwie oceniany plan, który określa operacje, które należy wykonać na rozproszonym zbiorze danych. DataFrame to także niezmienna kolekcja.

Spark DataSet :

Jako rozszerzenie API DataFrame, Spark 1.3 wprowadził również API DataSet, które zapewniają ściśle typowy i obiektowy interfejs programistyczny w Spark. Jest to niezmienne, bezpieczne dla typu zbieranie rozproszonych danych. Podobnie jak DataFrame, interfejsy API DataSet również wykorzystują silnik Catalyst w celu umożliwienia optymalizacji wykonywania. DataSet to rozszerzenie interfejsów API DataFrame.

Other Differences -

wprowadź opis zdjęcia tutaj


0

DataFrame jest RDD który ma schematu. Możesz myśleć o tym jak o tabeli relacyjnej bazy danych, ponieważ każda kolumna ma nazwę i znany typ. Potęga DataFrames wynika z faktu, że podczas tworzenia DataFrame ze strukturalnego zestawu danych (Json, Parquet ..) Spark jest w stanie wywnioskować schemat, przechodząc przez cały zestaw danych (Json, Parquet ..) jest ładowany. Następnie, podczas obliczania planu wykonania, Spark może korzystać ze schematu i wykonywać znacznie lepsze optymalizacje obliczeń. Należy pamiętać, że DataFrame był nazywany SchemaRDD przed Spark v1.3.0


0

Apache Spark - RDD, DataFrame i DataSet

Spark RDD -

RDD oznacza Resilient Distributed Datasets. Jest to zbiór rekordów tylko do odczytu partycji. RDD jest podstawową strukturą danych Spark. Umożliwia programistom wykonywanie obliczeń w pamięci dużych klastrów w sposób odporny na uszkodzenia. Przyspiesz więc zadanie.

Spark Dataframe -

W przeciwieństwie do RDD, dane zorganizowane w nazwane kolumny. Na przykład tabela w relacyjnej bazie danych. Jest to niezmienny rozproszony zbiór danych. DataFrame w Spark pozwala programistom nałożyć strukturę na rozproszony zbiór danych, umożliwiając abstrakcję wyższego poziomu.

Spark Dataset -

Zestawy danych w Apache Spark są rozszerzeniem DataFrame API, które zapewnia bezpieczny, obiektowy interfejs programowania. Zestaw danych wykorzystuje optymalizator Catalyst Spark'a, udostępniając wyrażenia i pola danych planerowi zapytań.


-1

Możesz używać RDD z danymi strukturalnymi i nieustrukturyzowanymi, gdzie jako ramka danych / zestaw danych może przetwarzać tylko dane ustrukturyzowane i częściowo ustrukturyzowane (ma odpowiedni schemat)


-2

Wszystkie świetne odpowiedzi i używanie każdego API ma pewne kompromisy. Zestaw danych jest zbudowany jako super API, aby rozwiązać wiele problemów, ale wiele razy RDD nadal działa najlepiej, jeśli rozumiesz swoje dane, a jeśli algorytm przetwarzania jest zoptymalizowany do wykonywania wielu rzeczy w jednym przejściu do dużych danych, RDD wydaje się najlepszą opcją.

Agregacja za pomocą interfejsu API zestawu danych nadal zużywa pamięć i z czasem będzie się poprawiać.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.