Vitor F. Lins

Veja como preparei o meu ambiente de estudos de Big Data com PySpark e uma Data Warehouse na nuvem

2024-03-21 | Artigo Tutorial

O cientista de dados é um profissional multidisciplinar, eu já estive estudando e praticando diversos temas da área, mas ainda não me aprofundei bem em ferramentas e técnicas relacionadas à Big Data. Neste tutorial, eu vou mostrar o que eu fiz para preparar o meu próprio “laboratório de Big Data”.

O resultado deste passo-a-passo vai ser uma máquina Linux que executa PySpark localmente, e tem acesso à até dois bancos de dados gratuitos da Oracle na nuvem, que podem armazenar até 20GB de dados cada (gratuitamente). Se você gostou da proposta, vamos ao tutorial!

⚠️ Disclaimer: Os exemplos de código apresentados aqui foram testados nestas condições:
  • Uma conta free tier já cadastrada na Oracle Cloud Infrastructure e um banco de dados provisionado
  • Um sistema Debian 12 como subsistema de Windows (WSL 2)
  • PySpark 3.5.1
  • Java 17
  • Python 3.9

1 Java

Vamos usar uma conexão JDBC (Java Database Connection), o backend do PySpark vai usar o Java instalado no sistema operacional para se comunicar com o banco de dados. Vamos começar garantindo que o Java está instalado.

1.1 Encontrar as versões disponíveis

apt search openjdk

1.2 Instalar a versão mais recente disponível

A consulta anterior pode mostrar outro número de versão, use-o no lugar do 17 abaixo.

sudo apt install openjdk-17-jdk

Alternativamente, é possível simplesmente instalar a versão recomendada pelo sistema, com:

sudo apt install default-jdk -y
# verificar a versão instalada
java --version

Note que esta versão provavelmente não é a mais recente.

1.3 Drivers JDBC da oracle

Baixar arquivo .jar. Cada tecnologia de banco de dados vai usar um driver diferente, para este exemplo vamos usar os drivers referentes ao banco de dados da Oracle.

sudo apt install wget
# Driver JDBC
wget https://download.oracle.com/otn-pub/otn_software/jdbc/233/ojdbc11.jar
# Universal Connection Pool (UCP)
wget https://download.oracle.com/otn-pub/otn_software/jdbc/233/ucp11.jar

2 Autenticação mTLS

2.1 Baixar carteira de autenticação.

A carteira vai ser um arquivo .zip que pode ser baixado pelo painel de gerenciamento de conexões da sua base de dados. Usando WSL 2, podemos usar qualquer navegador disponível no repositório apt.

Um sistema (Windows) com menos de 8gb de memória pode ter dificuldade para navegar, já que o subsistema Linux (Debian, neste caso) vai geralmente usar 50% da memória total do sistema. Também é recomendado um monitor com resolução de pelo menos 1920x1080. Se estiver seguindo este tutorial de um sistema Linux nativo (sem WSL), as restrições de memória e resolução de tela são mais leves.

sudo apt install chromium -y
chromium

[Imagem será adicionada posteriormente]

Primeiro acessamos a seção “Database Connection”

[Imagem será adicionada posteriormente]

Depois baixamos a carteira

2.2 Obter drivers adicionais

Estes são necessários para lidar com autenticação através de variáveis locais: oraclekpi.jar, osdt_cert.jar, osdt_core.jar.

É recomendável pegar todos os arquivos com o mesmo número de versão para evitar problemas de compatibilidade, aqui usaremos a versão 21.9.0.0.

Encontre a versão mais recente de cada um, obtenha o link, e faça o download. Exemplo com wget:

# oraclepki.jar
wget https://repo1.maven.org/maven2/com/oracle/database/security/oraclepki/21.9.0.0/oraclepki-21.9.0.0.jar
# osdt_cert.jar
wget https://repo1.maven.org/maven2/com/oracle/database/security/osdt_cert/21.9.0.0/osdt_cert-21.9.0.0.jar
# osdt_core.jar
wget https://repo1.maven.org/maven2/com/oracle/database/security/osdt_core/21.9.0.0/osdt_core-21.9.0.0.jar

3 PySpark, concedendo acesso aos .jar

A maneira mais simples é incluir os arquivos .jar baixados na biblioteca local do PySpark, se estiver usando um ambiente virtual (venv), esta biblioteca pode ser encontrada desta maneira:

# Cria uma ambiente virtual, vamos usar uma pasta “env”:
python -m venv env

#Ativa o ambiente virtual
source env/bin/activate

# Instala o PySpark
pip install pyspark

# Copia os arquivos .jar adquiridos nas etapas 2 e 3 para a pasta com a
# biblioteca do PySpark no ambiente virtual
cp *.jar ~/env/lib/python3.9/site-packages/pyspark/jars

Repare a pasta com nome python3.9, se sua versão de python for diferente, este vai ser o nome da pasta. Alternativamente, existem outros métodos para chegar neste resultado, se deseja explorá-los, veja este tutorial.

4 PySpark, acessando as credenciais

4.1 Extraindo arquivos da carteira

Para autenticar qualquer transação com o banco de dados, primeiramente será necessário informar a carteira de acesso Wallet_dbname.zip

Crie uma nova pasta e extraia o conteúdo da carteira nela

cd ~/lib
mkdir certs
unzip ~/Downloads/Wallet_dbname.zip -d ~/lib/certs/Wallet_dbname

Repare que dbname é o nome do banco de dados, substitua pelo nome que você escolheu ao criar o banco de dados.

4.2 Autenticando transações

A partir daqui, todos os demais detalhes da autenticação serão determinados dentro do python. A string de conexão deve fornecer o caminho para a pasta com as credencias que criamos na etapa anterior

O nome de usuário, senha, e string de conexão sempre serão fornecidos em qualquer comunicação com o banco de dados

from getpass import getpass

DBNAME = "dbname"
URL = (
  f"jdbc:oracle:thin:@{DBNAME}_high?"
  f"TNS_ADMIN=/home/user/lib/certs/Wallet_{DBNAME}"
)
USR = "ADMIN"
PWD = getpass("Insira a senha de administrador: ")
drivername = "oracle.jdbc.OracleDriver"
tablename = "example_table"

Existem maneiras mais seguras de armazenar a sua senha, tenha cuidado se pretende publicar seu código. Agora podemos testar se a nossa conexão está funcionando com este código simples:

from pyspark.sql import SparkSession, Row
from datetime import datetime, date

# data frame genérico para testar a conexão
df = spark.createDataFrame([
  Row(a=1, b=2., c='string1', d=date(2000, 1, 1), e=datetime(2000, 1, 1, 12, 0)),
  Row(a=2, b=3., c='string2', d=date(2000, 2, 1), e=datetime(2000, 1, 2, 12, 0)),
  Row(a=4, b=5., c='string3', d=date(2000, 3, 1), e=datetime(2000, 1, 3, 12, 0))
])

# exemplo de comando INSERT através da conexão JDBC
df.write.format("jdbc")\
  .option("driver", drivername)\
  .option("dbtable", tablename)\
  .option("url", URL)\
  .option("user", USR)\
  .option("password", PWD)\
  .save()

# lendo a tabela inserida
query = f"SELECT * FROM {tablename}"
read_df = spark.read.format("jdbc")\
  .option("driver", drivername)\
  .option("query", query)\
  .option("url", URL)\
  .option("user", USR)\
  .option("password", PWD)\
  .load()

 read_df.show()

Verifique se o resultado de read_df.show() é o mesmo que df.show(), se for, está funcionando!

Aprendi bastante sobre JDBC, métodos de autenticação e PySpark produzindo este tutorial, espero que você também tenha, e que você consiga tirar bastante proveito deste laboratório de Big Data, até a próxima!