Qualidade de Dados em Larga Escala com Great Expectations, Spark e Glue ETL (Case 2)
Neste artigo o objetivo é mostrar na prática, como testar a qualidade dos seus dados em arquitetura serverless utilizando o Great Expectations com Spark no AWS Glue ETL
Este artigo é uma outra versão do Qualidade de Dados em Larga Escala com Great Expectations, Spark e Airflow no EMR, só que agora utilizando o Great Expectations de forma serverless no Glue ETL.
Como no artigo anterior falei sobre os conceitos de Qualidade de Dados e do Great Expectations, aqui iremos direto ao ponto.
Os conceitos e resultados serão os mesmos do artigo anterior, mudando o meio como chegaremos aos resultados, ou seja, a arquitetura de processamento dos dados.
O código utilizado neste artigo pode ser encontrado neste repositório.
O link da data docs gerada pelo Great Expectations também pode ser acessada aqui =)
(Relembrando…) Case prático com Great Expectations
O cenário a ser trabalhado neste artigo é o mais próximo do que encontramos no dia a dia, então vamos trabalhar com o seguinte case:
Temos dados armazenados em um Data Lake que se encontra no S3 da AWS. Precisamos verificar a qualidade dos dados antes que o negócio tome decisões críticas em cima deles.
Os dados são sobre vendas de produtos de um e-commerce e nos diz muito sobre o comportamento dos clientes dessa loja.
Os dados utilizados para este artigo são abertos e se tratam de vendas do site da Amazon que podem ser encontrados no kaggle, neste link.
Arquitetura do Great Expectations com Spark no Glue ETL
Neste momento iremos analisar a arquitetura utilizada neste projeto, mostrando como as peças se interligam e assim executar o Great Expectations (GE) no Glue ETL.
A arquitetura considera a utilização de três buckets no S3: o primeiro para armazenar o script a ser executado no Glue ETL (spark-code), o segundo contém os dados a serem testados (data) e o terceiro armazena a documentação gerada pelo GE (data docs).
Os testes são executados através de um job do Glue ETL com agendamento diário pelo EventBridge.
E toda a infraestrutura será construída com o Terraform, conforme o desenho da arquitetura a seguir:
Agora vamos para a parte “mão na massa”!
1. Criação do script Spark com Great Expectations
Para a criação do script Spark que contém os casos de testes, iremos dividi-lo em alguns passos, conforme a seguir:
Configuração do contexto
O contexto do GE indica as principais configurações a serem consideradas para executar os testes.
O código a seguir faz a configuração do contexto através de um YAML criado por um objeto do próprio Python.
A configuração deste contexto basicamente é informar que o Spark é utilizado para realizar os testes, pois poderia ser outro cenário, como a utilização do Pandas.
Configurando a Data Docs
Um ponto importante aqui é a configuração do local em que será salva a nossa Data Docs. Por padrão a documentação HTML é gerada no armazenamento local, porém para este artigo, a data docs será armazenada e hosteada pelo S3.
Nas configurações precisamos indicar um bucket especifico para salvar a documentação.
No código a seguir, o bucket de destino (output_path) está sendo passado como parâmetro, assim o script fica mais dinâmico e personalizável.
Criação de um Validator
Antes de adicionar os casos de testes, é necessário configurar um Validator, nele indicamos os testes em forma de Batch Request.
O Validator já incorpora as funções de validação dos dados de forma built-in conforme veremos mais adiante, o que facilita e deixa muito mais intuitivo a criação dos casos de testes.
O código abaixo configura e cria o Validator utilizando o contexto dos nossos testes e também o dataframe que contém os dados para validação.
Criando os Casos de Testes
Chegou o momento mais esperado, criar os casos de testes.
Nesta etapa o objetivo é trabalhar com dois cenários de casos de testes:
- o primeiro é executar um perfil dos dados (profile)
- o outro é adicionar os casos de testes personalizados, conforme a necessidade do negócio.
- Profile dos dados
Um Data Profile refere-se ao processo de examinar, analisar, revisar e resumir conjuntos de dados para obter informações sobre a qualidade dos dados.
O GE permite criar um profile dos dados de forma automática e muito simples.
Nesse profile será gerada informações sobre todas as colunas dos dados e testes para checar valores nulos, tipos dos dados, padrão mais recorrente em cada coluna e outros.
Para criar um profile dos dados e adicionar ao contexto de testes, basta ter o código a seguir:
Um ponto importante é que o profile é executado através de um objeto Spark criado pelo GE (df_ge), como será visto posteriormente, o que difere dos demais casos de testes que serão adicionados a seguir, pois são feitos em cima do objeto Validator (criado no passo anterior).
Outro ponto a destacar é que foi utilizado um nome para a suite de testes do profile e outro para os testes dos validators, assim na data docs ficarão separados, isso ajuda na organização da documentação.
- Casos de testes
Agora basta adicionar os casos de testes conforme a necessidade de validação dos dados.
O código a seguir adiciona os seguintes testes:
- validar se todas as colunas desejadas estão no dataset;
- validar se o campo product_id tem valores únicos e não nulos;
- validar se o campo discount_percentage contém apenas valores entre 0 e 100;
- validar se o campo rating contém apenas valores entre 0 e 5;
- validar se o campo product_link contém apenas dados com um formato válido de um link, isso utilizando um regex para validar o padrão.
Após adicionar todos os casos de testes desejados, basta salvar as expectativas na suite de testes.
Executando os testes
(Parte adaptada para o Glue ETL)
Agora chegou o momento de ligar todos os pontos.
O código abaixo é a função principal que será chamada pelo Spark, ela faz a leitura dos dados que desejamos e executa as outras funções que discutimos anteriormente.
Gostaria de destacar três pontos do código acima:
- O primeiro ponto é que foi utilizado o contexto do Glue para ler os arquivos do S3 e depois convertermos os dados de Dynamic Dataframe (objeto do Glue) para um Dataframe do Spark, pois o GE no final aceita um Dataframe Spark para execução dos testes.
- O segundo ponto é para a linha de código abaixo, pois é nesse momento que o GE realmente executa as validações. Até então ele estava apenas adicionando ao Grafo de Execução e não executou de forma concreta. Ao executar o método validate, os testes são executados e os resultados retornados de forma estatística.
- O terceiro ponto é que depois da execução dos testes, conseguimos gerar a data docs, indicando qual configuração utilizar. No cenário aqui, o nome da configuração é s3_site.
Função principal
Gostaria apenas de destacar mais um ponto do script, a função main que contém a criação do Contexto Glue a partir do contexto padrão do Spark, possibilitando assim a leitura e manipulação dos dados armazenados no S3 de forma nativa.
2. Criação da Infraestrutura com Terraform
Para agilizar, controlar e reproduzir nossa infraestrutura, iremos aqui utilizar o Terraform, assim criaremos:
- Glue ETL Job;
- agendamento da execução no EventBridge;
- upload do script para o S3 e;
- IAM roles.
O código a seguir mostra como podemos criar um job do Glue ETL no Terraform, inclusive indicando onde estará armazenado o script que criamos anteriormente (s3://cjmm-code-spark/data_quality/glue_etl/main.py) e as bibliotecas a serem instaladas no ambiente de execução, além das configurações de computação que desejamos para o ambiente a ser utilizado para execução do código.
A seguir temos o código para criar o agendamento no EventBridge, que está vinculado ao Glue Job criado anteriormente, automatizando a execução do para todos os dias (horário de 00:00 UTC).
Também temos o upload do script PySpark que está no mesmo projeto do Terraform para dentro de um bucket no S3, assim o Glue Job terá acesso para copiar esse arquivo e executar em seu serviço.
Caso queira conferir o código completo e a criação das roles do IAM, só acessar o código do Terrafrom que está no repositório do projeto.
3. Execução do Script no Glue ETL
Conforme vimos anteriormente, o script será executado diariamente através do agendamento feito utilizando o EventBridge, agora veremos os detalhes do job no Glue e também a possibilidade de executá-lo manualmente.
Logo abaixo temos a imagem que representa o nosso job criado no Glue ETL, onde é possível selecioná-lo para alteração, execução e até exclusão.
Ao acessar o job é possível verificar as últimas execuções, os detalhes do agendamento e também outras informações como o próprio script no editor do Glue ETL:
Como mencionado, podemos verificar os agendamentos de execução para o job:
No Glue ETL ainda podemos analisar o monitoramento dos jobs, visualizando as execuções, falhas, debugar o código por logs e até mensurar os custos das execuções:
4. Resultados
Agora é o momento de analisar os dois resultados dos testes executados.
O primeiro são os arquivos da data docs salvos no bucket do S3, conforme abaixo:
E o segundo resultado é ao acessar a data docs, conforme abaixo:
Lembrando que a data docs criada neste artigo pode ser acessada neste link.
Ao acessar a suite com o profile dos dados temos o resultado a seguir:
E ao acessar a suite com o casos testes criados temos o resultado abaixo:
Conclusão
O Glue ETL é uma ferramenta que traz o propósito do serverless, que é pagar só pelo o que utilizamos, escalabilidade gerenciada e aceleração da entrega de valor.
Minha dica final é apenas analisar a relação de custo, pois o Glue ETL pode ficar bem caro em relação a computação e o tempo utilizado para processar e testar os seus dados, levando em consideração o cenário deste artigo.
Assim vale a pena pensar no Glue ETL que acelera a execução de scripts Spark em relação ao EMR, Spark on Kubernetes entre outras possíveis soluções.
Siga-me:
LinkedIn: https://www.linkedin.com/in/cicero-moura/
Github: https://github.com/cicerojmm