Domine PySpark: 25 Perguntas Essenciais que Você Precisa Saber Responder (2024)

Carlos Zansavio
7 min readNov 20, 2023

1. O que é o PySpark?

PySpark é uma interface para o Apache Spark, um motor de análise e processamento de dados em larga escala. PySpark fornece uma interface de programação de alto nível para trabalhar com Apache Spark, tornando a vida do desenvolvedor mais fácil.

2. Quais benefícios de usar o PySpark?

Alguns benefícios do PySpark:

  • Facilidade de uso: PySpark fornece uma API alto nível em Python, o que torna fácil o desenvolvimento e deploy de novas aplicações em Spark.
  • Perfomance: Aplicações PySpark podem ter performance muito boas em conjunto de dados gigantes (BigData)
  • Escabilidade: Aplicações PySpark podem ser escaláveis facilmente.
  • Flexibilidade: PySpark pode ser usado para resolver vários problemas no ramo de BigData, incluindo processamento de dados, aprendizado de máquina (machine learning) e análise de dados.

3. Qual é a diferença entre Spark e PySpark?

Apache Spark é um motor de análise de dados em larga escala open-source. Ele nos fornece uma interface para trabalhar com dados distribuídos em vários servidores, apresentando também tolerância a falha.

PySpark é uma interface para o Apache Spark utilizando a linguagem Python. Apache Spark tem outras interfaces como SQL, Scala, Java e R. Todas essas interfaces no fundo utilizam o mesmo motor do Apache Spark.

4. Quais são as ações mais comuns no Apache Spark?

  • Reduce(function): Esse ação agrega os elementos de um conjunto de dados utilizando a função passada como argumento.
  • Count(): Retorna o número total de elementos de um Dataset
  • Collect(): Esse método retorna todos os elementos de um Dataset como um Array.
  • First(): Retorna o primeiro elemento de uma coleção.
  • Take(n): Retorna os primeiros n elementos de uma coleção.
  • Foreach(func): Itera sobre os elementos de um Dataset executando a função passada como argumento.

5. O que é um SparkContext?

Um SparkContext é o ponto inicial de qualquer aplicação Spark. É responsável pela criação e gerenciamento dos clusters. Ele é usado para conectar às diversas máquinas e também para alocar recursos.

A seguir está um exemplo de criação de um contexto Spark em Python:

from pyspark import SparkContext
sc = SparkContext("local", "Olá Mundo App")

6. O que é um RDD?

Resilient Distribution Dataset (RDD) ou, em tradução livre, Conjunto de Dados Distribuído e Resiliente é uma abstração de dados no Apache Spark. Basicamente é um conjunto de dados particionados e distribuídos em um cluster. RDD esconde e abstrai todo esse processo para o engenheiro. As principais features de um RDD são:

  • Distribuídos: Dados são distribuídos através de vários nós dentro do cluster.
  • Resilientes: RDD é tolerante a falhas; o que quer dizer que se algum nó cair, os dados não serão perdidos graças ao Spark.
  • Dataset: É uma coleção de dados similar as Collections em Scala.
  • Imutáveis: Dados em RDD não podem ser modificados após a criação.

Exemplo de um RDD:

from pyspark import SparkContext

sc = SparkContext("local", "Exemplo App")

words = sc.parallelize (
[
"Python",
"Java",
"JavaScript",
"C++",
"Ruby",
"Swift",
"Go",
"PHP"
]
)

7. Qual são as principais operações que podem ser feitas em um RDD?

As principais operações em um RDD são:

  • Transformação: Esse função é utilizada para criar um novo RDD a partir de outro RDD.
  • Ação: Essa função retorna o valor depois de rodar um processamento em um RDD.

Exemplo:

from pyspark import SparkContext

sc = SparkContext("local", "Exemplo App")

words = sc.parallelize (
[
"Python",
"Java",
"JavaScript",
"C++",
"Ruby",
"Swift",
"Go",
"PHP"
]
)

counts = words.count()
print("Count is : {}".format(counts))

Saída:

Count is : 8

8. O que é um DataFrame?

Um Dataframe é uma coleção de dados organizados em colunas. Ele é conceitualmente parecido com o Dataframe do Pandas, porém com algumas otimizações por de baixo dos panos.

DataFrames podem ser instanciados de diversas maneiras: arquivos estruturados, tabelas no Hive, banco de dados externos ou RDDs já existentes.

Exemplo a partir de um RDD:

from pyspark.sql import SparkSession
from pyspark.sql import Row

spark = SparkSession.builder.appName("example").getOrCreate()

data = [("John", 25), ("Alice", 30), ("Bob", 28)]

rdd = spark.sparkContext.parallelize(data)

schema = ["name", "age"]
df = rdd.map(lambda x: Row(name=x[0], age=int(x[1]))).toDF(schema)

df.show()

Saída:

+-----+---+
| name|age|
+-----+---+
| John| 25|
|Alice| 30|
| Bob| 28|
+-----+---+

9. O que é um Dataset?

Dataset é uma coleção distribuída de dados, introduzida na versão 1.6 do Spark. Ele combina benefícios dos RDDs com a otimização proporcionadas pelo Spark SQL.

10. Quais são as transformações mais comuns no Spark?

As transformações mais comuns no Spark são:

  • map(): Aplica uma função argumento para cada elemento no RDD e retorna um novo RDD.
  • filter(): Retorna um novo RDD contendo apenas os elementos que satisfazem a condição imposta.
  • reduce(): Reduz o RDD a apenas um valor dado a função argumento e retorna apenas o resultado acumulado.
  • join(): Junta dois RDDs com base em uma chave comum, retorna um novo RDD.

11. Quais são as acões mais comuns no Spark?

As ações mais comuns no Spark são:

  • collect(): Retorna todos os elementos de um RDD como uma lista.
  • count(): Retorna o número de entidades em um RDD.
  • first(): Retorna o primeiro elemento de um RDD.
  • take(): Retorna os primeiros n elementos de um RDD.

12. Como funciona o cache no PySpark?

Cache no PySpark possibilita armazenar RDDs na memória RAM, impulsionando significativamente o desempenho das aplicações Spark.

O armazenamento padrão de uma aplicação Spark é MEMORY_AND_DISK . Exemplo de um cacheamento:

from pyspark.sql import SparkSession
spark = SparkSession.builder.getOrCreate()

df = spark.range(1)

# Cache em memória
df.cache()

13. O que é particionamento no PySpark?

O particionamento no PySpark divide um RDD em vários conjuntos de dados menores, permitindo o processamento independente de cada parte. Isso melhora significativamente o desempenho, possibilitando o processamento distribuído dos dados em cada nó.

14. O que são variáveis brodcast no PySpark?

Variáveis brodcast são váriaveis que podem ser transmitidas para todos os nós de um cluster. Isso pode ser útil em datasets muito grandes onde apenas um nó não consegue guardar toda a base de dados.

Exemplo:

>> from pyspark.context import SparkContext
>> sc = SparkContext('local', 'test')
>> b = sc.broadcast([1, 2, 3, 4, 5])
>> b.value

Saída: [1, 2, 3, 4, 5]

15. O que são acumuladores no PySpark?

Acumuladores no PySpark são variáveis que podem ser atualizadas por vários nós dentro de um cluster. Eles podem ser úteis para agregar dados de vários nós em um único valor.

16. Como você lida com assimetria dos dados no PySpark?

Assimetria dos dados pode ocorrer quando um RDD não está bem distribuído dentro de um cluster. Isso pode levar a problemas de perfomance, já que alguns nós podem ficar sobrecarregados enquanto outros não.

Uma maneira de tratar essa assimetria é usar o método repartition() que redistribui os dados dentre os nós. Outra maneira de tratar esse problema é usando mapPartitions(), no qual conseguimos aplicar uma função para cada nó independentemente.

17. Como você melhora o uso de memória no Spark?

Podemos utilizar as seguintes técnicas:

  • Usar estruturas de dados como Arrays ou objetos primitivos em vez de Linked Lists (Lista encadeadas) ou HashMaps (Dicionários).
  • Reduzir o uso de estruturas de dados encadeadas/aninhadas.
  • Usar IDs númericos em vez de Strings.

18. O que é uma operação Shuffle (embaralhamento) no Spark?

Shuffle é uma operação no Spark usada para redistribuir dados em um cluster. É uma operação custosa e complexa.

19. Quais operações podem causar embalharamento dos dados (shuffle) no Spark?

As operações mais comuns que podem causar embaralhamento de dados são:

  • Repartition
  • Coalesce
  • GroupByKey
  • ReduceByKey
  • Cogroup
  • Join

20. O que é lazy evaluation no Apache Spark?

O Apache Spark adota lazy evaluation para aprimorar certas operações. As transformações não são imediatamente aplicadas aos RDDs, mas sim adiadas até o momento preciso em que necessitam ser executadas. Assim, o Spark consegue otimizar o processamento, permitindo uma melhor gestão e eficiência das operações.

21. Qual é a diferença entre os métodos cache() e persist() no Apache Spark?

Ambos métodos são utilizados para persistir os dados de um RDD em memória. A principal diferença entre cache() e persist() está na capacidade do persist() de permitir a especificação do local onde os dados serão salvos, ao passo que o cache() utilizará sempre o método padrão, que é MEMORY_ONLY.

22. Como você remove dados da cache no Apache Spark?

Apache Spark automaticamente remove objetos não utilizados da cache pelo Garbage Collector. Para isso, ele utiliza o algoritmo de Least Recently Used (LRU) onde ele remove o elementos menos utilizados primeiro.

Em caso em que você quer forçar essa desalocação de memória, pode-se utilizar o método RDD.unpersist() .

23. Como Apache Spark suporta Aprendizado de Máquinas (Machine Learning)?

Spark suporta algoritmos de aprendizado de máquina atráves de sua biblioteca chamada MLlib. Essa biblioteca é conhecida por sua escalabilidade e abrange uma ampla variedade de algoritmos para diversas tarefas de processamento de Big Data.

24. Como minimizar a transfêrencia de dados no Apache Spark?

Operações que causam Shuffle (embaralhamento) levam a grandes transferências de dados dentro do cluster. É possível minimizar essa movimentação de dados utilizando as seguintes técnicas:

  • spark.shuffle.compress : Essa configuração pode ser utilizada para comprimir os dados.
  • ByKey : Minizar o uso de operações ByKey pode minizar a transfêrencia de dados já que essas operações causam muito embaralhemento (shuffle) nos dados.

25. Quais níveis de persistência de dados no Apache Spark?

Temos os seguintes níveis de persistências:

  • MEMORY_ONLY: RDDs são guardados como objetos desserializados na JVM. Se o RDD não couber na memória, eles serão recomputados quando for necessário.
  • MEMORY_ONLY_SER: RDDs são guardados como objetos na JVM. São mais eficientes do que o primeiro nível já que são guardados como objetos serializados.
  • MEMORY_AND_DISK: RDDs são guardados como objetos desserializados na JVM. Se o RDD não couber na memória, eles serão guardados em disco.
  • MEMORY_AND_DISK_SE: RDDs são guardados como objetos serializados na JVM. Se o RDD não couber na memória, eles serão guardados em disco.
  • DISK_ONLY: RDD são guardados apenas em disco.

Refêrencias

--

--