Compartilhar via


Como criar pipelines de dados simples, eficientes e de baixa latência

As empresas orientadas por dados de hoje produzem dados continuamente, o que requer pipelines de dados de engenharia que ingerem e transformam continuamente esses dados. Esses pipelines devem ser capazes de processar e entregar dados exatamente uma vez, produzir resultados com latências inferiores a 200 milissegundos e sempre tentar minimizar custos.

Este artigo descreve as abordagens de processamento de fluxo em lote e incremental para pipelines de dados de engenharia, por que o processamento de fluxo incremental é a melhor opção e as próximas etapas para começar a usar as ofertas de processamento de fluxo incremental do Databricks, Streaming no Azure Databricks e O que é DLT?. Esses recursos permitem que você escreva e execute rapidamente pipelines que garantem semântica de entrega, latência, custo e muito mais.

As armadilhas de trabalhos repetidos em lote

Ao configurar o seu pipeline de dados, pode, primeiramente, escrever trabalhos em lote repetidos para importar os seus dados. Por exemplo, a cada hora você pode executar um trabalho do Spark que lê a partir de sua fonte e grava dados em um coletor como o Delta Lake. O desafio com essa abordagem é processar incrementalmente sua fonte, porque o trabalho do Spark que é executado a cada hora precisa começar onde o último terminou. Você pode registrar o carimbo de data/hora mais recente dos dados processados e, em seguida, selecionar todas as linhas com carimbos de data/hora mais recentes do que esse carimbo de data/hora, mas há armadilhas:

Para executar um pipeline de dados contínuo, você pode tentar agendar um trabalho em lote por hora que leia incrementalmente a partir de sua origem, faça transformações e grave o resultado em um coletor, como o Delta Lake. Esta abordagem pode ter armadilhas:

  • Um trabalho do Spark que consulta todos os novos dados após um timestamp não capturará dados atrasados.
  • Um trabalho do Spark que falha pode levar à quebra de garantias exatas uma vez, se não for tratado com cuidado.
  • Um trabalho do Spark que lista o conteúdo de locais de armazenamento em nuvem para encontrar novos arquivos se tornará caro.

Em seguida, você ainda precisa transformar repetidamente esses dados. Você pode escrever trabalhos em lote repetidos que, em seguida, agregam seus dados ou aplicam outras operações, o que complica e reduz ainda mais a eficiência do pipeline.

Um exemplo de lote

Para compreender plenamente os desafios da ingestão e transformação em lote do seu pipeline, considere os exemplos a seguir.

Dados perdidos

Dado um tópico Kafka com dados de uso que determinam quanto cobrar aos seus clientes, e o pipeline está a ingerir em lotes, a sequência de eventos pode ter esta aparência:

  1. Seu primeiro lote tem dois registros às 8h e 8h30.
  2. Você atualiza a hora mais recente para às 8h30.
  3. Você obtém outro recorde às 8h15.
  4. Seu segundo lote consulta tudo depois das 8h30, então você perde o registro às 8h15.

Além disso, você não quer cobrar demais ou subestimar seus usuários, então você deve garantir que está ingerindo todos os registros exatamente uma vez.

Processamento redundante

Em seguida, suponha que seus dados contenham linhas de compras de usuários e você queira agregar as vendas por hora para saber os horários mais populares em sua loja. Se as compras para a mesma hora chegarem em lotes diferentes, você terá vários lotes que produzem saídas para a mesma hora:

Exemplo de ingestão em lote

A janela das 8h às 9h tem dois elementos (a saída do lote 1), um elemento (a saída do lote 2) ou três (a saída de nenhum dos lotes)? Os dados necessários para produzir uma determinada janela de tempo aparecem em vários lotes de transformação. Para resolver isso, você pode particionar seus dados por dia e reprocessar toda a partição quando precisar calcular um resultado. Em seguida, você pode substituir os resultados em sua pia:

Exemplo de ingestão em lote

No entanto, isso ocorre às custas da latência e do custo, porque o segundo lote precisa fazer o trabalho desnecessário de processamento de dados que pode já ter processado.

Sem armadilhas com o processamento incremental de fluxos

O processamento de fluxo incremental torna mais fácil evitar todas as armadilhas de trabalhos em lote repetidos para ingerir e transformar dados. O Databricks Structured Streaming e DLT gerencia as complexidades de implementação de streaming para permitir que se concentre apenas na sua lógica de negócios. Você só precisa especificar a qual fonte se conectar, quais transformações devem ser feitas nos dados e onde gravar o resultado.

Ingestão incremental

A ingestão incremental no Databricks é potenciada pelo Apache Spark Structured Streaming, que pode consumir de forma incremental uma fonte de dados e gravá-la num destino. O mecanismo de Streaming Estruturado pode consumir dados exatamente uma vez e o mecanismo pode lidar com dados fora de ordem. O mecanismo pode ser executado em notebooks ou usando tabelas de streaming em DLT.

O motor de streaming estruturado no Databricks fornece fontes de streaming proprietárias, como o AutoLoader, que podem processar ficheiros na nuvem de forma incremental e custo-efetiva. O Databricks também fornece conectores para outros barramentos de mensagens populares, como Apache Kafka, Amazon Kinesis, Apache Pulsare Google Pub/Sub.

Transformação incremental

A transformação incremental em Databricks com Structured Streaming permite especificar transformações para DataFrames com a mesma API de uma consulta em lote, mas rastreia dados entre lotes e valores agregados ao longo do tempo, para que não precises de o fazer. Ele nunca precisa reprocessar dados, por isso é mais rápido e econômico do que trabalhos em lote repetidos. O Streaming Estruturado produz um fluxo de dados que pode ser anexado ao seu coletor, como Delta Lake, Kafka ou qualquer outro conector suportado.

Visões Materializadas em DLT são alimentadas pelo motor Enzyme. Enzyme ainda processa incrementalmente a sua fonte, mas em vez de produzir um fluxo, ela cria uma vista materializada, que é uma tabela pré-computada que armazena os resultados de uma consulta que o utilizador lhe dá. O Enzyme é capaz de determinar eficientemente como os novos dados afetam os resultados da sua consulta e mantém a tabela pré-calculada up-toatualizada.

As Visualizações Materializadas criam uma visão sobre o seu agregado que está sempre se atualizando de forma eficiente para que, por exemplo, no cenário descrito acima, você saiba que a janela das 8h às 9h tem três elementos.

Streaming estruturado ou DLT?

A diferença significativa entre Structured Streaming e DLT é a maneira como você operacionaliza suas consultas de streaming. No streaming estruturado, especifica manualmente muitas configurações e precisa integrar as consultas manualmente. Você deve iniciar explicitamente as consultas, esperar que elas sejam encerradas, cancelá-las em caso de falha e outras ações. Com o DLT, você de forma declarativa dá à DLT seus pipelines para serem executados, e ela os mantém em execução.

A DLT também possui recursos como Visualizações Materializadas, que pré-computam de forma eficiente e incremental as transformações de seus dados.

Para obter mais informações sobre esses recursos, consulte Streaming no Azure Databricks e O que é DLT?.

Próximos passos