Skip to content

Projeto de engenharia de dados, utilizando ferramentas big data, como pyspark, databricks e GCP.

Notifications You must be signed in to change notification settings

annamatias/gcp_dataops

Repository files navigation

Apache SparkGoogle CloudPythonJupyter NotebookPrometheusGitHub ActionsDatabricksDelta Table

GCP DataOps

Projeto com todos os processos de DataOps

CI

Sobre

O projeto representa todos os processos de DataOps, ele contém CI/CD, criado com o Actions Workflows do GitHub para podermos testar o código após o push. Trazendo mais segurança e uniformidade ao código, evitando futuros erros na execução, e integridade ao dividir o código entre a equipe. Estamos utilizando do Google Cloud Platform, para utilização IaaS (Infraestrutura como Serviço), usufruindo da Compute Engine, Databricks e Storage Cloud.

O desenvolvimento da ingestão de dados, estaremos utilizando das tecnologias: Python, Pyspark e Delta Lake. Esquematizando a visualização de dados, utilizaremos do próprio Databricks, e finalizando o fluxo de DataOps, ele deve conter Data Observability e Data Monitoring, nossa infraestrutura ela já consta com otimas ferramentas de monitoração da nossa aplicação, e para fecharmos com chave de ouro iremos utilizar dos loggers, para garantir rastreabilidade de erros no nosso código.

Sem contar que para entregarmos dados com a qualidade, esse projeto conta com boas práticas de Data Quality e testes unitários feito em pyspark, para além de testarmos o resultado esperado em nossas funções, atenderemos os pilares de qualidade dos dados, entre eles: precisão, completude, consistência, validade, exclusividade e pontualidade.

Até então, não é ideal utilizar spark para a pequena quantidade de dados, o ideal é acima de GB (Giga Bytes), mas é um projeto, visa trazer aprendizados da vida real, com conteúdo técnico.


Executar Projeto

Você pode realizar o clone, e executar o jupyter notebook, mas não vai funcionar como é o verdadeiro objetivo (Utilizar o GCP para execução juntamente com o Databricks).

Para executar o meu projeto, recomendo criar uma conta no google cloud platform, caso não tenha e realizar os passos abaixo de configuração e execução. Nessa doc do projeto tem todos os passos para reproduzir um equivalente ao meu, mas é necessário apenas configurar a conta e importar o arquivo e executar no ambiente configurado.

Clonagem

> git clone https://github.com/annamatias/gcp_dataops.git


Configurando GCP (Google Cloud Platform)

Depois que criamos nossa conta, ele já cria um projeto automaticamente, para termos controle de qual projeto estamos mexendo, vamos renomear.

No canto superior direito, ao lado esquerdo da sua foto de perfil da conta do google, temos um menu, iremos clicar nele e ir até Configuração do projeto, conforme imagem abaixo. Eu coloquei o nome de Databricks with GCP, fique a vontade para escolher o seu.

image

imagem 1 - Acessando configurações

image

imagem 2 - Alterando nome do projeto e salvando

Ativando Databricks

No canto superior esquerdo, temos um menu bar, acessando ele, vamos atrás do Databricks, o GCP te trás opção de fixar para aparecer logo em cima. Eu fixei para encontra-lo com maior facilidade.

image

imagem 4 - Databricks fixado

Depois que acessar o databricks, clique em Assinar e concorde com os termos e condições. Antes do botão acessar, irá mostrar o resumo do pedido e quantidade de dias que estará gratuito.

Outro ponto importante você tem que ter um cartão para faturamento, mas fica calmo que a Google não vai sair cobrando nada de você. Muito pelo contrario e é uma experiencia muito boa que eu obtive, quando passa o prazo de gratuidade e você não assina o pacote completo, ele automaticamente apaga e corta os recursos utilizados para não gerar nada, e você não será cobrado.

image

imagem 3 - Resumo do pedido, ao assinar o Databricks

Faça login sempre com a conta que utiliza o GCP, depois que selecionar o plano que eles indicam para você criar a conta no Databricks, e vai aparecer uma tela conferme a próxima imagem. Observe que eles pedem o nome de uma organização, você escreve o nome que achar melhor.

image

imagem 5 - Criando conta

Feito o processo acima, importante citar que vai ser enviado um e-mail com a confirmação da criação da conta, parecido com o e-mail abaixo.

image

imagem 6 - Exemplo e-mail

Depois que chegar o e-mail, volte novamente na console do GCP na aba do Databricks. Iremos clicar em "Gerenciar no fornecedor" nele, ele vai te redirecionar para um link para você fazer login e criar o seu workspace. Antes disso, iremos realizar login novamente e selecionar o plano de assinatura, é só confirmar.

image

imagem 7 - Gerenciar no fornecedor

image

imagem 8 - Plano de assinatura

Feito os passos acima, ele vai abrir o workspace, conforme dissemos anteriormente, iremos criar o nosso "Criar Workspace".

Aqui nesse passo é bem simples. Basta colocar o nome do workspace que deseja, você vai copiar do GCP o ID do projeto e colar lá, e na região SEMPRE busque utilizar us-central1 porque esse é uma das regiões gratuitas.

image

imagem 9 - Configuração workspace

Feito isso, você vai finalizar e vai receber um email, lá vai ter o link que está apto a mexer no databricks, ou então você pode clicar logo em seguida no workspace que criou e aguardar o link ser disponibilizado, conforme exemplo abaixo.

image

imagem 10 - Workspace preparando o link

Acessando o link, vamos criar um cluster, ele já aparece logo no inicio bem grande, ele já vai criar com as configurações necessárias para você mas você pode alterar de acordo com a necessidade. Como é um projeto simples vou deixar do jeito que está.

image

imagem 11 - Criando cluster

Gratuidade

Reforçando recado IMPORTANTE!

O GCP é gratuito por 90 dias para novos usuários e o Databricks por 14 dias (Lembrando que os prazos sempre estão sujeito a alterações). Fique sempre atento a esse prazo, para que não tenha eventuais cobranças futuramente.

O próprio google alega que depois de 90 dias caso não tenha o upgrade, ele exclui todos os seus projetos, mas faça isso antes..."O seguro morreu de velho" - Como diz meus pais.

CI/CD GitHub e Databricks

Neste projeto iremos realizar a conexão entre Github e Databricks, para CI/CD. Primeiro vamos conectar o nosso repositório.

Se você estive utilizando a versão gratuita talvez tenha limitações para conseguir realizar a integração, caso já tenha muitas coisas dentro do repositório.

Para adicionar, devemos ir na sessão de repositórios, como a imagem abaixo, adicionar as informações que solicitam, basicamente o link do clone do repo. Feito isso é só criar um repositório.

image

imagem 12 - Criando repositório

Concluindo o passo acima, já é possível visualizar o nosso repositório e as pastas.

O Databricks ele é bem completo, principalmente a sua documentação, onde pela própria interface conseguimos criar uma nova branch, realizar commits, push, pull, merge pela mesma interface.

image

Github Actions

Para termos nossa esteira de integração e entrega continua, vamos utilizar os workflows do github. Ele vai servir para manter a acuracia do código, para não haver futuros erros e depuração de código demorada para cada usuário que esteja utilizando do repositório.

Estou seguindo essa documentação do github para implementarmos workflows no python.

PyLint

Primeiro de todos os workflows, baseado em DataOps, iremos implementar o Lint, ele serve para verificar se a escrita do nosso código está correta, evitando erros futuros, antes mesmo de o código estar em vigor executando.

O exemplo a seguir instala ou atualiza o ruff e o usa para fazer lint de todos os arquivos. Para obter mais informações, confira Ruff. Dei uma adaptada baseado na doc do github actions, acrescentei o nome, onde ele vai executar e o jobs build.

Para aplicar, você tem que criar uma nova pasta oculta .github/workflows e um arquivo yml, com o conteúdo abaixo.

name: Pylint

on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    - name: Set up Python
      uses: actions/setup-python@v4
      with:
        python-version: '3.x'
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install -r requirements.txt
    - name: Lint with Ruff
      run: |
        pip install ruff
        ruff --format=github --target-version=py37 .
      continue-on-error: true

A etapa de lint tem continue-on-error: true definido. Isto impedirá que o fluxo de trabalho falhe se a etapa de limpeza de código não for bem-sucedida. Após corrigir todos os erros de limpeza de código, você poderá remover essa opção para que o fluxo de trabalho capture novos problemas.

Verificando Build Pylint

O nosso primeiro build, a ideia é que falhe mesmo, porque estamos configurando ele. Como estamos realizando a instalação do requeriments no nosso bash, mas ele não existe ainda. Segue um mini gif, ensinando como verificar o seu build aqui no github.

image

imagem 13 - Verificando build

Mas ele está pronto o nosso build, agora com a implementação do código e executando na máquina local, você consegue realizar testar tudo o que foi instalado no ambiente virtual. Eu comentei esse trecho de dependencias por enquanto para visualizar a funcionalidade e ele funciona lindamente.

image

imagem 14 - Execução build pylint

ELT/ETL

Realizando Pull

Somente seguir o gif abaixo, para realizar o pull após alterações.

image

imagem 15 - Criação de pull request

Criando pastas e arquivos dentro do repositório

Exemplo de criação de pastas e notebook dentro de um repositório no Databricks;

image

imagem 16 - Criação de pastas dentro de um repositório no Databricks

Criando um notebook

Feito tudo acima, agora conseguimos utilizar do nosso cluster.

No canto superior esquerdo vamos em Data science e engineering, clique no + para criar um notebook.

Onde está os meus notebooks?

No canto superior esquerdo vamos em Data science e engineering, clique em Workspace para ver todos os notebooks, pastas criadas dentro do databricks.

Realizando a importação de um arquivo

Você pode simplesmente baixar e depois arrastas ou procurar via desktop o seu arquivo, e realizar o deploy.

image

imagem 17 - Deploy de um arquivo

Realizando upload de arquivo no Storage Cloud

Iremos acessar via console o storage cloud, depois disso é somente adicionar um novo arquivo no caminho desejado. Como vou utilizar o arquivo no databricks, eu adicionei dentro de uma pasta /tmp

image

imagem 18 - Deploy de um arquivo no storage

Realizar leitura e armazenamento de dados

Para isso recomendo olhar o código adicionado na estrutura.

Mas deixo aqui uma breve visualização de como é o comportamento após armazenar os dados particionado por uma coluna e no formato Delta via GCP.

image

imagem 18 - Console storage cloud no GCP após armanezamento

Criar uma branch e criar pull request para main via Databricks

A nossa primeira vez, ela vai estar desconfigurada e vai solicitar que realizemos as devidas configurações. Para isso, no seu email utilizado para realizar os commits dentro do seu repositório, exclusivamente para ele teremos que criar um SSH com permissões para o Databricks ler e gravar os dados.

Documentações de apoio:

Os passos acimas é necessário que você tenha feito o git clone do seu repositório, na sua máquina, abra o terminal de preferência e execute os comandos. Vou deixar abaixo um guia via terminal de como eu fiz e depois via interface onde eu adicionei, mas recomendo que você mesmo faça a leitura.

A geração de SSH para escritura no repositório com o seu e-mail, ela é feita em muitos lugares. Então esse conhecimento vai ser útil em experiências profissionais. Pode ocorrer num Azure DevOps, Amazon, GCP with Databricks e muitos outros.

# Para verificar se existe chave:
>  ls -al ~/.ssh

# Para gerar uma nova SSH para o meu e-mail

> ssh-keygen -t ed25519 -C "your-email" 
Generating public/private ed25519 key pair.
Enter file in which to save the key (/Users/annakarolinymatias/.ssh/id_ed2558689): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 


# Para verificar se foi feito com sucesso

> eval "$(ssh-agent -s)"
Agent pid 59115

# Adicionando a chave

> ssh-add --apple-use-keychain ~/.ssh/id_ed25519
Enter passphrase for /Users/annakarolinymatias/.ssh/id_ed2558689: 
Identity added: /Users/annakarolinymatias/.ssh/id_ed2558689 (your-email)

# Para copiar a secret SSH

> pbcopy < ~/.ssh/id_ed25519    
                             
# Para visualizar a key para adicionar no Github SSH

> cat ~/.ssh/id_ed25519.pub 
ssh-ed2558689 AAAAC3NzLEJ2/zunnWAEXwg8c5m your-email

Exemplo após adicionar a key ao Github via interface

image

imagem 19 - Exemplo depois de adicionar a key

Feito isso, temos que gerar um token de acesso pessoal para colocar no databricks. Para isso iremos em configurações e depois configurações do desenvolvedor. Gerar um token pessoal e selecionar as permissões desejadas para esse token de acesso.

image

imagem 20 - Caminho feito para obter o token pessoal

Após gerar esse token, acrescentamos ele dentro do nosso databricks, para que seja possível criar branchs e realizar outras operações de leitura e escrita, passando por nossa esteira de integração e entrega continua. Sendo possivel visualizar depois de cama push o nosso build em git actions.

image

imagem 21 - Exemplificação após acrescentar o token no databricks

Abrindo pull request

Após criarmos uma branch, vamos colocar a mensagem da alteração e adicionamos, feito vai surgir um link de acesso a nossa PR (pull request), iremos acessar e finalizar o processo, conforme abaixo.

image

imagem 22 - Exemplo via interface de criação de PR

Direcionando para o nosso Github, conseguimos visualizar o nosso pull request e em sequência vamos criar ele.

image

imagem 23 - Visualização da PR no github

Depois de feito a PR, vamos esperar finalizar o nosso build e em seguida iremos completar o merge na main.

image

imagem 24 - Build concluido e realização do merge

Outro ponto importante, na aba actions é possível verificar todos os build que já ocorreram e os quais estão na fila executando.

Clicando no build também conseguimos visualizar de forma detalhada todas as configurações que acrescentamos para verificar na nossa integração continua.

image

imagem 25 - Visualizando builds no actions

Como criar um Job com Schedule?

No canto superior esquerdo vamos em Data science e engineering, clique em Workflows para ver todos os jobs criados, e para criar um novo, você vai no canto superior direito em Create Job.

Testes com Pyspark e Data Quality

Abordando um assunto de extrema importancia, após passar por muitos processos acima que estão inclusos dentro do DataOps, temos um dos principais pilares. O Data Quality ele diz muito sobre a qualidade dos dados e testes que podem ser implementados para garantir que a informação que temos ela realmente é confiável.

Temos esse artigo: https://www.heavy.ai/technical-glossary/data-quality, e ele é bem objetivo referente a Data Quality. De ferramentas temos algumas como o Great Expectations e o PyDeequ, ambas na linguagem Python, é claro que pode ter outras, mas essas duas é a mais falada.

Indo para a prática dos testes, primeiro eu peguei o código de ELT do notebook e consolidei em um arquivo.py com os métodos isolados para executar localmente e testar-los. Partindo desse principio, vamos alterar o nosso build para testarmos o nosso código.

Antes disso, para executar o nosso código, foi necessário realizar a instalação de algumas dependências. Caso tenha feito o clone desse repositório, você pode apenas instalar os requeriments e já ter acesso a todas as instalações.

  • pip install delta-spark
  • pip install pyspark

Feito as instalações acima, acredito que não falte mais nada, então iremos para a correção do nosso build. O que teremos de diferente é o coverage, ele serve para verificar se estamos com a cobertura 100% de testes para os nossos códigos e utilizamos ele para verificar se ele executou com sucesso, erro ou falha os testes. Adicionamos aqui também um ignore em um erro de linha maior no flake8 e estou ignorando a pasta de notebooks, no meu caso não tem porque deixar rodar o lint nele porque é mais um arquivo de testes.

name: CI

on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: "3.x"
      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          python -m pip install flake8 coverage
          pip install -r requirements.txt
      - name: Lint with flake8
        run: |
          flake8 --ignore=E501 src/ tests/ --exclude=src/notebooks
      - name: Run unit tests and generate coverage report
        run: |
          coverage run -m unittest -v
          coverage report
          coverage html

Subindo esse código já vamos ter um build com testes, sempre quando subirmos um push, ele será feito esse build. Falando sobre a construção de testes em pyspark, eu sempre sigo um tutorial da Cambridge, ele é bem objetivo e ele diz sobre uma estrutura base para podermos rodar os nossos testes.

  • Logger, para rastrear erros em nivel de loggers (aqui diz muito sobre data observability.
  • setUpClass, para criarmos uma sessão no spark, dentro dele iremos executar o nosso código spark.
  • tearDownClass, ele serve para apargarmos os arquivos criados temporariamente e finalizar a sessão do spark para não ficar executando infinitamente.

Podendo visualizar o código dessa forma:

class PySparkTest(unittest.TestCase):

    @classmethod
    def suppress_py4j_logging(cls):
        logger = logging.getLogger("py4j")
        logger.setLevel(logging.WARN)

    @classmethod
    def create_testing_pyspark_session(cls):
        builder = SparkSession.builder \
            .appName("Testes Pyspark") \
            .config("spark.sql.extensions", "io.delta.sql.DeltaSparkSessionExtension") \
            .config("spark.sql.catalog.spark_catalog", "org.apache.spark.sql.delta.catalog.DeltaCatalog")
        spark = configure_spark_with_delta_pip(builder).getOrCreate()
        return spark

    @classmethod
    def setUpClass(cls):
        cls.suppress_py4j_logging()
        cls.spark = cls.create_testing_pyspark_session()

    @classmethod
    def tearDownClass(cls):
        shutil.rmtree(
            "tests/storage_test")
        cls.spark.stop()

Se vocês observarem no artigo indicado, sendo ele nossa base para testes, eu fiz algumas adaptações e elas estão descritas no próprio site do Delta, para executarmos funcionalidades do Delta, além de instalarmos temos que subir algumas configurações no spark para ele reconhecer e executar de forma correta. Portanto é possível ver a diferença no nosso setup com configurações especificas direcionada ao Delta. Outro ponto importante, essa configuração ela é especifica para a instalação via pip, conforme o guia de instalação do próprio site da Delta Table.

Construindo alguns testes com unittest, não fica muito diferente do python tradicional (no caso, sem a utilização de algum framework), que é possivel verificar nessa pasta do repositório o código completo https://github.com/annamatias/gcp_dataops/blob/main/tests/unit_tests/tests_ingestion_cardiovascular_diseases_risk.py

Feito os testes, subimos uma PR e assim que subimos já podemos verificar o push, se foi com sucesso ou não. Detalhe tem todas as ocorrências possiveis de execução no nosso build, e fica tão satisfatório de ver. Deixo aqui um exemplo de build com testes.

image

imagem 26 - Build testes com coverage

Data Visualization

No nosso projeto de arquitetura base, abordamos após a ingestão de dados armazenado no storage a visualização de dados. Esse tema é muito extenso, podendo ter varias ferramentas para realizar a visualização de dados. Nesse projeto vamos utilizar o próprio Databricks para a visualização, mas poderiamos fazer dashboards atrativos sobre os dados em um PowerBI e entre outras ferramentas.

Dashboards no Databricks

Para iniciarmos, primeiro vamos alterar o ambiente para o SQL, iremos na aba paineis e criar um novo dashboard, conforme a próxima imagem.

image

imagem 26 - Interface de criação de dashboards

Aqui tem muitas possibilidades, você pode instalar alguns exemplos de dash e refazer no seu. Você pode criar paineis a partir de uma consulta SQL com a visualização que é a melhor para transmitir um determinado objetivo. Lembrando que visualização de dados não é apenas criar dashboards, é transmitir de uma forma bonita, legivel, objetiva o verdadeiro valor da informação.


Status do Projeto

Finalizado.

Arquitetura Base

image


Referências


Autor

Anna Karoliny - Mentora, Professora, Desenvolvedora e Engenheira de Dados

About

Projeto de engenharia de dados, utilizando ferramentas big data, como pyspark, databricks e GCP.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages