mais lidos
Life at Nu
Conheça a sede do Nubank em Pinheiros, São Paulo/Brasil jan 11
Design
A nova aparência do Nubank: conheça nossa nova logo maio 17
Culture & Values
Como os valores e a cultura da Nu moldam os produtos que criamos ago 7
Carreiras
Reunimos grandes mentes de diversas origens que permitem a discussão e o debate e melhoram a resolução de problemas.
Saiba mais sobre nossas carreiras


À medida que a análise de dados se torna mais impactante, as equipes de dados crescem e os conjuntos de dados ficam mais numerosos. Isso acarreta novos desafios de colaboração e eficiência, assim como a qualidade e facilidade de descoberta.
No Nubank, o maior banco digital do mundo, com 40 milhões de clientes, os dados estão no cerne do nosso negócio. Eles estão presentes nas tomadas de decisão automáticas para concessão de crédito, no envio de comunicações personalizadas, ou na geração de relatórios de regulamentação. Temos uma plataforma de dados de autosserviço onde todo mundo pode pesquisar qualquer dado que não seja restrito (como dados não pessoais), criar tabelas e adicioná-las aos nossos pipelines. Em 8 anos, chegamos perto de 800 contribuidores, que adicionaram 40 mil tabelas ao nosso pipeline de dados.
Com o aumento de usuários e uso dos dados, identificamos dois fatores essenciais para continuar usando os dados de forma ágil e produtiva: a organização da equipe e padrões de engenharia, para incentivar boas práticas de colaboração.
Com relação à organização da equipe, criamos o cargo de Engenharia de Análise, uma função dedicada à estratégia e gerenciamento de dados em termos de qualidade, privacidade, confiabilidade, arquitetura e custos. Os engenheiros de análise estão na maioria das equipes de produto e equipes multifuncionais. Eles trabalham com uma equipe de plataforma de dados focada em infraestrutura e ferramentas.
Quanto aos padrões de engenharia, desenvolvemos processos técnicos e ferramentas que nos permitem fazer a empresa triunfar, permitindo que os contribuidores de dados trabalhem de forma autônoma e produtiva e aproveitem o trabalho de outras pessoas ao longo do tempo.
Quais são os padrões de engenharia que permitem um trabalho com dados mais eficiente e colaborativo?
Neste artigo, mostraremos como usamos padrões de engenharia de software para:
Conheça nossas oportunidades
Parte 1: Permitindo contribuições autônomas e estruturadas
Para escalar nosso processo de contribuição para os pipelines de dados, tentamos encontrar o equilíbrio correto entre liberdade total e estrutura tediosa. Atualmente, qualquer Nubanker treinado consegue criar uma tabela e adicioná-la ao pipeline em algumas horas, ou menos, de forma praticamente autônoma, com um processo otimizado de revisão por pares. Isso nos permite iterar rapidamente no trabalho com dados.
Objetos estruturados padronizados
Todo o nosso sistema de dados se baseia em vários componentes padronizados no Scala. Toda tabela é criada por meio de um objeto padronizado específico, com atributos estruturados.
Um objeto de tabela de dados em nosso sistema é composto por três tipos principais de atributos:
A lista de entradas nos permite adicionar a tabela automaticamente para ser executada no pipeline, no local correto do gráfico de dependência.
Quanto aos metadados, dependendo da camada de qualidade dessa tabela, todos, ou apenas uma parte dos atributos dos metadados, serão necessários, a fim de garantir uma boa documentação para conjuntos de dados de alta qualidade, como conjunto de dados centrais, e limite de atrito para criar conjuntos de dados experimentais. Os metadados de permissão necessários também nos permitem configurar facilmente o gerenciamento de acesso granular.
Nomeando convenções, reusabilidade de métricas e organização de arquivos
Para facilitar a descoberta de dados e incentivar a coerência e consistência das métricas, implementamos convenções de nomenclatura para as tabelas e para as métricas.
Nós também criamos estruturas que nos permitem definir uma métrica uma vez (seu código de cálculo e os metadados) e reutilizá-la em vários conjuntos de dados.
Por fim, definimos uma organização de estrutura de arquivos específica em nosso repositório para garantir que a descoberta do código é fácil, que todos os códigos que precisam ser executados por nosso pipeline de dados estão no lugar certo, e que temos os acessos corretos e atendemos aos requisitos para o gerenciamento de mudanças.
Processo de teste de qualidade
Para permitir que qualquer pessoa escreva uma consulta e a adicione ao pipeline, precisamos confirmar a execução de algumas verificações de qualidade.
Estamos testando a qualidade em dois níveis: transformações da própria consulta (testes de unidade) e funcionamento geral com o resto do sistema (testes de integração).
Primeiramente, há vários testes pequenos chamados de testes de unidade, escritos pelos contribuidores de dados. Esses testes conferem se os resultados correspondem aos esperados pelas transformações.
Nós escrevemos nossas consultas no Scala, que nos permite dividir as transformações em pequenas funções que podem (e devem) ser testadas por unidade. Para testar as transformações do Spark, usamos a suíte de testes Holdenkarau , que nos dá as classes-base necessárias para executar consultas no Spark. Um teste de unidade geralmente é assim:
Continuando, temos que nos certificar de que se adicionarmos essa tabela ao pipeline de dados, ela funcionará bem com o resto do sistema e nada mais será afetado negativamente. Isso se chama teste de integração. Para publicar uma nova tabela ou fazer alterações a uma já existente, todos os testes de integração devem ter um resultado positivo. Eles conferem se todas as entradas existem, se essa é uma tabela nova ou uma coluna de tabela, ou se alguma inconsistência poderia ocorrer no tempo de compilação. Esses testes de integração são escritos pela equipe da plataforma central; eles não precisam ser reescritos para cada tabela ou alteração nova.
Parte 2: Aprimorando a colaboração e o trabalho em equipe
Compartilhamento de conhecimento em revisões de códigos
A revisão por pares finaliza o processo de contribuição para o nosso pipeline de dados. Ela ajuda a garantir que o código tenha boa qualidade e segue as melhores práticas, dar um feedback prático assíncrono para o contribuidor e treinar o revisor para explicar seu feedback. No geral, o conhecimento é transmitido perfeitamente através dessas revisões.
Há duas revisões para adicionar um novo objeto ao nosso repositório de dados: uma para verificar a lógica do negócio e outra para verificar as melhores práticas do Scala, do Spark e de testes.
Os engenheiros de análise e outros contribuidores superiores se revezam nas responsabilidades da revisão técnica. Uma boa parte da revisão foca em garantir que o código está claro e legível, dividido em pequenas funções, com testes de unidade claros. Geralmente conseguimos revisar todos os pull request em um único dia.
Reutilizando códigos com bibliotecas
Outro padrão para trabalhar em grandes projetos de engenharia é garantir que os contribuidores construam a partir do que outros já fizeram, para serem mais produtivos e focar nas novas adições.
Um dos motivos que nos faz ter o código-base de dados no Scala é dar autonomia aos usuários de dados para criar e construir em bibliotecas que contêm as funções já desenvolvidas por outras pessoas. As equipes usam, criam e contribuem com as bibliotecas para reutilizarem as mesmas estruturas e definições entre diversos conjuntos de dados, além de gerar vários conjuntos de dados similares de forma programática e adicioná-los ao pipeline de ETL.
Por exemplo, nossa Plataforma de Experimentação gera conjuntos de dados automaticamente com várias métricas para cada teste A/B; assim, as decisões podem ser tomadas rapidamente, sem restrições analíticas.
Isso aumenta a velocidade de entrega de novos conjuntos de dados e também simplifica a manutenção e consistência. Dessa forma, a lógica centralizada passa por manutenção uma única vez para vários conjuntos de dados. Em resumo, esse processo aumenta a eficiência e a qualidade das análises.
Documentação e descobertas
Um aspecto essencial para a colaboração eficiente é permitir que qualquer pessoa encontre a informação correta de forma fácil. Nós trabalhamos para deixar a documentação disponível em diferentes níveis: no processo de contribuição e na nossa plataforma de dados, no objetivo e detentores de conjuntos de dados, e em todas as colunas e métricas para cada tabela.
Estamos desenvolvendo ferramentas internas e painéis para facilitar a descoberta e a navegação dessa documentação e dos metadados, para que os Nubankers possam ser mais eficientes no trabalho com dados. Temos o Compass como exemplo, nossa ferramenta de pesquisa de dados internos, que busca informações dos metadados que geramos.
Parte 3: simplificando a posse da vida útil dados
monitoramento com o uso de metadados
Precisamos garantir que o sistema funcione totalmente. O monitoramento nos permite ter planos de governança de dados e OKRs (objetivos e resultados-chave), além de certificar que tudo está consistente e com boa qualidade ao longo do tempo.
No geral, monitoramos a qualidade dos dados gerados pela consulta, a otimização da consulta, a experiência do usuário e aspectos de governança relacionados à posse de dados, as dependências de linhagem e restrições de acesso. Nosso monitoramento se baseia em nossos metadados declarados a partir dos nossos objetos estruturados, bem como em métricas calculadas automaticamente, como contagem de linhas, valor médio de uma coluna, tempo em que uma tabela estava disponível e tempo para executar uma consulta.
Mostramos essas informações em painéis, além de alertas que enviam diretamente uma mensagem no Slack para as pessoas responsáveis, acionados por algumas regras de criticidade.
Manutenção de conjunto de dados ao longo do tempo
Os usuários costumam ter a expectativa de que as tabelas no pipeline de dados permaneçam corretas. Contudo, a inovação iterativa de produtos está geralmente relacionada a alterações nos dados coletados ou em sua estrutura. As necessidades de manutenção podem surgir de forma proativa, devido ao desenvolvimento de novos produtos e reestruturação de serviços, ou de forma reativa, por meio de alertas do nosso monitoramento.
Quando os produtos evoluem, precisamos garantir que temos as ferramentas certas para a manutenção das tabelas impactadas em estágios posteriores.
Assim como acontece na engenharia de software, a documentação, os testes de unidade, os testes de integração e as verificações de monitoramento são proteções para garantir que o cálculo do conjunto de dados seja atualizado por qualquer pessoa, sem causar problemas ou alterar o objetivo principal definido pelo criador da tabela. Mesmo com detentores de dados para todos os nossos objetos de dados, esse sistema nos permite ter uma eficiência operacional, já que qualquer pessoa pode revezar na resolução de problemas dados, confiando na segurança fornecida pelas proteções.
Graças aos metadados usados para classificar tabelas em diferentes categorias (conjunto de dados centrais, conjunto de dados críticos, entradas de modelo etc.), temos expectativas variadas com relação à velocidade de solução de um problema e quem deveria validar as alterações.
Controle de Versão
As transformações de dados definidas por usuário e as bibliotecas compartilhadas são administradas em um repositório Git centralizado. Como usamos Git, nós também ganhamos capacidades de controle de versão, além de termos interfaces simples para a revisão por pares. Isso significa que temos um histórico de alterações rastreável em uma definição de conjunto de dados. Com esse histórico, podemos reverter as alterações, se necessário, entender como esses dados foram gerados ou até executar uma versão mais antiga das nossas transformações de dados. Essa capacidade de controle de dados provou ser uma das partes mais importantes do nosso sistema, para reverter facilmente quando algo dá errado e para fins de auditoria.
Conclusão
As empresas têm investido cada vez mais em plataformas de autosserviço para remover as restrições de uma equipe de dados única. Essas plataformas fomentam uma cultura de dados em toda a empresa; é um sistema que também traz vários desafios de governança na prática. Uma organização de pessoas com responsabilidades bem definidas é primordial para enfrentar tais desafios. As equipes de dados podem causar ainda mais impacto com ferramentas e práticas que lhes permitem colaborar com eficiência.
Criar uma plataforma modular com objetos estruturados, convenções de nomenclatura, práticas de biblioteca e de testes, aplicar revisão por pares, documentação; garantir que podemos monitorar, manter e reverter onde for essencial para escalar nossa equipe de dados e aproveitar as oportunidades.
Os dados têm um papel fundamental no crescimento do Nubank. É provável que não conseguíssemos chegar tão longe e tão rápido, sem esse sistema.
É claro que investir nessas ferramentas tem um custo: tempo investido no começo para projetar e implementar o sistema; mais tempo para os recém-chegados se adaptarem, e um aumento marginal no tempo gasto em alguns requisitos extras na contribuição (testes, documentação, revisão). Vimos que esse investimento foi logo compensado, pois nossas equipes aumentaram muito rápido (fomos de 0 para 800 contribuidores na plataforma de dados em 8 anos). Não conseguiríamos ter tantas contribuições individuais tão rápido sem prejudicar o sistema, e o monitoramento de qualidade seria muito mais complicado.
Dar poder para os usuários inovarem de forma autônoma e colaborativa é essencial para o sucesso das equipes de dados. Encontrar a quantidade certa de ferramentas e requisitos para conceder o máximo de flexibilidade aos usuários e ao mesmo tempo ter proteções de governança é fundamental para escalar as análises de forma eficiente e com segurança. Há muito o que aprender com as melhores práticas da engenharia de software.
Conheça nossas oportunidades