Ir para o conteúdo principal

Explorando o Delta Lake: imposição e evolução de esquema

Diving Into Delta Lake: Schema Enforcement & Evolution

Publicado: 24 de setembro de 2019

Soluções10 min de leitura

Experimente esta série de notebooks no Databricks

Os dados, assim como nossas experiências, estão sempre evoluindo e se acumulando. Para acompanhar, nossos modelos mentais do mundo devem se adaptar a novos dados, alguns dos quais contêm novas dimensões: novas maneiras de ver coisas que não tínhamos ideia antes. Esses modelos mentais não são diferentes do esquema de uma tabela, definindo como categorizamos e processamos novas informações.

Isso nos leva ao gerenciamento de esquema. À medida que os problemas e requisitos de negócios evoluem ao longo do tempo, o mesmo acontece com a estrutura de seus dados. Com o Delta Lake, à medida que os dados mudam, incorporar novas dimensões é fácil. Os usuários têm acesso a semânticas simples para controlar o esquema de suas tabelas. Essas ferramentas incluem imposição de esquema, que impede que os usuários poluam acidentalmente suas tabelas com erros ou dados inúteis, bem como a evolução de esquema, que permite adicionar automaticamente novas colunas de dados avançados quando essas colunas pertencem. Neste blog, vamos nos aprofundar no uso dessas ferramentas.

Entendendo os esquemas de tabela

Cada DataFrame no Apache Spark™ contém um esquema, um projeto que define o formato dos dados, como tipos de dados e colunas, e metadados. Com o Delta Lake, o esquema da tabela é salvo em formato JSON dentro do log de transações.

O que é imposição de esquema?

A imposição de esquema, também conhecida como validação de esquema, é uma proteção no Delta Lake que garante a qualidade dos dados, rejeitando gravações em uma tabela que não correspondem ao esquema da tabela. Como o gerente da recepção de um restaurante movimentado que aceita apenas reservas, ele verifica se cada coluna nos dados inseridos na tabela está em sua lista de colunas esperadas (em outras palavras, se cada uma tem uma "reserva") e rejeita quaisquer gravações com colunas que não estão na lista.

Como funciona a imposição de esquema?

O Delta Lake usa a validação de esquema na gravação, o que significa que todas as novas gravações em uma tabela são verificadas quanto à compatibilidade com o esquema da tabela de destino no momento da gravação. Se o esquema não for compatível, o Delta Lake cancela a transação por completo (nenhum dado é gravado) e gera uma exceção para informar o usuário sobre a incompatibilidade.

Para determinar se uma gravação em uma tabela é compatível, o Delta Lake usa as seguintes regras. O DataFrame a ser gravado:

  • Não pode conter nenhuma coluna adicional que não esteja presente no esquema da tabela de destino. Por outro lado, não há problema se os dados de entrada não contiverem todas as colunas da tabela: essas colunas simplesmente receberão valores nulos.
  • Não pode ter tipos de dados de coluna que difiram dos tipos de dados de coluna na tabela de destino. Se a coluna de uma tabela de destino contiver dados StringType, mas a coluna correspondente no DataFrame contiver dados IntegerType, a imposição de esquema gerará uma exceção e impedirá que a operação de gravação ocorra.
  • Não pode conter nomes de coluna que diferem apenas por maiúsculas e minúsculas. Isso significa que você não pode ter colunas como 'Foo' e 'foo' definidas na mesma tabela. Embora o Spark possa ser usado no modo que diferencia ou não maiúsculas de minúsculas (padrão), o Delta Lake preserva as maiúsculas e minúsculas, mas não diferencia ao armazenar o esquema. O Parquet diferencia maiúsculas de minúsculas ao armazenar e retornar informações de coluna. Para evitar possíveis erros, corrupção de dados ou problemas de perda (que nós mesmos vivenciamos no Databricks), decidimos adicionar essa restrição.

Para ilustrar, dê uma olhada no que acontece no código abaixo quando uma tentativa de anexar algumas colunas recém-calculadas a uma tabela Delta Lake que ainda não está configurada para aceitá-las.

Em vez de adicionar automaticamente as novas colunas, o Delta Lake impõe o esquema e impede que a gravação ocorra. Para ajudar a identificar qual(is) coluna(s) causou(aram) a incompatibilidade, o Spark imprime os dois esquemas no rastreamento de pilha para comparação.

Como a imposição de esquema é útil?

Como é uma verificação tão rigorosa, a imposição de esquema é uma excelente ferramenta para usar como um guardião de um conjunto de dados limpo e totalmente transformado, pronto para produção ou consumo. Normalmente, é imposta em tabelas que alimentam diretamente:

  • Algoritmos de machine learning
  • Painéis de BI
  • Ferramentas de análise e visualização de dados
  • Qualquer sistema de produção que exija esquemas semânticos altamente estruturados, fortemente tipados

Para preparar seus dados para este obstáculo final, muitos usuários empregam uma arquitetura simples de "vários saltos" que adiciona progressivamente estrutura às suas tabelas. Para saber mais, dê uma olhada na postagem intitulada Produção de Machine Learning com Delta Lake.

É claro, a imposição de esquema pode ser usada em qualquer lugar em seu pipeline, mas esteja ciente de que pode ser um pouco frustrante ter sua gravação de streaming em uma tabela falhar porque você se esqueceu de que adicionou uma única coluna aos dados de entrada, por exemplo.

Prevenindo a diluição de dados

Neste ponto, você pode estar se perguntando, qual é toda essa confusão? Afinal, às vezes, um erro inesperado de "incompatibilidade de esquema" pode atrapalhar seu fluxo de trabalho, especialmente se você for novo no Delta Lake. Por que não deixar o esquema mudar como for necessário para que eu possa gravar meu DataFrame, não importa o quê?

Como diz o velho ditado, "é melhor prevenir do que remediar". Em algum momento, se você não impor seu esquema, problemas com a compatibilidade do tipo de dados aparecerão: fontes aparentemente homogêneas de dados brutos podem conter casos extremos, colunas corrompidas, mapeamentos malformados ou outras coisas assustadoras que aparecem na noite. Uma abordagem muito melhor é impedir esses inimigos nos portões - usando a imposição de esquema - e lidar com eles à luz do dia, em vez de mais tarde, quando eles estarão à espreita nos recessos sombrios de seu código de produção.

A imposição de esquema oferece a tranquilidade de que o esquema de sua tabela não mudará, a menos que você tome a decisão afirmativa de alterá-lo. Ele evita a "diluição" de dados, que pode ocorrer quando novas colunas são anexadas com tanta frequência que tabelas antes ricas e concisas perdem seu significado e utilidade devido ao dilúvio de dados. Ao incentivá-lo a ser intencional, definir altos padrões e esperar alta qualidade, a imposição de esquema está fazendo exatamente o que foi projetada para fazer: mantê-lo honesto e suas tabelas limpas.

Se, após uma análise mais aprofundada, você decidir que realmente queria adicionar essa nova coluna, é uma correção fácil de uma linha, conforme discutido abaixo. A solução é a evolução do esquema!

UM LÍDER 5X

Gartner®: Databricks, líder em banco de dados em nuvem

O que é evolução de esquema?

A evolução de esquema é um recurso que permite aos usuários alterar facilmente o esquema atual de uma tabela para acomodar dados que estão mudando ao longo do tempo. Mais comumente, é usado ao executar uma operação de anexação ou substituição, para adaptar automaticamente o esquema para incluir uma ou mais novas colunas.

Como funciona a evolução de esquema?

Seguindo o exemplo da seção anterior, os desenvolvedores podem usar facilmente a evolução de esquema para adicionar as novas colunas que foram rejeitadas anteriormente devido a uma incompatibilidade de esquema. A evolução de esquema é ativada adicionando .option('mergeSchema', 'true') ao seu comando .write ou .writeStream Spark.

Para visualizar o gráfico, execute a seguinte instrução Spark SQL.

Como alternativa, você pode definir esta opção para toda a sessão do Spark adicionando spark.databricks.delta.schema.autoMerge = True à sua configuração do Spark. Use com cautela, pois a imposição de esquema não o avisará mais sobre incompatibilidades de esquema não intencionais.

Ao incluir a opção mergeSchema em sua consulta, todas as colunas que estão presentes no DataFrame, mas não na tabela de destino, são adicionadas automaticamente ao final do esquema como parte de uma transação de gravação. Campos aninhados também podem ser adicionados, e esses campos serão adicionados ao final de suas respectivas colunas de struct também.

Engenheiros e cientistas de dados podem usar esta opção para adicionar novas colunas (talvez uma métrica recém-rastreada ou uma coluna dos números de vendas deste mês) às suas tabelas de produção de machine learning existentes sem quebrar os modelos existentes que dependem das colunas antigas.

Os seguintes tipos de alterações de esquema são elegíveis para evolução de esquema durante anexos ou substituições de tabela:

  • Adicionar novas colunas (este é o cenário mais comum)
  • Alterar os tipos de dados de NullType -> qualquer outro tipo ou upcasts de ByteType -> ShortType -> IntegerType

Outras alterações, que não são elegíveis para evolução de esquema, exigem que o esquema e os dados sejam substituídos adicionando .option("overwriteSchema", "true"). Por exemplo, no caso em que a coluna "Foo" era originalmente um tipo de dados integer e o novo esquema seria um tipo de dados string, todos os arquivos Parquet (dados) precisariam ser reescritos. Essas alterações incluem:

  • Soltar uma coluna
  • Alterar o tipo de dados de uma coluna existente (no local)
  • Renomear nomes de coluna que diferem apenas por maiúsculas e minúsculas (por exemplo, "Foo" e "foo")

Finalmente, com o próximo lançamento do Spark 3.0, o DDL explícito (usando ALTER TABLE) será totalmente suportado, permitindo que os usuários executem as seguintes ações nos esquemas de tabela:

  • Adicionar colunas
  • Alterar comentários de coluna
  • Definir propriedades de tabela que definem o comportamento da tabela, como definir a duração da retenção do log de transações

Como a evolução de esquema é útil?

A evolução de esquema pode ser usada sempre que você pretender alterar o esquema de sua tabela (ao contrário de onde você adicionou acidentalmente colunas ao seu DataFrame que não deveriam estar lá). É a maneira mais fácil de migrar seu esquema porque adiciona automaticamente os nomes de coluna e tipos de dados corretos, sem ter que declará-los explicitamente.

Resumo

A imposição de esquema rejeita quaisquer novas colunas ou outras alterações de esquema que não sejam compatíveis com sua tabela. Ao definir e manter esses altos padrões, analistas e engenheiros podem confiar que seus dados têm os mais altos níveis de integridade e raciocinar sobre eles com clareza, permitindo que tomem melhores decisões de negócios.

Por outro lado, a evolução de esquema complementa a imposição, facilitando a ocorrência automática de alterações de esquema pretendidas. Afinal, não deve ser difícil adicionar uma coluna.

A imposição de esquema é o yin para o yang da evolução de esquema. Quando usados juntos, esses recursos tornam mais fácil do que nunca bloquear o ruído e sintonizar o sinal.

Gostaríamos também de agradecer a Mukul Murthy e Pranav Anand por suas contribuições para este blog.

Interessado no Delta Lake de código aberto?
Visite o hub online do Delta Lake para saber mais, baixar o código mais recente e participar da comunidade Delta Lake.

Relacionado

Artigos desta série:
Mergulhando no Delta Lake #1: Descompactando o Log de Transações
Mergulhando no Delta Lake #2: Imposição e Evolução de Esquema
Mergulhando no Delta Lake #3: Internos de DML (Atualização, Exclusão, Mesclagem)

Produção de Machine Learning com Delta Lake
O que é um Data Lake?

(Esta publicação no blog foi traduzida utilizando ferramentas baseadas em inteligência artificial) Publicação original

Nunca perca uma postagem da Databricks

Inscreva-se nas categorias de seu interesse e receba as últimas postagens na sua caixa de entrada