Introdução ao PySpark no Google Colab

Bem-vindo a nossa jornada no mundo do PySpark! O PySpark é a API Python para o Apache Spark, o framework de código aberto projetado para processamento de dados distribuídos.

🕒 Tempo estimado de leitura: 8 minutos

Neste texto, percorreremos a arquitetura central de um cluster Spark, nos aprofundaremos na anatomia de um aplicativo Spark e exploraremos as poderosas APIs estruturadas do Spark usando DataFrames.

Para facilitar o aprendizado, configuraremos o ambiente Spark no Google Colab, proporcionando uma plataforma prática e eficiente para realizar nossos experimentos e análises. Vamos juntos descobrir como o PySpark pode transformar a forma como lidamos com grandes volumes de dados.

Todos os exemplos também são explicados aqui👨‍🔬, um notebook correspondente do Google Colab para tornar seu aprendizado ainda mais interativo.

Compreendendo o Spark: Terminologia e conceitos básicos

Normalmente, quando você pensa em um carro 🚗 , imagina um único veículo parado na sua garagem ou estacionado no escritório. Este carro 🚗 é perfeitamente adequado para tarefas diárias ou deslocamento para o trabalho. No entanto, existem algumas tarefas que seu carro simplesmente não consegue lidar devido à sua potência e capacidade limitadas. Por exemplo, se você quiser transportar o equipamento de uma banda de rock inteira 🎸 pelo país, um único carro não será suficiente - ele não tem espaço suficiente e a viagem seria muito trabalhosa.

Em cenários como esses, uma frota de caminhões 🚛🚛🚛 é útil. Uma frota reúne as capacidades de armazenamento de muitos veículos, permitindo-nos transportar todos os itens como se estivessem em um caminhão gigante. Mas, apenas ter uma frota não resolve o problema; você precisa de um sistema bem coordenado para gerenciar a logística. Pense no Spark como aquela ferramenta de logística sofisticada, gerenciando e orquestrando as tarefas de transporte de equipamentos por toda a frota.

O Apache Spark é um poderoso sistema de computação distribuída projetado para velocidade e facilidade de uso. Ao contrário dos sistemas tradicionais de processamento em lote, o Spark oferece recursos de processamento na memória, tornando-o significativamente mais rápido para tarefas de análise de dados e aprendizado de máquina.

Principais componentes do Spark

Pense nos aplicativos Spark como uma cozinha movimentada em um restaurante 🍽️, onde o chefe 👨‍🍳 de cozinha supervisiona todo o processo de cozimento enquanto vários subchefes 👨🏼‍🍳 executam tarefas específicas. Nessa analogia, o chefe de cozinha 👨‍🍳 é o processo condutor (driver), e os subchefes 👨🏼‍🍳 são os processos executores (executors).

O chefe 👨‍🍳 de cozinha (processo condutor) fica na cozinha e tem três responsabilidades principais:

  1. manter o controle sobre as operações gerais da cozinha,

  2. responder aos pedidos dos clientes e

  3. planejar, distribuir e agendar tarefas para os subchefes 👨🏼‍🍳.

Sem o chefe 👨‍🍳 de cozinha, a cozinha entraria em caos — assim como o processo condutor é o cérebro e o comando central de um aplicativo Spark, crucial para manter a ordem e atribuir tarefas durante o ciclo de vida de uma aplicação Spark.

Nessa cozinha bem organizada, os subchefes 👨🏼‍🍳 (executores) têm duas funções principais:

  1. eles executam cuidadosamente as receitas passadas pelo chefe de cozinha e

  2. mantêm o chefe 👨‍🍳 de cozinha informado sobre o status de suas tarefas de cozimento.

O último componente vital dessa operação culinária é o gerente do restaurante 🧑🏻‍💼 (gerente de cluster). O gerente do restaurante supervisiona todo o restaurante (máquinas físicas) e aloca espaço e recursos da cozinha para diferentes chefs (aplicativos Spark).

Como uma breve revisão, os pontos-chave a serem lembrados são:

  1. O Spark tem um gerenciador de cluster (o gerente do restaurante 🧑🏻‍💼) que mantém o controle dos recursos disponíveis.

  2. O processo do driver (chefe 👨‍🍳 de cozinha) executa as instruções do nosso programa principal nos executores (subchefes 👨🏼‍🍳) para concluir as tarefas.

Enquanto os executores executam predominantemente o código Spark, o driver pode operar em várias linguagens por meio das APIs de linguagem do Spark, assim como um chefe 👨‍🍳 de cozinha pode comunicar receitas em diferentes estilos culinários.

🛠️ Setup do ambiente

Aqui, conduziremos o processo de download necessário para a instalação e configuração adequadas do Apache Spark no Google Colab. Esta etapa é fundamental para garantir que todas as dependências sejam adquiridas corretamente, proporcionando um ambiente funcional e otimizado para a execução de tarefas e análises utilizando o Apache Spark.

Certifique-se de seguir cada etapa cuidadosamente, garantindo uma configuração suave e eficiente do Spark no ambiente Colab.

# A variável spark_version contém o valor da versão do Spark a ser utilizado.
# Para saber versões disponíveis acesse https://dlcdn.apache.org/spark
spark_version = "3.5.2"

# Instalação do Open JDK
# O Apache Spark é escrito em Scala, que é executado na Máquina Virtual Java (JVM).
# O OpenJDK fornece uma implementação de código aberto da JVM, garantindo compatibilidade e suporte para a execução do Spark.
!apt-get install openjdk-8-jdk-headless -qq > /dev/null

# Download do spark-{spark_version}-bin-hadoop3, uma distribuição específica do Apache Spark
!wget -q https://dlcdn.apache.org/spark/spark-{spark_version}/spark-{spark_version}-bin-hadoop3.tgz

# Descompactação do conteúdo do arquivo spark-VERSION-bin-hadoop3.tgz no sistema de arquivos
!tar xf spark-{spark_version}-bin-hadoop3.tgz

# Configuração das variáveis de ambiente
# A variável de ambiente JAVA_HOME aponta para o diretório de instalação do Java na máquina e é essencial para o Spark
# A variável de ambiente SPARK_HOME aponta para o diretório de instalação do Apache Spark. Ela é usada pelo Spark para localizar os seus próprios componentes e bibliotecas.
import os
os.environ["JAVA_HOME"] = "/usr/lib/jvm/java-8-openjdk-amd64"
os.environ["SPARK_HOME"] = f"/content/spark-{spark_version}-bin-hadoop3"

# A biblioteca findspark é usada para facilitar a configuração e inicialização do Apache Spark em ambientes locais, como em máquinas de desenvolvimento.
!pip install -q findspark

# findspark.init() facilita a configuração e inicialização do Apache Spark em ambientes locais de desenvolvimento
import findspark
findspark.init()

🛤️ Descrição passo a passo da instalação e configuração


Inicialmente definimos por meio da variável spark_version a versão do Spark a ser instalada no ambiente.

spark_version = "3.5.2"

O Spark foi desenvolvido em Scala e requer a Java Virtual Machine (JVM) para execução. Inicialmente, baixamos o Java com o comando:

!apt-get install openjdk-8-jdk-headless -qq > /dev/null

Em seguida, realizamos o download de um arquivo comprimido que contém uma distribuição pré-compilada do Apache Spark, usando:

!wget -q https://dlcdn.apache.org/spark/spark-{spark_version}/spark-{spark_version}-bin-hadoop3.tgz

Para instalar e começar a usar esta versão do Spark, precisamos descompactar o arquivo usando o comando abaixo. Ele irá extrair os arquivos necessários para um diretório, a partir do qual poderemos então iniciar a configuração e execução do Spark.

!tar xf spark-{spark_version}-bin-hadoop3.tgz

A configuração das variáveis de ambiente JAVA_HOME e SPARK_HOME é realizada com o código:

import os
os.environ["JAVA_HOME"] = "/usr/lib/jvm/java-8-openjdk-amd64"
os.environ["SPARK_HOME"] = f"/content/spark-{spark_version}-bin-hadoop3"

A variável de ambiente JAVA_HOME aponta para o diretório de instalação do Java na máquina. É essencial para o Spark saber onde o Java está instalado para que possa usar a JVM para execução. Sem essa configuração, o Spark pode não ser capaz de encontrar o Java corretamente.

SPARK_HOME aponta para o diretório de instalação do Apache Spark. Ela é usada pelo Spark para localizar os seus próprios componentes e bibliotecas.

Agora, com todas as dependências instaladas no Colab, definimos o caminho do ambiente para permitir a execução do PySpark. Utilizamos a biblioteca findspark para simplificar a configuração do Apache Spark em ambientes locais, instalando-a com

!pip install -q findspark

e iniciando com:

import findspark
findspark.init()

Este último comando adiciona o diretório Spark ao sys.path do Python, permitindo a importação e uso do Spark como uma biblioteca Python em ambientes de desenvolvimento local sem a necessidade de configurar variáveis de ambiente separadamente.

👨‍🔬 Testando a instalação

Agora, podemos testar a nossa instalação por meio de um exemplo simples de manipulação de um DataFrame com PySpark. Estamos considerando que você já fez a instalação do PySpark conforme apresentado anteriormente.

from pyspark.sql import SparkSession

# Inicializando uma sessão do Spark
# SparkSession é a entrada principal para a funcionalidade do Spark SQL. 
# Configuramos o nome do aplicativo Spark e criamos ou obtemos uma sessão existente.
spark = SparkSession.builder \
    .appName("Exemplo PySpark DataFrame") \
    .getOrCreate()

# Dados de exemplo
# Aqui criamos uma lista de tuplas com os dados de exemplo.
dados = [
    ("João", 28, "São Paulo"),
    ("Maria", 22, "Rio de Janeiro"),
    ("Pedro", 35, "Belo Horizonte"),
    ("Ana", 23, "Curitiba")
]

# Definindo o esquema (nomes das colunas)
# Definimos uma lista com os nomes das colunas para o DataFrame.
colunas = ["Nome", "Idade", "Cidade"]

# Criando o DataFrame
# Utilizamos a função createDataFrame do SparkSession para transformar os dados e as colunas em um DataFrame.
df = spark.createDataFrame(dados, colunas)

# Exibindo o DataFrame
# Usamos o método show() para mostrar as primeiras linhas do DataFrame.
print("DataFrame inicial")
df.show()

# Filtrando Dados
# Exibimos registros onde a idade é igual ou superior a 25.
# O método filter() é utilizado com uma expressão booleana para filtrar os dados.
print("Registros com Idade igual ou superior a 25")
df_filtrado = df.filter(df["Idade"] >= 25)
df_filtrado.show()

# Selecionando Colunas
# Selecionamos apenas as colunas "Nome" e "Cidade" do DataFrame.
# O método select() é usado para essa operação.
print("Seleção apenas das colunas Nome e Cidade")
df_selecionado = df.select("Nome", "Cidade")
df_selecionado.show()

# Agrupando Dados
# Agrupamos os dados pela coluna "Cidade" e contamos o número de registros em cada grupo.
# O método groupBy() é utilizado para agrupar, seguido do método count() para contar os registros em cada grupo.
print("Contando o total de registros por cidade")
df_agrupado = df.groupBy("Cidade").count()
df_agrupado.show()

# Salvando o DataFrame
# Salvamos o DataFrame em um arquivo CSV na localização especificada.
# O método write.csv() é utilizado para essa operação, com a opção header=True para incluir o cabeçalho.
df.write.csv("/content/output.csv", header=True)

Executar o código acima produzirá a seguinte saída.

DataFrame inicial
+-----+-----+--------------+
| Nome|Idade|        Cidade|
+-----+-----+--------------+
| João|   28|     São Paulo|
|Maria|   22|Rio de Janeiro|
|Pedro|   35|Belo Horizonte|
|  Ana|   23|      Curitiba|
+-----+-----+--------------+

Registros com Idade igual ou superior a 25
+-----+-----+--------------+
| Nome|Idade|        Cidade|
+-----+-----+--------------+
| João|   28|     São Paulo|
|Pedro|   35|Belo Horizonte|
+-----+-----+--------------+

Seleção apenas das colunas Nome e Cidade
+-----+--------------+
| Nome|        Cidade|
+-----+--------------+
| João|     São Paulo|
|Maria|Rio de Janeiro|
|Pedro|Belo Horizonte|
|  Ana|      Curitiba|
+-----+--------------+

Contando o total de registros por cidade
+--------------+-----+
|        Cidade|count|
+--------------+-----+
|     São Paulo|    1|
|Rio de Janeiro|    1|
|      Curitiba|    1|
|Belo Horizonte|    1|
+--------------+-----+

Conclusão

Parabéns! Você deu seus primeiros passos no mundo do PySpark. Ao longo deste texto, exploramos a arquitetura do Apache Spark, configuramos o ambiente de desenvolvimento no Colab e executamos operações essenciais com DataFrames utilizando PySpark.

Esperamos que você tenha adquirido uma compreensão sólida de como o Spark funciona e como utilizar o PySpark para manipulação e análise de dados.

Este conhecimento é apenas o começo. Nos próximos artigos vamos explorar como o PySpark oferece uma ampla gama de funcionalidades para processar grandes conjuntos de dados de maneira rápida e eficiente.