Arquitetura No-Ops para Ingestão e Processamento no Lakehouse usando Terraform + Databricks (AWS)
Artigo escrito por Thiago Heron em conjunto com o Marcos Junior.
Atualmente, com o crescimento da área de dados, as empresas necessitam de uma maior ingestão e processamento de dados, com uma arquitetura que permita ser escalável, além de suportar toda a gestão e governança da mesma.
Porém, a alta complexidade das ferramentas demanda muito tempo de estudo e dedicação dos times e, por muitas vezes termos que lidar com os diferentes perfis de engenharia de dados (DataOps, Analytics Engineering, etc), a escassez dessa mão de obra qualificada no mercado resulta na sobrecarga dos profissionais nos times. Dado esse contexto, decidimos usar ferramentas e arquiteturas menos complexas, porém, mantendo a alta eficiência e desempenho do time.
Considerando que os times de engenharia são compostos geralmente por pessoas com background de desenvolvimento, torna-se muito mais tangível aprender a usar ferramentas de IaC (Infrastructure as Code) do que todas as camadas de complexidade de gestão de Clusters Kubernetes (EKS), Clusters de Map Reduce (EMR) e ainda manter a alta performance e um custo balanceado.
Pensando nos problemas citados acima — e também porque queremos uma stack de dados moderna — decidimos optar por uma arquitetura mais No-Ops e uma Plataforma de Dados do mercado já consolidada. Testamos diversas ferramentas, como: BigQuery, Snowflake e Databricks, e optamos pela última.
Agora, vamos ver as diferenças entre nossa antiga arquitetura em comparação com a nova.
Antiga Arquitetura de Dados da Warren em 2021
- Airflow (MWAA)
- Kubernetes (EKS)
- EMR Clusters / EMR Serverless
- Elastic Container Service (ECS)
- Elastic Container Registry (ECR)
Nova Arquitetura de Dados da Warren em 2022
- Terraform (Infrastructure as a Code)
- Databricks + Databricks Workflows
Databricks Workflows é um serviço de orquestrador de tasks lançado recentemente, concorrendo com Airflow, Dagster, etc. Além disso, utiliza toda a gestão de Clusters Databricks para processamento das tasks. Apesar disso, existem algumas limitações que traremos a seguir.
Prós e Contras da Plataforma
Prós:
- Gestão de Infraestrutura de Clusters, como AutoScaling, entre outros, é feita pela Databricks;
- Eliminação de gestão de ferramentas complexas como EKS + EMR, Airflow (MWAA ou Self-managed dentro do EKS);
- Custos menores para manter a nova arquitetura com Terraform + Workflows Databricks, em comparação com antiga arquitetura de EKS / EMR Cluster / EMR Serverless / Airflow (MWAA);
- Databricks atende 80% da nossa carga de processamento, sem a necessidade de nenhum tipo de tuning, pois os Clusters da Databricks já vem com seu Spark otimizado;
- Formato Delta como padrão pela Databricks que, além de diminuir o tempo de processamento dos nossos pipelines, ainda facilita a ingestão incremental (CDC) do Lakehouse;
- Baixa exigência na adaptação de códigos vindos da antiga arquitetura para Databricks (basicamente, tivemos que mudar a forma de passar os parâmetros);
- Gerenciamento de usuários facilitada para cada Workflow, permitindo diferentes níveis de acesso, como: apenas visualização, edit, trigger, etc;
- Aumento da velocidade do tempo de desenvolvimento, pois não temos mais a complexidade tuning de Spark e build de imagens Dockers, que eram necessários na antiga arquitetura;
- Databricks é uma empresa com suporte da comunidade muito grande e, também, a empresa em si tem uma frente grande de apoio aos seus clientes no Brasil;
- Seu dado fica armazenado no seu Storage (S3) e o formato Delta é Open Source, o que facilita caso a empresa queira sair da Databricks;
- Permite multi-cloud com a Databricks (AWS, GCP, Azure).
Contras:
- Apesar do Databricks Workflows possuírem mecanismo de orquestração, o Airflow possui features mais avançadas, como o reprocessamento de um período histórico e execução de tasks isoladas em uma DAG, enquanto no Workflow é necessário fazer isso através de code, ou executar apenas um dia de cada vez do seu histórico;
- Airflow possui bastante operators prontos que permitem uma ingestão de dados mais rápido, enquanto no Databricks será necessário criar através de códigos;
- Devido a essa falta de operators, é necessário usar uma ferramenta de ingestão aliada ao Databricks. No nosso caso, optamos pelo Airbyte;
- Apesar de muito completa a documentação, ela é longa, e a plataforma requer algumas horas de estudos, principalmente na configuração inicial. A curva de aprendizado depende do perfil de cada profissional, mas, no geral, é mais fácil aprender Databricks do que outras três ferramentas para atender as mesmas funcionalidades;
- Inicialização de clusters demoram alguns minutos.
Implementação da Arquitetura No-Ops
A partir de agora, vamos demonstrar como implementar um pipeline de dados e a nossa Arquitetura No-Ops com Terraform + Databricks. Antes de iniciarmos, alguns pré-requisitos:
- Conhecimento básico em Terraform.
- Possuir um Workspace criado no Databricks.
- Possuir uma conta na AWS.
Para o desenvolvimento dessa arquitetura, vamos passar por algumas etapas:
- Como configurar repositórios do GitHub no Databricks.
- Identificar informações de seu Workspace Databricks para a criação de recursos.
- Criar passo a passo o código Terraform, desde a estrutura de projeto, criação de Workflow, Clusters, Tasks, e Orquestração do Pipeline, Invocação de Código do Pipeline em um Repositório Remoto do GitHub.
- Por fim, a visualização do pipeline implementado no Workflows Databricks.
Configuração do GitHub no Databricks
Vamos iniciar pela configuração no GitHub no Databricks para que o Databricks Workflow consiga enxergar o repositório e executar os códigos com você nele.
Primeiro, entre em sua conta no Databricks, clique em Settings -> User Settings -> Git Integration tab -> Selecione o Git Provider: ‘GitHub’ -> Adicione o Personal Access Token (PAT) da sua Conta GitHub.
- Para criar um Personal Access Token (PAT) no GitHub, siga a seguinte documentação.
- Caso tenha alguma dificuldade na configuração do GitHub no Databricks, siga a seguinte documentação.
Após isso, sua conta Databricks terá acesso aos códigos de sua conta do GitHub.
Observação: O ideal é que você use uma Service Account ao invés da sua conta pessoal, e utilize ela para configurar o GitHub, PAT e Databricks.
Informações do Workspace Databricks
Após a configuração do GitHub, será necessária algumas informações de seu ambiente Databricks, que são:
- DATABRICKS_HOST
- DATABRICKS_ACCOUNT_ID
- DATABRICKS_TOKEN
Essas informações podem ser obtidas seguindo a seguinte documentação!
Essas informações serão necessárias para criarmos os recursos no Databricks e permissões AWS através do Terraform.
Desenvolvimento com Terraform
Nosso objetivo aqui é demonstrar como implementar pipelines no Workflows Databricks utilizando Terraform. Não vamos entrar em detalhes sobre controle de ambientes (produção, homologação e desenvolvimento), remotes states, state locks, etc, mas podemos no futuro escrever um novo artigo trazendo esses pontos.
Estrutura do Repositório
Os códigos do repositório estarão disponíveis no GitHub.
- main.tf: Configurações de Providers AWS e Databricks.
- workflow.tf: Databricks Workflow do Pipeline (Orquestração, Gestão de Cluster + Invocação de Códigos)
- permissions.tf: Permissões da AWS e Databricks (Roles, Policies, Instances Profiles, etc…)
- jsons/: Diretório de JSONs com Roles e Policies necessárias.
Vamos detalhar logo abaixo, para que serve e o que contém nesses arquivos.
Terraform: “main.tf”
Arquivo “main.tf”, que são as configurações de providers da Databricks e AWS e suas respectivas versões.
Terraform: “permissions.tf” — Configuração de Roles e Instance Profiles
Para que o Workflow Databricks consiga se comunicar com a AWS, é necessário a criação de uma Role na AWS, um Instance Profile (AWS) e um Instance Profile (Databricks). Para isso, vamos utilizar os seguintes recursos do Terraform:
- Resource Terraform: aws_iam_role
- Resource Terraform: aws_iam_instance_profile
- Resource Terraform: databricks_instance_profile
Terraform: “permissions.tf” — Configuração de Policies para Accesos aos Serviços da AWS
Após a configuração de Roles e Instance Profiles, o nosso Workflow já consegue se comunicar com a AWS. Agora, precisamos passar quais serviços que o Workflow terá acesso. Como exemplo, vamos criar uma Policy com permissões para que o Workflow consiga manipular objetos em um Bucket do S3. Para isso, vamos utilizar os seguintes recursos do Terraform:
- Resource Terraform: aws_iam_policy
- Resource Terraform: aws_iam_role_policy_attachment
Observação: A Policy abaixo foi criada com Full Access ao Bucket do S3 apenas para fins de demonstração. Limite os seus acessos seguindo o conceito de Least Privilege Principle das Best Practices da AWS.
Pronto! Acabamos de configurar a comunicação do Databricks com a AWS, e também demonstramos como permitir os acessos aos serviços específicos da AWS, no caso, o S3.
Terraform: “workflows.tf”
Com todas as permissões devidamente configuradas, vamos iniciar a implementação de orquestração de pipelines e criação de cluster através do Databricks Workflows.
Configurações Gerais do Workflow
- Primeiro, vamos criar um locals centralizando as configurações gerais do Workflow, como nome de pipelines, versão de spark, etc.
- Os parâmetros são autoexplicativos.
Criando o Databricks Workflow
Vamos criar um Workflow utilizando recurso databricks_job do Terraform.
Vamos adicionar o recurso databricks_job no código e atribuir os valores definidos no locals (código acima) para criar nosso Workflow Databricks Pipeline, denominado “Warren-Pipeline-Example”
Criação de Cluster no Workflow
Após a criação do Workflow, vamos criar um Cluster para o Workflow, onde as tasks serão executadas. Para isso vamos utilizar a key job_cluster do recurso databricks_job:
- Observe que, dentro de aws_attributes estamos atribuindo o Instance Profile criado arquivo permissions.tf . Dessa forma, estamos permitindo que o Cluster se comunique com a AWS e tenha os acessos aos recursos, por exemplo: manipulação de objetos no Bucket do S3, ou algum outro serviço específico, etc.
Existem duas formas de criarmos um Cluster no Workflow:
- Workflow com Single Cluster
- Workflow com Cluster por Task
Vamos dar uma olhadinha nas duas:
Workflow com Single Cluster
- Para criar o Workflow com Single Cluster, no momento da criação, é necessário passar uma configuração de spark_config.
- Essa configuração define que só terá um Single Node, ou seja, todas as tasks serão executadas em um único node.
Workflow com Cluster por Task
Para criar o Workflow por Task, é necessário criar um cluster para através do new_cluster{…} dentro cada task{…}. Além disso, você pode configurar um mínimo e máximo de workers por cluster por task.
- autoscale -> min_workers: Mínimo de workers do cluster para aquela task.
- autoscale -> max_workers: Máximo de workers do cluster para aquela task.
Criando Tasks e Orquestração no Databricks Workflow
Pronto, agora que sabemos como criar um Workflow, e como configurar Single Cluster / Cluster Por Task, vamos então criar nossas tasks que executarão o código do GitHub, e sua orquestração.
Para isso, vamos utilizar a key task{}. Dentro de task, é possível realizar diversas configurações como:
- Instalação de Libraries do PyPi, Jar, Egg, Whl, entre outros.
- Dependência entre Tasks/Jobs.
- Passagem de parâmetros para cada task/jobs (Inclusive horário de execução, etc).
- Controle de retries, delay entre cada tentativa.
- No campo notebook_task, você deve passar o caminho do código do seu repositório que deseja executar (não coloque o .py). Além, a primeira linha desse arquivo deve conter o seguinte código: “# Databricks notebook source”. Para mais informações, consulte a documentação.
Nessa segunda imagem, estamos demonstrando a criação de uma nova task, denominada “Task-2”, que tem uma dependência da Task-1. Dessa forma, é possível criar as dependências entre tasks.
Terraform Plan / Apply
Após toda a infraestrutura implementada, precisamos dar um apply no Terraform para criar os recursos na AWS e Databricks.
- Exporte as seguintes variávies de ambiente:
- DATABRICKS_HOST
- DATABRICKS_ACCOUNT_ID
- DATABRICKS_TOKEN
- AWS_ACCESS_KEY_ID
- AWS_SECRET_ACCESS_KEY
- AWS_SESSION_TOKEN (Opcional)
2. Crie um plano de execução do Terraform, e aplique a implementação:
- Step Plan:
- Step Apply:
Pronto! Após isso, os recursos já devem estar disponíveis na AWS e no Databricks.
Demonstração do Workflow no Databricks
Entre na sua conta Databricks, clique na aba lateral esquerda “Workflows”, no campo de busca, digite “Warren-Pipeline-Example”, e clique para abrir.
O resultado da seguinte infraestrutura será apresentado logo abaixo:
- Visão de Histórico de Execuções
- Visão do Plano de Execução
- Visão de Tempo de Execuções
- Visão do Configurações e Informações do Cluster.
Visão de Histórico de Execuções
- Possibilita a visualização de todas as execuções, com seu tempo e status de execução. (Succeeded, Failed, Retry, Skipped, etc).
- Permite iniciar uma execução manualmente clicando em Run now ou Run now with different parameters (permitindo passar novos valores para os parâmetros das task, como, por exemplo, um start_date diferente).
Visão do Plano de Execução
- Na parte superior, clique na aba Tasks para visualizar o Plano de Execução e a dependências entre tasks.
- É possível visualizar cada uma das suas tasks, dependência entre elas, quais clusters elas serão executadas, configurações de parâmetros, etc.
Após a execução com sucesso de um Workflow, os status das tasks serão demonstrados dessa forma:
Os exemplos de logs/outputs de uma execução:
Visão de Tempo de Execuções
- Na parte superior, clique no botão “Matrix”.
- Permite comparar os tempos de execução de cada tasks ao longo do tempo, além de seus status finais.
Visão do Configurações e Informações do Cluster.
- Na aba lateral direita, encontre o campo Compute, e depois clique em Configure.
- Possui as informações necessárias sobre seu Cluster.
Conclusões
Ainda que tenha desafios de aprendizado e a necessidade de algumas features que tínhamos na arquitetura antiga, o ganho de gestão, tempo de desenvolvimento, processamento, qualidade de entrega e custos nos fez concluir que tomamos a decisão certa ao adotar essa arquitetura, baseado no nosso contexto.
Gostaria mencionar e agradecer a Karinne Cristina, Marcos Junior e Leonardo Vinícius que participaram da construção e implementação dessa arquitetura.
Referências
Run jobs using notebooks in a remote Git Repository