3 Principios de Desenvolvimento de Spark Com Python
3 Principios de Desenvolvimento de Spark Com Python
126 min.
Créditos
Professor (a)
F
FERNANDO DURIER
Introdução
Você sabia que as aplicações de Big Data estão em praticamente todos os setores da
sociedade moderna?
Nesse cenário de oportunidades e desafios, a Apache Foundation desenvolveu o
framework Hadoop: a tecnologia que estudaremos aqui. Além de explorar conceitos,
também vamos demonstrar alguns exemplos práticos que ajudarão você a entender o
funcionamento do Hadoop.
Preparação
Para reproduzir os exemplos apresentados ao longo deste conteúdo, você deve utilizar
o sistema operacional Windows e instalar o Java 8 em seu computador. Além disso,
também precisará instalar o Hadoop.
Objetivos
Ao final desta aula, você será capaz de:
Analisar a arquitetura da tecnologia de framework de software livre chamada Hadoop.
2009
2010
2014
Benefícios do Spark
O Spark se estabeleceu como um framework que tem como benefícios:
monetization_on
Custo
O Spark é um framework de código aberto. Portanto, sua licença é gratuita, assim como
é o caso do Hadoop. Mas, para que o Spark possa ser utilizado na prática, é necessário
usar equipamentos que, obviamente, têm custos.
done_all
Facilidade de uso
Além de oferecer APIs para programação em Java, Scala, Python, linguagem R e SQL, o
Spark também disponibiliza componentes de aplicação, como Hive, Pig, Sqoop, HBase.
library_books
Bibliotecas com diversas finalidades
O Spark produz alto desempenho para processamento de dados em lote e fluxo
(streaming).
speed
Velocidade
O Spark produz alto desempenho para processamento de dados em lote e fluxo
(streaming).
Integração de dados
Aprendizado de máquina
Análise interativa
Atividade
Questão 1
As aplicações de Big Data são dinâmicas e cada vez mais comuns. Então, é necessário
utilizar recursos computacionais, como frameworks e plataformas de desenvolvimento
que auxiliem na criação de aplicações eficientes para atender a essa demanda.
O Spark é um framework de alto desempenho usado com sucesso exatamente para
esse tipo de situação. Nesse sentido, assinale a alternativa correta a respeito do Spark
e seus cenários de aplicação:
Apesar de ser aplicado com sucesso para Big Data, o Spark não é
D adequado para projetos de aprendizado de máquina, devido a
características específicas.
E O Spark é uma ferramenta ideal para aplicações do tipo ETL, mas não é
adequado para operações analíticas em tempo real.
O Spark é um framework para aplicações de Big Data que possui alto desempenho. Por
isso, é a principal tecnologia atualmente para esse tipo de aplicação. Ele pode ser
utilizado para aplicações de Internet das Coisas (IoT), redes sociais, portais de notícias
e muitas outras situações similares. Mas sua configuração é um desafio! É necessário
um profundo conhecimento de sua plataforma e da aplicação para configurar os
parâmetros adequadamente.
Arquitetura do Spark
Modelo de abstrações
A arquitetura do Spark é baseada no modelo mestre-escravo com camadas e
componentes bem definidos e fracamente acoplados. Além disso, ela também possui
integração com várias bibliotecas. Essa arquitetura é baseada em duas abstrações.
Vamos entendê-las com mais detalhes a seguir.
Conjunto de dados distribuídos resilientes
Do inglês “Resilient Dataset Distribution (RDD)”. O conjunto de dados (datasets)
contempla os dados organizados em grupos. Esses dados são:
sync_alt
Distribuídos
São alocados a nós diferentes.
cached
Resilientes
São recuperados em caso de falha.
Em outras palavras, são grupos de itens de dados que podem ser armazenados na
memória dos nós trabalhadores.
Os RDDs suportam esses dois tipos de operações:
Transformações
Operações como mapa, filtro, junção e união, que são executadas em um RDD e geram um
novo RDD contendo o resultado.
Ações
Operações como redução, contagem e primeiro ou último, que retornam um valor após a
execução de um cálculo em um RDD.
Cluster Manager;
Executors;
Arquitetura do Spark.
Cluster Manager
É o gerenciador de cluster – um componente opcional que só será necessário se o
Spark for executado de forma distribuída. Ele é responsável por administrar as
máquinas que serão utilizadas como workers.
Os gerenciadores de cluster podem ser classificados em três tipos (APACHE SPARK,
2018):
Independente (standalone)
Gerenciador de cluster simples que facilita a configuração de um cluster.
Apache Mesos
Gerenciador geral de cluster que também pode executar Hadoop MapReduce.
Hadoop YARN
Gerenciador de recursos no Hadoop.
Além desses três tipos, há um suporte experimental para Kubernetes, que é uma
plataforma de código aberto para fornecer infraestrutura centrada em contêineres.
Worker Node
São os nós de trabalho, ou seja, as máquinas que, de fato, executarão as tarefas
enviadas pelo Driver Program. Se o Spark for executado no modo local, a máquina
desempenhará tanto o papel de Driver Program quanto de worker.
Os workers são nós escravos, e sua função é executar o código do aplicativo no cluster.
Além disso, eles são compostos por:
executor (executores) – processos de nós de trabalho encarregados de executar tarefas
individuais em determinado trabalho do Spark;
Atividade
Questão 1
2. O Driver Program solicita recursos para o gerenciador do cluster (cluster manager) para
iniciar os executores;
6. Se algum Worker Node falhar, suas tarefas serão enviadas a outros executores para serem
processadas novamente.
Linguagens de programação do Spark
De forma resumida, o Spark é uma ferramenta computacional voltada para aplicações
de Big Data, em que podemos fazer o agendamento, a distribuição e o monitoramento
de várias aplicações distribuídas.
O ecossistema do Spark é formado pelos recursos de linguagem de programação, os
quais permitem que os projetos possam ser programados em diferentes linguagens e
por distintos tipos de componentes totalmente integrados à plataforma.
As linguagens de programação que podemos utilizar para desenvolver projetos no
Spark são:
Scala
Python
Java
Componentes do Spark
Têm como objetivo facilitar o desenvolvimento de projetos com finalidades específicas,
como os de aprendizado de máquina, por exemplo.
Os principais componentes do ecossistema do Spark são (CHELLAPPAN; GANESAN,
2018):
Fornece suporte para dados estruturados e permite consultar os dados por meio
da linguagem SQL. Além disso, também oferece suporte para representação dos
dados a partir de datasets e dataframes.
MLlib expand_more
GraphX expand_more
É uma biblioteca usada para manipular e realizar cálculos paralelos aos grafos.
Com ela, podemos visualizar os dados em forma de grafo, além de fornecer
vários operadores para manipulação de grafos e combiná-los com RDDs. Essa
biblioteca é bastante útil para trabalharmos com bancos de dados orientados a
grafos.
Atividade
Questão 1
!wget -q https://downloads.apache.org/spark/spark-3.2.2/spark-3.2.2-
bin-hadoop3.2.tgz
Isso significa que você fez o download do arquivo a seguir, da versão 3.2.2 do Spark e 3.2
do Hadoop: spark-3.2.2-bin-hadoop3.2.tgz
3. Instale o pacote PySpark, que é uma interface do Python para o Apache Spark, essencial
para o desenvolvimento de nossas aplicações. Como ele não está no caminho do sistema
por padrão (sys.path), você precisa resolver isso adicionando o PySpark ao sys.path em
tempo de execução por meio do FindSpark, que torna o PySpark uma biblioteca regular.
3.2. Para instalar o PySpark, execute a linha de comando a seguir em uma célula do
Google Colab:
content_copy
1 import os
2 ·os.environ["JAVA_HOME"] = "/usr/lib/jvm/java-8-openjdk-amd64"
3 ·os.environ["SPARK_HOME"] = "/content/spark-3.2.2-bin-hadoop3.2"
4.2. Na primeira linha do código, observe que importamos o pacote os, que é uma
interface para o sistema operacional. No caso de nosso programa, associamos as
variáveis de ambiente aos caminhos em que o Java e o Spark estão instalados no
Google Colab.
4.3. Fique atento aos nomes dos arquivos. Eles precisam fazer referência às versões que
você baixou. Do contrário, a configuração estará errada.
Atividade
Questão 1
help(findspark)
import findspark
findspark.init()
2. Crie uma sessão no Spark, que permite trabalhar com RDD, Dataframe e Dataset. Para isso,
escreva o código a seguir em uma célula de código do Google Colab e, em seguida,
execute-o:
Observe que, na segunda linha, tivemos de usar o método getOrCreate para criar uma
sessão no Spark ou, simplesmente, obter uma sessão, caso já exista.
2.1. Ainda na sessão do Spark, analise o master. Existem dois casos possíveis:
3. Depois de criar a sessão do Spark, utilize-a para acessar dados. Considere os dados que já estão
disponíveis no Google Colab – no caso, um dataset sobre residências na Califórnia. Para ver
esses dados, acesse um símbolo de diretório no lado esquerdo do Google Colab.
dataset =
spark.read.csv('/content/sample_data/california_housing_test.csv',inferSchema=True,
header =True)
root
Com isso, você executou nosso exemplo completo do Spark no Google Colab.
Atividade
Questão 1
Você acabou de desenvolver uma aplicação prática com o Spark. Agora, refaça todos
os passos anteriores, com exceção do comando spark.stop(). Seu exercício é
apresentar o conteúdo básico do Dataset.
Abrir soluçãoexpand_more
Aqui, você precisa criar uma célula de código e executar o seguinte comando:
dataset.head()
O que é o PySpark?
É uma biblioteca Spark para executar programas Python usando recursos do Apache
Spark, ou seja, trata-se de uma API Python para Apache Spark. Como já vimos, o
Apache Spark é um framework aplicado para o processamento de dados distribuídos
de alto desempenho.
Vejamos as principais vantagens do PySpark:
Tem um mecanismo de processamento distribuído em memória de uso geral, que permite
processar dados com eficiência de maneira distribuída.
close_fullscreen
Conectar-se a um cluster Spark do
PySpark.
settings
Realizar operações com Spark
DataFrames.
Vamos entender melhor cada um deles.
Conectando-se a um cluster Spark do PySpark
O primeiro passo que precisamos fazer para utilizar o Spark é conectar-se a um cluster.
Para realizar a conexão, devemos criar uma instância da classe SparkContext. O
construtor dessa classe possui alguns argumentos que permitem especificar os
atributos do cluster ao qual estamos nos conectando.
looks_one
Importar a biblioteca PySpark.
looks_two
Instanciar um objeto SparkContext.
O código que faz exatamente essa sequência é este:
Python
content_copy
Para visualizarmos os dados de Dataset, executamos o código a seguir, que vai exibir o
cabeçalho das colunas e o conteúdo da primeira linha: dataset.head()
Esse código produz a saída dada por:
Python
content_copy
1 dataset.createOrReplaceTempView("tabela_temporaria")
2 print(spark.catalog.listTables())
3
Questão 1
Uma das vantagens de trabalhar com o Spark é que essa tecnologia oferece suporte
para diversas linguagens de programação. Uma dessas linguagens é o Python, que
pode ser acessado pela API PySpark. Essa API possui diversas características que
precisam ser bem compreendidas para desenvolver aplicações de qualidade do Python
no Spark. Nesse sentido, assinale a alternativa correta sobre as características do
PySpark:
bar_chart
Dados
table_rows
Linhas
table_chart
Colunas
Com o Pandas, também podemos fazer a limpeza de dados por meio da exclusão de
linhas, seja porque os dados não são relevantes, seja porque contêm valores errados,
como valores vazios ou nulos.
A seguir, vamos estudar como o Pandas se relaciona com as aplicações do PySpark. Em
especial, vamos usar o Pandas para trabalhar com SQL e DataFrame do Spark.
Convertendo Spark SQL para Pandas
Vamos voltar ao exemplo que já havíamos iniciado: a ideia é obter a localização de
residências com a maior quantidade de quartos. Portanto, o resultado da consulta deve
apresentar a latitude e a longitude do bloco residencial com a maior quantidade de
quartos.
A primeira parte de nossa solução vai ser dividida nos seguintes passos:
1. Implementar a consulta SQL na tabela chamada de tabela_temporaria, que já carregamos
no Spark para retornar a quantidade máxima de quartos;
A seguir, podemos ver o código de nossa solução, que reproduz exatamente os passos
que descrevemos.
Python
content_copy
Na última linha do código, tivemos de fazer algumas manipulações para acessar o valor
que queremos converter para inteiro. Isso foi necessário, pois o retorno é um
DataFrame. Depois de executar o programa, obtemos a seguinte saída:.
Python
content_copy
Observe que, na primeira linha da saída, aparecem os valores 0 e 30450.0, que são,
respectivamente, a localização do elemento e o valor dentro do DataFrame. Na
segunda linha, aparece o campo Name com o rótulo maximo_quartos, que foi o nome
associado ao retorno do SQL.
Agora, vamos continuar a solução, que consiste em obter a localização do bloco
residencial com a maior quantidade de quartos. Para isso, vamos realizar os seguintes
passos:
1. Implementar a consulta SQL para retornar a latitude e a longitude da residência com a
quantidade máxima de quartos que obtivemos na execução do programa anterior;
4. Exibir o resultado.
1 }longitude latitude
2 ·0 -117.2 33.58
No caso, havia apenas um bloco residencial com 30450 quartos. O zero (0) que
aparece na segunda linha da saída se refere ao número do registro. No Python, a
indexação de listas e vetores começa na posição zero.
Atividade
Questão 1
Processo de conversão
Agora, vamos estudar um exemplo que converte um DataFrame do Pandas para um
DataFrame no Spark. Nosso exemplo seguirá estes passos:
1. Gerar dados aleatórios que seguem a distribuição normal com média e desvio-padrão que
fornecemos – vamos usar a biblioteca Numpy para gerar os dados e a biblioteca Pandas
para organizá-los em um DataFrame;
1 import pandas as pd
2 import numpy as np
3 media = 0
4 desvio_padrao=0.1
5 pd_temporario = pd.DataFrame(np.random.normal(media,desvio_padrao,100)
6 spark_temporario = spark.createDataFrame(pd_temporario)
7 print(spark.catalog.listTables())
8 spark_temporario.createOrReplaceTempView("nova_tabela_temporaria")
9 print(spark.catalog.listTables())
10
Essa saída inclui informações sobre a última tabela que criamos. Para concluir,
precisamos fechar a sessão, executando o código: spark.stop().
Dicas e boas práticas
O fato de termos usado o Google Colab para desenvolver nosso projeto facilita
bastante o processo, pois é mais fácil realizarmos testes e ajustes sem a necessidade
de fazer muitas configurações.
Uma boa prática de programação nesse tipo de ambiente é usar uma célula de código
para executar as sequências que apresentamos, pois, se houver algum problema, será
mais fácil detectá-lo e corrigi-lo.
Atenção!
Uma fonte de erros comum é não observar a indentação, o que, para a maioria das
linguagens, não seria problema. Mas, no caso do Python, a indentação faz parte da
sintaxe para delimitação de blocos lógicos.
Outra questão importante: quando rodamos os exemplos, não podemos esquecer de
instalar os pacotes e as dependências, exatamente como foi apresentado.
Atividade
Questão 1
O DataFrame do PySpark está preparado para trabalhar com o RDD, que é um dos
componentes básicos da arquitetura do Spark. Portanto, ele utiliza melhor os recursos
computacionais do que o DataFrame tradicional do Python.
MapReduce
Esse cenário é uma descrição do paradigma MapReduce, que foi introduzido pela
empresa Google por volta de 2004 (HAMSTRA et al., 2015).
O MapReduce é uma estratégia de computação com capacidade para processar
grandes conjuntos de dados de forma distribuída em várias máquinas. Sua essência é
mapear um conjunto de dados de entrada em uma coleção de pares (chave-valor) e,
em seguida, reduzir todos os pares com a mesma chave.
Essa forma de fazer o processamento é muito eficiente para aplicações distribuídas,
pois quase todos os dados podem ser mapeados em pares (chave-valor). As chaves e
os valores podem ser de qualquer tipo: strings, inteiros, tipos abstratos e até os
próprios pares (chave-valor).
Exemplo
O exemplo clássico para utilização de MapReduce é o que trata da contagem das
frequências de palavras em um texto grande. Mas essa estratégia também pode ser
utilizada para fazer classificações e pesquisas distribuídas, em aprendizado de máquina
e em muitas outras situações práticas que apenas confirmam a importância dessa
técnica utilizada pelo Spark.
Paradigma MapReduce
Como vimos, o exemplo clássico de MapReduce é o de contar a quantidade de palavras
em um arquivo. A ideia é bem simples: a entrada de dados do sistema é um arquivo
texto que pode conter palavras repetidas. No final, o algoritmo produz uma lista com as
palavras e a quantidade de vezes que elas apareceram no arquivo.
Na imagem a seguir, podemos entender como o MapReduce trabalha no exemplo de
contagem de palavras:
Exemplo de MapReduce.
Separação expand_more
Mapeamento expand_more
Aplica uma função a cada elemento de uma lista e coleta o resultado. No caso
do exemplo de contagem de palavras, nosso objetivo é mapear cada palavra no
arquivo de entrada em um par chave-valor: a chave é a palavra, e o valor é o
número de ocorrências.
Embaralhamento expand_more
Redução expand_more
Conta o número de valores com a mesma chave. Essa etapa é muito eficiente
devido ao processamento das etapas anteriores, pois é um simples processo de
contagem.
Final expand_more
Atividade
Questão 1
A computação distribuída é naturalmente aplicada para Big Data. Isso ocorre devido às
características próprias dos projetos com grandes volumes de dados e todas as
complexidades envolvidas. Algumas dessas complexidades se referem à velocidade
com que os dados são gerados e processados. Nesse sentido, assinale a alternativa
correta a respeito da computação distribuída no contexto do Spark.
Transformações do Spark
São funções que recebem um RDD como entrada e produzem um ou mais RDDs como
saída. Elas não modificam o RDD de entrada, pois os RDDs são imutáveis. A ideia é
transformar um conjunto de dados de entrada no conjunto que queremos obter.
Por definição, as transformações do Spark são operações preguiçosas (lazy
evaluations). Isso significa que os novos RDDs são criados apenas depois da execução
de uma operação classificada como ação. Portanto, a transformação cria um conjunto
de dados a partir de um existente.
Ainda sobre o processo preguiçoso das transformações, quando aplicamos uma
transformação em qualquer RDD, ela não será executada de imediato. O Spark cria um
grafo acíclico dirigido (DAG) com as seguintes informações:
Operação aplicada;
RDD origem;
Apenas quando aplicarmos uma ação, serão realizados os cálculos sobre o RDD.
Existem dois tipos de transformações. Vamos conhecer cada uma delas.
Transformações estreitas
São aquelas resultantes da aplicação de funções de mapeamento e de filtragem. Os
dados se originam de uma única partição. Essa característica é chamada de
autossuficiência.
Portanto, as partições de um RDD de saída possuem registros que se originam de uma
única partição no RDD pai. Além disso, o Spark utiliza apenas um subconjunto de
partições para obter o resultado.
O Spark agrupa as transformações estreitas como um estágio conhecido como
pipelining. A ideia é fazer um processamento com a maior quantidade de operações
em uma única partição de dados.
Exemplo
map() – aplica a transformação em cada elemento de uma fonte de dados e retorna um
novo conjunto de dados, que podem ser RDD, DataFrame ou Dataset.
flatMap() – faz o nivelamento das colunas do conjunto de dados resultante depois de
aplicar a função em cada elemento e retorna um novo conjunto de dados.
filter – faz uma filtragem dos registros de uma fonte de dados.
mapPartitions() – é parecida com a função map(), pois executa a função de
transformação em cada partição de dados.
sample() – retorna um subconjunto aleatório dos dados de entrada.
union() – retorna a união de dois conjuntos de dados de entrada.
Transformações amplas
Em alguns casos, os dados necessários para realizar os cálculos com os registros em
uma única partição podem estar em muitas partições. Portanto, é necessário realizar
movimentos de dados entre as partições para executar as transformações, que são
chamadas de amplas. Elas também são conhecidas como transformações aleatórias,
porque podem depender de uma mistura aleatória.
Exemplo
Intersection() – retorna a interseção de dois RDDs.
distinct() – retorna um novo RDD com os elementos distintos de um RDD de origem.
groupByKey() – é aplicada sobre um conjunto de dados de pares (K, V) – K representa a
chave (Key), e V representa o valor (Value) – e retorna um conjunto de dados de pares
agrupados pelas chaves.
reduceByKey() – opera também sobre um conjunto de dados de pares (K, V) e retorna
um conjunto de dados de pares (K, V), no qual os valores para cada chave são
agregados, usando a função redução, que deve ser do tipo (V, V) = > V.
sortByKey() – opera sobre um conjunto de dados de pares (K, V) e retorna um conjunto
de dados de pares (K, V) ordenados por K.
join() – combina os campos de duas fontes de dados, usando valores comuns.
coalesce() – utiliza uma partição existente para que menos dados sejam misturados e,
assim, seja possível diminuir o número de partições.
Ações do Spark
Uma ação no Spark retorna o resultado dos cálculos no RDD. Para realizar o
processamento, uma ação utiliza o DAG para carregar os dados no RDD original, realizar
todas as transformações intermediárias e retornar os resultados para o Driver Program
ou gravá-los no sistema de arquivos.
Ou seja, as ações são operações sobre os RDDs que produzem valores, e não RDD.
Exemplo
first() – retorna o primeiro elemento no RDD.
take() – retorna um vetor com os primeiros n elementos do conjunto de dados, onde n é
um parâmetro da função.
reduce() – agrega elementos de um conjunto de dados por meio de funções.
collect() – retorna os elementos do conjunto de dados como um vetor.
count() – retorna a quantidade de elementos no RDD.
Atividade
Questão 1
2. Acompanhe o exemplo 1 – Vetores, que tem como objetivo receber um vetor numérico e,
para cada elemento do vetor, aplicar a seguinte função matemática: \(f(x)=x^2+x\).
2.1. Para criar o vetor, utilize o pacote Numpy e importe esse pacote, usando o seguinte
código:
import numpy as np
paralelo = spark_contexto.parallelize(vetor)
2.4. Faça uma rápida verificação do conteúdo da variável paralelo, usando o código:
print(paralelo)
Esse código produz a seguinte saída, a qual indica que você criou o RDD com
sucesso:
ParallelCollectionRDD[3] at readRDDFromFile at
PythonRDD.scala:274
2.5. Como o vetor já está no Spark, você pode aplicar o mapeamento. Para isso, use o
seguinte código:
mapa.collect()
3. Acompanhe o exemplo 2 – Listas, que tem como objetivo contar a frequência das palavras
de uma lista.
paralelo = spark_contexto.parallelize(["distribuida",
"distribuida", "spark", "rdd", "spark", "spark"])
3.2. Implemente uma função lambda que simplesmente associa o número 1 a uma
palavra. O código fica exatamente assim:>
Ou seja, a função recebe uma variável x e vai produzir o par (x, 1).
• A coleta dos dados na etapa final, dada pela função collect, em uma lista que
chamamos de mapa.
Esse código percorre a lista mapa e imprime cada par formado pela
palavra e sua respectiva ocorrência. A saída é a seguinte:
distribuida: 2
spark: 3
rdd: 1
spark_contexto.stop()
Atividade
Questão 1
9735015
Pronto! Você já desenvolveu mais um exemplo com PySpark. Continue seus estudos
para aprofundar seus conhecimentos.
spark_contexto = SparkContext()
lista = [1, 2, 3, 4, 5, 3]
lista_rdd = spark_contexto.parallelize(lista)
2. Execute a ação de contar os elementos do RDD. Para isso, implemente o código a seguir,
que vai produzir na saída o valor 6:
lista_rdd.count()
3. Crie uma função lambda que recebe um número como parâmetro e retorna um par
formado pelo número do parâmetro e pelo mesmo número multiplicado por 10. Para isso,
use o código:
4. Aplique a transformação flatMap com a ação collect da função lambda para a lista_rdd.
Para isso, use o código a seguir, que vai produzir a saída [1, 10, 2, 20, 3, 30, 4, 40, 5, 50, 3,
30]:
lista_rdd.flatMap(par_ordenado).collect()
5. Aplique a transformação map com a ação collect da função lambda para a lista_rdd. Para
isso, use o código a seguir, que vai produzir a saída [(1, 10), (2, 20), (3, 30), (4, 40), (5, 50),
(3, 30)]:
lista_rdd.map(par_ordenado).collect()
spark_contexto.stop()
Atividade
Questão 1
Abrir soluçãoexpand_more
[(1, 1), (2, 4), (3, 9), (4, 16), (5, 25), (3, 9)]
Parabéns por ter realizado esses exercícios práticos! Agora, você já sabe como
utilizar o Spark com PySpark. Para consolidar seus conhecimentos, reveja os
conceitos e exemplos e faça muitos testes. Bons estudos!.
Conclusão
Explore +
Acesse o site oficial do Apache Spark e aprofunde seus conceitos sobre sua arquitetura e
os componentes de seu ecossistema.
Acesse o site oficial do Pandas com PySpark e explore diversos exemplos práticos que
ajudarão você a aprimorar seus conhecimentos.
Referências bibliográficas
APACHE SPARK.. Cluster mode overview. Maryland: The Apache Software Foundation, 2018.
CHELLAPPAN, S.; GANESAN, D.. Practical Apache Spark: using the Scala API. Berkeley:
Apress, 2018.