Eu só estou querendo saber qual é a diferença entre um RDD
e DataFrame
(Spark 2.0.0 DataFrame é um mero tipo de alias para Dataset[Row]
) no Apache Spark?
Você pode converter um para o outro?
Eu só estou querendo saber qual é a diferença entre um RDD
e DataFrame
(Spark 2.0.0 DataFrame é um mero tipo de alias para Dataset[Row]
) no Apache Spark?
Você pode converter um para o outro?
Respostas:
A DataFrame
é bem definido com uma pesquisa no Google por "definição de DataFrame":
Um quadro de dados é uma tabela ou estrutura bidimensional do tipo matriz, em que cada coluna contém medidas em uma variável e cada linha contém um caso.
Portanto, a DataFrame
possui metadados adicionais devido ao seu formato tabular, o que permite ao Spark executar certas otimizações na consulta finalizada.
Um RDD
, por outro lado, é apenas um de R esilient D istributed D ataset que é mais de uma caixa negra de dados que não podem ser optimizadas como as operações que podem ser executadas de encontro a ele, não é tão limitada.
No entanto, você pode passar de um DataFrame para um RDD
via seu rdd
método e de um RDD
para um DataFrame
(se o RDD estiver em um formato tabular) através do toDF
método
Em geral , é recomendável usar um sempre DataFrame
que possível devido à otimização de consulta integrada.
A primeira coisa é que
DataFrame
evoluiuSchemaRDD
.
Sim .. conversão entre Dataframe
e RDD
é absolutamente possível.
Abaixo estão alguns trechos de código de exemplo.
df.rdd
é RDD[Row]
Abaixo estão algumas das opções para criar o quadro de dados.
1) yourrddOffrow.toDF
converte para DataFrame
.
2) Uso createDataFrame
do contexto sql
val df = spark.createDataFrame(rddOfRow, schema)
onde o esquema pode ser de algumas das opções abaixo, conforme descrito na boa postagem SO.
Da classe de caso scala e da API de reflexão do scalaimport org.apache.spark.sql.catalyst.ScalaReflection val schema = ScalaReflection.schemaFor[YourScalacaseClass].dataType.asInstanceOf[StructType]
OU usando
Encoders
import org.apache.spark.sql.Encoders val mySchema = Encoders.product[MyCaseClass].schema
como descrito pelo esquema também pode ser criado usando
StructType
eStructField
val schema = new StructType() .add(StructField("id", StringType, true)) .add(StructField("col1", DoubleType, true)) .add(StructField("col2", DoubleType, true)) etc...
De fato, existem agora três APIs Apache Spark.
RDD
API:A
RDD
API (Conjunto de dados distribuídos resilientes) está no Spark desde a versão 1.0.A
RDD
API fornece muitos métodos de transformação, comomap
(),filter
() ereduce
() para executar cálculos nos dados. Cada um desses métodos resulta em um novoRDD
representando os dados transformados. No entanto, esses métodos estão apenas definindo as operações a serem executadas e as transformações não são executadas até que um método de ação seja chamado. Exemplos de métodos de ação sãocollect
() esaveAsObjectFile
().
Exemplo de RDD:
rdd.filter(_.age > 21) // transformation
.map(_.last)// transformation
.saveAsObjectFile("under21.bin") // action
Exemplo: Filtrar por Atributo com RDD
rdd.filter(_.age > 21)
DataFrame
APIO Spark 1.3 introduziu uma nova
DataFrame
API como parte da iniciativa do Project Tungsten, que busca melhorar o desempenho e a escalabilidade do Spark. ADataFrame
API introduz o conceito de um esquema para descrever os dados, permitindo que o Spark gerencie o esquema e passe dados apenas entre nós, de uma maneira muito mais eficiente do que usar a serialização Java.A
DataFrame
API é radicalmente diferente daRDD
API porque é uma API para a construção de um plano de consulta relacional que o otimizador Catalyst do Spark pode executar. A API é natural para desenvolvedores familiarizados com a criação de planos de consulta
Exemplo de estilo SQL:
df.filter("age > 21");
Limitações: como o código está se referindo aos atributos de dados por nome, não é possível que o compilador detecte erros. Se os nomes dos atributos estiverem incorretos, o erro será detectado apenas no tempo de execução, quando o plano de consulta for criado.
Outra desvantagem da DataFrame
API é que ela é muito centrada na escala e, embora ofereça suporte a Java, o suporte é limitado.
Por exemplo, ao criar a DataFrame
partir RDD
de objetos Java existentes , o otimizador Catalyst do Spark não pode inferir o esquema e pressupõe que quaisquer objetos no DataFrame implementem a scala.Product
interface. Scala case class
trabalha fora da caixa porque eles implementam essa interface.
Dataset
APIA
Dataset
API, lançada como uma visualização da API no Spark 1.6, visa fornecer o melhor dos dois mundos; o estilo familiar de programação orientada a objetos e a segurança de tipo em tempo de compilação daRDD
API, mas com os benefícios de desempenho do otimizador de consulta do Catalyst. Os conjuntos de dados também usam o mesmo mecanismo eficiente de armazenamento fora da pilha que aDataFrame
API.Quando se trata de serializar dados, a
Dataset
API tem o conceito de codificadores que traduzem entre representações da JVM (objetos) e o formato binário interno do Spark. O Spark possui codificadores internos muito avançados, pois geram código de bytes para interagir com dados fora da pilha e fornecem acesso sob demanda a atributos individuais sem precisar desserializar um objeto inteiro. O Spark ainda não fornece uma API para implementar codificadores personalizados, mas está planejada para uma versão futura.Além disso, a
Dataset
API foi projetada para funcionar igualmente bem com Java e Scala. Ao trabalhar com objetos Java, é importante que eles sejam totalmente compatíveis com o bean.
Exemplo de Dataset
estilo SQL da API:
dataset.filter(_.age < 21);
Avaliações diff. entre DataFrame
& DataSet
:
Fluxo de nível catalítico. (Desmistificando a apresentação do DataFrame e do conjunto de dados do spark summit)
Leia mais ... artigo databricks - Um conto de três APIs do Apache Spark: RDDs vs DataFrames e conjuntos de dados
df.filter("age > 21");
isso pode ser avaliado / analisado apenas em tempo de execução. desde a sua string. No caso de conjuntos de dados, os conjuntos de dados são compatíveis com o bean. então a idade é propriedade do bean. se a propriedade age não estiver presente no seu bean, você saberá cedo no tempo de compilação (ie dataset.filter(_.age < 21);
). O erro de análise pode ser renomeado como erros de avaliação.
O Apache Spark fornece três tipos de APIs
Aqui está a comparação de APIs entre RDD, Dataframe e Dataset.
A principal abstração que o Spark fornece é um conjunto de dados distribuído resiliente (RDD), que é uma coleção de elementos particionados entre os nós do cluster que podem ser operados em paralelo.
Coleção distribuída: o
RDD usa operações MapReduce que são amplamente adotadas para processar e gerar grandes conjuntos de dados com um algoritmo distribuído paralelo em um cluster. Ele permite que os usuários escrevam cálculos paralelos, usando um conjunto de operadores de alto nível, sem ter que se preocupar com a distribuição do trabalho e a tolerância a falhas.
Imutável: RDDs compostos por uma coleção de registros que são particionados. Uma partição é uma unidade básica de paralelismo em um RDD, e cada partição é uma divisão lógica de dados que é imutável e criada através de algumas transformações nas partições existentes. A imutabilidade ajuda a obter consistência nos cálculos.
Tolerante a falhas: no caso de perdermos uma partição do RDD, podemos reproduzir a transformação nessa partição na linhagem para obter o mesmo cálculo, em vez de fazer a replicação de dados em vários nós. Essa característica é o maior benefício do RDD, pois economiza muitos esforços no gerenciamento e replicação de dados e, portanto, obtém cálculos mais rápidos.
Avaliações preguiçosas: todas as transformações no Spark são preguiçosas, pois não calculam seus resultados imediatamente. Em vez disso, eles apenas lembram as transformações aplicadas a algum conjunto de dados base. As transformações são computadas apenas quando uma ação exige que um resultado seja retornado ao programa do driver.
Transformações funcionais: os RDDs suportam dois tipos de operações: transformações, que criam um novo conjunto de dados a partir de um já existente, e ações, que retornam um valor ao programa do driver após executar uma computação no conjunto de dados.
Formatos de processamento de dados:
ele pode processar com facilidade e eficiência os dados estruturados e não estruturados.
Linguagens de programação suportadas: A
API RDD está disponível em Java, Scala, Python e R.
Nenhum mecanismo de otimização embutido: Ao trabalhar com dados estruturados, os RDDs não podem tirar proveito dos otimizadores avançados do Spark, incluindo o otimizador de catalisador e o mecanismo de execução de tungstênio. Os desenvolvedores precisam otimizar cada RDD com base em seus atributos.
Manipulando Dados Estruturados: Ao contrário do Dataframe e dos conjuntos de dados, os RDDs não inferem o esquema dos dados ingeridos e exigem que o usuário os especifique.
O Spark introduziu Dataframes na versão Spark 1.3. O Dataframe supera os principais desafios que os RDDs tiveram.
Um DataFrame é uma coleção distribuída de dados organizados em colunas nomeadas. É conceitualmente equivalente a uma tabela em um banco de dados relacional ou em um Dataframe do R / Python. Juntamente com o Dataframe, o Spark também introduziu o otimizador de catalisador, que utiliza recursos avançados de programação para criar um otimizador de consulta extensível.
Coleção distribuída de objeto de linha: Um DataFrame é uma coleção distribuída de dados organizados em colunas nomeadas. É conceitualmente equivalente a uma tabela em um banco de dados relacional, mas com otimizações mais avançadas sob o capô.
Processamento de dados: processamento de formatos de dados estruturados e não estruturados (Avro, CSV, pesquisa elástica e Cassandra) e sistemas de armazenamento (HDFS, tabelas HIVE, MySQL, etc). Ele pode ler e escrever em todas essas várias fontes de dados.
Otimização usando o otimizador de catalisador: ele habilita as consultas SQL e a API DataFrame. O Dataframe usa a estrutura de transformação de árvore catalisadora em quatro fases,
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.
Compatibilidade do Hive: Usando o Spark SQL, você pode executar consultas do Hive não modificadas nos seus armazéns do Hive existentes. Ele reutiliza o Hive frontend e o MetaStore e oferece total compatibilidade com dados, consultas e UDFs existentes do Hive.
Tungstênio: O tungstênio fornece um back-end de execução física, que gerencia explicitamente a memória e gera dinamicamente bytecode para avaliação de expressão.
Linguagens de programação suportadas: a
API Dataframe está disponível em Java, Scala, Python e R.
Exemplo:
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
Isso é um desafio especialmente quando você está trabalhando com várias etapas de transformação e agregação.
Exemplo:
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]
A API do conjunto de dados é uma extensão do DataFrames que fornece uma interface de programação orientada a objeto e com segurança de tipo. É uma coleção imutável de objetos fortemente tipados que são mapeados para um esquema relacional.
No centro do conjunto de dados, a API é um novo conceito chamado codificador, responsável pela conversão entre objetos JVM e representação tabular. A representação tabular é armazenada usando o formato binário interno de tungstênio Spark, permitindo operações em dados serializados e melhor utilização da memória. O Spark 1.6 vem com suporte para a geração automática de codificadores para uma ampla variedade de tipos, incluindo tipos primitivos (por exemplo, String, Inteiro, Longo), classes de caso Scala e Java Beans.
Oferece o melhor do RDD e do Dataframe: RDD (programação funcional, tipo seguro), DataFrame (modelo relacional, otimização de consultas, execução de tungstênio, classificação e shuffling)
Codificadores: Com o uso de codificadores, é fácil converter qualquer objeto da JVM em um conjunto de dados, permitindo que os usuários trabalhem com dados estruturados e não estruturados, diferentemente do Dataframe.
Linguagens de programação suportadas: atualmente, a API de conjuntos de dados está disponível apenas no Scala e Java. Atualmente, Python e R não são suportados na versão 1.6. O suporte ao Python está previsto para a versão 2.0.
Segurança de tipo: a API de conjuntos de dados fornece segurança em tempo de compilação que não estava disponível nos quadros de dados. No exemplo abaixo, podemos ver como o Dataset pode operar em objetos de domínio com funções lambda de compilação.
Exemplo:
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]
Exemplo:
ds.select(col("name").as[String], $"age".as[Int]).collect()
Sem suporte para Python e R: A partir da versão 1.6, os conjuntos de dados suportam apenas Scala e Java. O suporte ao Python será introduzido no Spark 2.0.
A API de conjuntos de dados traz várias vantagens sobre a API RDD e Dataframe existente com melhor segurança de tipo e programação funcional. Com o desafio dos requisitos de conversão de tipo na API, você ainda não teria a segurança de tipo necessária e tornará seu código frágil.
Dataset
não é LINQ e a expressão lambda não pode ser interpretada como árvores de expressão. Portanto, existem caixas pretas e você perde praticamente todos os benefícios do otimizador (se não todos). Apenas um pequeno subconjunto de possíveis desvantagens: Spark 2.0 Dataset vs DataFrame . Além disso, apenas para repetir algo que afirmei várias vezes - em geral, a verificação de tipo de ponta a ponta não é possível com a Dataset
API. As junções são apenas o exemplo mais importante.
RDD
RDD
é uma coleção de elementos tolerantes a falhas que podem ser operados em paralelo.
DataFrame
DataFrame
é um conjunto de dados organizado em colunas nomeadas. É conceitualmente equivalente a uma tabela em um banco de dados relacional ou um quadro de dados no R / Python, mas com otimizações mais avançadas sob o capô .
Dataset
Dataset
é uma coleção distribuída de dados. O Dataset é uma nova interface adicionada no Spark 1.6 que fornece os benefícios dos RDDs (digitação forte, capacidade de usar funções lambda poderosas) com os benefícios do mecanismo de execução otimizado do Spark SQL .
Nota:
O conjunto de dados de linhas (
Dataset[Row]
) no Scala / Java geralmente se refere a DataFrames .
Nice comparison of all of them with a code snippet.
P: Você pode converter um para o outro, como RDD em DataFrame ou vice-versa?
1. RDD
para DataFrame
com.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|
+------+----+----+
mais maneiras: Converter um objeto RDD em Dataframe no Spark
2. DataFrame
/ DataSet
to RDD
com .rdd()
método
val rowsRdd: RDD[Row] = df.rdd() // DataFrame to RDD
Porque DataFrame
é mal digitado e os desenvolvedores não estão obtendo os benefícios do sistema de tipos. Por exemplo, digamos que você queira ler algo do SQL e executar alguma agregação:
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")))
Quando você diz people("deptId")
que não está recebendo de volta um objeto Int
, ou a Long
, está recuperando um Column
objeto no qual precisa operar. Em idiomas com sistemas de tipos avançados, como o Scala, você acaba perdendo toda a segurança de tipos, o que aumenta o número de erros em tempo de execução para itens que podem ser descobertos em tempo de compilação.
Pelo contrário, DataSet[T]
é digitado. quando você faz:
val people: People = val people = sqlContext.read.parquet("...").as[People]
Na verdade, você está recuperando um People
objeto, onde deptId
é um tipo integral real e não um tipo de coluna, aproveitando assim o sistema de tipos.
A partir do Spark 2.0, as APIs DataFrame e DataSet serão unificadas, onde DataFrame
haverá um alias de tipo para DataSet[Row]
.
DataFrame
foi evitar alterações de API. Enfim, só queria salientar. Obrigado pela edição e voto positivo de mim.
Simplesmente RDD
é o componente principal, mas DataFrame
é uma API introduzida no spark 1.30.
Coleta de partições de dados chamadas RDD
. Estes RDD
devem seguir algumas propriedades, como:
Aqui RDD
é estruturado ou não estruturado.
DataFrame
é uma API disponível em Scala, Java, Python e R. Permite processar qualquer tipo de dados estruturados e semiestruturados. Para definir DataFrame
, uma coleção de dados distribuídos organizados em colunas nomeadas é chamada DataFrame
. Pode facilmente optimizar o RDDs
no DataFrame
. Você pode processar dados JSON, dados de parquet e dados do HiveQL por vez usando DataFrame
.
val sampleRDD = sqlContext.jsonFile("hdfs://localhost:9000/jsondata.json")
val sample_DF = sampleRDD.toDF()
Aqui Sample_DF considera como DataFrame
. sampleRDD
é (dados brutos) chamado RDD
.
A maioria das respostas está correta, só quero adicionar um ponto aqui
No Spark 2.0, as duas APIs (DataFrame + DataSet) serão unificadas em uma única API.
"Unificando o DataFrame e o conjunto de dados: no Scala e Java, o DataFrame e o conjunto de dados foram unificados, ou seja, o DataFrame é apenas um alias de tipo para o conjunto de dados da linha. No Python e R, dada a falta de segurança do tipo, o DataFrame é a principal interface de programação."
Os conjuntos de dados são semelhantes aos RDDs, no entanto, em vez de usar a serialização Java ou o Kryo, eles usam um codificador especializado para serializar os objetos para processamento ou transmissão pela rede.
O Spark SQL suporta dois métodos diferentes para converter RDDs existentes em conjuntos de dados. O primeiro método usa reflexão para inferir o esquema de um RDD que contém tipos específicos de objetos. Essa abordagem baseada em reflexão leva a um código mais conciso e funciona bem quando você já conhece o esquema enquanto escreve seu aplicativo Spark.
O segundo método para criar conjuntos de dados é através de uma interface programática que permite construir um esquema e aplicá-lo a um RDD existente. Embora esse método seja mais detalhado, ele permite construir conjuntos de dados quando as colunas e seus tipos não são conhecidos até o tempo de execução.
Aqui você pode encontrar RDD para resposta de conversação de quadro de dados
Um DataFrame é equivalente a uma tabela no RDBMS e também pode ser manipulado de maneiras semelhantes às coleções distribuídas "nativas" nos RDDs. Ao contrário dos RDDs, os Dataframes controlam o esquema e suportam várias operações relacionais que levam a uma execução mais otimizada. Cada objeto DataFrame representa um plano lógico, mas devido à sua natureza "preguiçosa", nenhuma execução ocorre até que o usuário chame uma "operação de saída" específica.
Espero que ajude!
Um Dataframe é um RDD de objetos Row, cada um representando um registro. Um Dataframe também conhece o esquema (isto é, campos de dados) de suas linhas. Embora os Dataframes pareçam RDDs regulares, internamente eles armazenam dados de uma maneira mais eficiente, aproveitando seu esquema. Além disso, eles fornecem novas operações não disponíveis nos RDDs, como a capacidade de executar consultas SQL. Os quadros de dados podem ser criados a partir de fontes de dados externas, a partir dos resultados de consultas ou de RDDs regulares.
Referência: Zaharia M., et al. Aprendizagem Spark (O'Reilly, 2015)
Spark RDD (resilient distributed dataset)
:
RDD é a principal API de abstração de dados e está disponível desde a primeira versão do Spark (Spark 1.0). É uma API de nível inferior para manipular a coleta distribuída de dados. As APIs do RDD expõem alguns métodos extremamente úteis que podem ser usados para obter um controle muito rígido sobre a estrutura de dados físicos subjacente. É uma coleção imutável (somente leitura) de dados particionados distribuídos em diferentes máquinas. O RDD permite que o cálculo na memória de grandes clusters acelere o processamento de grandes dados de maneira tolerante a falhas. Para ativar a tolerância a falhas, o RDD usa o DAG (Directed Acyclic Graph), que consiste em um conjunto de vértices e arestas. Os vértices e arestas no DAG representam o RDD e a operação a ser aplicada nesse RDD, respectivamente. As transformações definidas no RDD são preguiçosas e são executadas apenas quando uma ação é chamada
Spark DataFrame
:
O Spark 1.3 introduziu duas novas APIs de abstração de dados - DataFrame e DataSet. As APIs do DataFrame organizam os dados em colunas nomeadas como uma tabela no banco de dados relacional. Ele permite que os programadores definam o esquema em uma coleção distribuída de dados. Cada linha em um DataFrame é do tipo de objeto. Como uma tabela SQL, cada coluna deve ter o mesmo número de linhas em um DataFrame. Em resumo, o DataFrame é um plano avaliado preguiçosamente, que especifica que as operações precisam ser executadas na coleta distribuída dos dados. O DataFrame também é uma coleção imutável.
Spark DataSet
:
Como uma extensão das APIs do DataFrame, o Spark 1.3 também introduziu as APIs do DataSet, que fornecem uma interface de programação estritamente tipificada e orientada a objetos no Spark. É uma coleta imutável e segura de dados distribuídos. Como o DataFrame, as APIs do DataSet também usam o mecanismo Catalyst para permitir a otimização da execução. DataSet é uma extensão para as APIs do DataFrame.
Other Differences
-
Um DataFrame é um RDD que possui um esquema. Você pode pensar nisso como uma tabela de banco de dados relacional, em que cada coluna tem um nome e um tipo conhecido. O poder dos DataFrames vem do fato de que, quando você cria um DataFrame a partir de um conjunto de dados estruturado (Json, Parquet ..), o Spark é capaz de inferir um esquema fazendo uma passagem por todo o conjunto de dados (Json, Parquet ..) que é sendo carregado. Então, ao calcular o plano de execução, o Spark, pode usar o esquema e fazer otimizações de computação substancialmente melhores. Observe que o DataFrame foi chamado SchemaRDD antes do Spark v1.3.0
Spark RDD -
Um RDD significa Conjuntos de dados distribuídos resilientes. É uma coleção de registros de partição somente leitura. RDD é a estrutura de dados fundamental do Spark. Ele permite que um programador execute cálculos na memória em grandes grupos de maneira tolerante a falhas. Assim, acelere a tarefa.
Dataframe Spark -
Ao contrário de um RDD, os dados são organizados em colunas nomeadas. Por exemplo, uma tabela em um banco de dados relacional. É uma coleção distribuída imutável de dados. O DataFrame no Spark permite que os desenvolvedores imponham uma estrutura em uma coleção distribuída de dados, permitindo abstração de nível superior.
Conjunto de dados Spark -
Os conjuntos de dados no Apache Spark são uma extensão da API DataFrame, que fornece uma interface de programação orientada a objeto e com segurança de tipo. O conjunto de dados aproveita o otimizador Catalyst do Spark expondo expressões e campos de dados a um planejador de consultas.
Todas as ótimas respostas e o uso de cada API têm algumas vantagens. O conjunto de dados foi criado para ser uma super API para resolver muitos problemas, mas muitas vezes o RDD ainda funciona melhor se você entender seus dados e se o algoritmo de processamento for otimizado para fazer muitas coisas em Passagem única para dados grandes, o RDD parece ser a melhor opção.
A agregação usando a API do conjunto de dados ainda consome memória e melhora com o tempo.