top of page
Foto do escritorReginaldo Silva

Databricks - Delta lake - Vacuum Inventory Table - Reduzindo até 50% de custos

Fala dataholics, bora de mais conteúdo técnico, no post de hoje falaremos de uma nova feature que ajudará com redução de custos no seu ambiente Databricks, ela nasceu recentemente, falaremos da Vacuum Inventory Table.


Veremos nesse post:

  • O que é Vacuum

  • Como funciona o Vacuum

  • Inventory Table

  • Cloud Inventory - Azure Blob Inventory

  • Vacuum Inventory table

  • Cases e onde aplicar o Inventory

  • Quanto custo o Azure Blob Inventory

  • Resumo

 

O que é Vacuum


Já falamos bastante sobre Vacuum nesse blog, mas, caso você esta chegando agora, deixo uma recomendação de leitura, entre outros posts do Blog onde explico o funcionamento da Engine.


Vamos fazer um recap bem rápido:

Toda operação que executamos em uma tabela Delta uma nova versão é gerada em conjunto com novos arquivos, pois, por padrão, o Delta Lake não altera arquivos Parquets existentes.


Independente da operação (INSERT, DELETE ou UPDATE) novos arquivos serão gerados com uma nova versão da tabela, mesmo para casos de DELETE (estou desconsiderando o Deletion Vector aqui).


Exemplo, se um DELETE de um registro é aplicado em uma tabela Delta, supondo que esse registro esta em um Parquet com outros registros que não foram deletados, o que acontecerá é que a engine Delta cria uma nova versão da tabela criando um novo arquivo Parquert sem o registro deletado, o arquivo antigo se mantém no storage para Time Travel, a engine marca esse arquivo no Delta Log como "removed".


Logo, toda operação que fazemos pode gerar novos arquivos e marcar arquivos existentes como "removed", esses arquivos continuam existindo no Storage para que você possa voltar no tempo com time travel ou uma operação de Restore.


Na prática, isso é maravilhoso, mas temos um problema, se não fazermos uma limpeza (Vacuum) estaremos acumulando histórico eternamente e isso pode custar caro em termos de armazenamento de storage, então o recomendado é que você execute uma rotina de Vacuum com frequência nas suas tabelas Delta, defina bem sua política de retenção, leia o primeiro artigo da referência.


 

Vacuum - Como funciona


Bom então sabemos que é necessário rodar uma rotina de Vacuum com frequência, se você ainda não tem uma rotina configurada, de uma olhada na DTSTOOLS ou no meu post sobre redução de custo com rotina de manutenção, caso contrario seu ambiente já deve possuir uma rotina rodando e é dela que falaremos, como podemos otimizá-la.


A operação de Vacuum funciona em 3 fases:

  1. Listagem de todos os arquivos no Storage

  2. Cruzamento dos aquivos dessa listagem com o Delta Log

    1. Aqui ela pegará todos os arquivos marcados como REMOVED, verificar se o tempo de retenção atende o requisito e criar uma lista de arquivos para deletar.

  3. Deleta os arquivos no Storage


Dessas 3 fases a primeira tende ser a mais custosa delas, em todos os sentidos, em tempo de execução e custo $ para o seu Storage, ela dispara uma sequência de operações de LIST recursiva para o seu storage, dependendo do tamanho da sua tabela e quantidade e níveis de pasta, isso pode ser bem custoso mesmo, podendo levar horas.


Essa operação costuma ser muito mais custosa para tabelas com particionamento de dados, ou seja, com muitos níveis de pastas, em tabelas com Liquid Cluster ou sem particionamento essa operação de list será bem mais rápida, pois, não precisa de recursividade.


Tabelas com particionamento na casa de TB (terabytes) pra cima podem precisar de milhões de operações de List somente para executar o Vacuum, aqui vale lembrar que operações de LIST são cobradas em todos os Storages (AWS, GCP e Azure).


No Azure temos esse preço:


Ou seja, se precisarmos fazer 1 milhão de operações de list para executar uma única operação de Vacuum, estamos falando de algo em torno de R$23,00 reais para uma listagem em um Storage Premium, parece barato né? Isso multiplicado pela quantidade de tabelas e vezes que você executa uma operação de Vacuum no seu ambiente pode sair um pouco salgado.


Mas o custo não fica só no Storage, uma operação de List em si é barata como vimos na tabela acima, mas, as horas de um cluster ligado somente para fazer operação de List, ai a brincadeira pode começar a ficar cara.


Ou seja, o custo total não fica na operação do Storage e sim no tempo total de duração, como estamos falando de centenas de milhões de operações de list, isso pode levar um tempo considerável.


Pensando neste problema, falaremos da solução Inventory Table + Cloud Inventory,

 

O Delta Lake lançou uma feature para o comando Vacuum chamada de Inventory Table, ela consiste em uma tabela com um inventário de arquivos do nosso Storage.


Basicamente você informa na operação de Vacuum quem é a Inventory Table e ao invés de execução a fase 1 de LIST ele busca as informações nessa tabela, acelerando muito o processo, ou seja, ele vai direto para a fase 2.


Se voce estiver usando Databricks, esta disponivel no DBR 15.2.


Bom, mas da de onde veio essa tabela e os dados que estão dentro dela?

 

Cloud Inventory - Azure Blob Inventory


Em ambas as principais Clouds temos um recurso chamado Inventory, esse recurso executa uma operação de List recursiva e armazena esse resultado em algum lugar configurado.


Hoje falaremos especificamente do Azure Storage Blob Inventory.


Não há nenhum segredo aqui, ela é uma feature bem simples, executando uma operação massiva de List no seu Storage e armazena esse resultado em algum lugar, vamos falar de algumas configurações para atender ao nosso caso.


Primeiro ponto, essa feature é para:

  • Standard general-purpose v2

  • Premium block blob storage

  • Blob storage


Aqui um detalhe muito relevante, se seu storage possui Hierarchical Namspace habilitado, essa operação de inventário pode demorar mais do que o normal, o tempo máximo para executar essa operação é de 6 dias, se o seu storage for muito denso, ele pode atingir esse limite e abortar.

Se você estiver nessa situação, a minha dica é segregar em mais de uma Rule, ou seja, criar Rules para pastas especificas.


O resultado dessa operação pode ser salva em CSV ou Parquet, claro que iremos de Parquet para o nosso caso.


Vejamos como habilitar o Inventory no seu Storage:


Ao acessar o seu Storage Account, na aba lateral navegue até essa opção: Blob Inventory.


Similar a rotina de Life Cycle precisamos definir Rules para configurar, são Rules bem simples que podem ser feitas pela UI ou via JSON.


Basicamente nessa Rule definiremos a frequência (Diária ou semanal, não temos outra operação), o nome do container que iremos salvar as informações, os tipos de blobs que desejamos que estejam no inventário, o formato que salvaremos, os campos que desejamos colocar no nosso Parquet e o diretório que desejamos listar, podemos filtrar pastas especificas ou listar o container todo.


Aqui estou definindo que o resultado desse inventario será armazenado no container chamado "inventory", no próprio storage account.


A lista de campo que desejamos salvar, se desejar você pode escolher todas e usar para outras análises futuras, aqui estou selecionando apenas as que considero relevante para o nosso processo.

  • Name

  • Creation time

  • Last modified

  • Last access time

  • ETag

  • Content lenght

  • Contente type

  • Blob type

  • Acess tier

  • HDI folder status - Caso seu storage tenha Hierarchical Namespace


Aqui podemos definir a frequência para Daily o tipo Parquet, e podemos usar filtros para pastas especificas ou excluir pastas que não queremos, isso é bem útil para economizar tempo e espaço, na minha deixei vazio, pois, meu storage é pequeno.


Pronto, rotina criada, agora é esperar a primeira execução, e não, não tem como forçar uma execução ou mesmo definir o horário, pelo menos não achei nada, caso alguém saiba comenta aí.


Ou seja, precisamos esperar o dia seguinte, ela rodará 24 horas após a configuração, ou seja, você não escolhe nem o horário de execução, se seu storage for grande espere por um bom tempo antes de abrir um chamado na MS ou revise os seus filtros.

Aqui está o resultado, ela cria uma estrutura de pastas particionadas, com isso você pode manter histórico das suas execuções.

Aqui podemos consultar nosso resultado usando a engine de Parquet.


Então estamos prontos? Quase lá.


 

Vacuum Inventory


Para a operação de Vacuum funcionar precisamos especificar uma Delta Table o Spark SQL Query com o mesmo schema esperado, caso contrario não funcionará, o Schema precisa ser exatamente igual, contudo, o schema exportado pelo Inventory não é o igual e não temos as mesmas colunas, com isso, precisamos tratar os dados antes de passar para nossa rotina de vacuum.


Schema esperado:


Para isso disponibilizo um script que vocês possam automatizar a rotina, ficou extremamente simples e útil, estarei integrando ele na DTSTOOLS e nos scripts da rotina de manutenção que estão no Github.


O script está bem simples e documentado, basta preencher essas variáveis:

  • storageName: Nome do storage account onde está o seu Data Lake

  • dataBucket: nome do Bucket que está os dados para análise, esse é nome do bucket que você aplicou o inventory

  • inventoryBucket: Nome do bucket onde os dados do inventário foram salvos, você pode ter salvo no mesmo bucket de dados.

  • inventoryCatalogName: Nome do catálogo onde a tabela será criada

  • inventoryDatabaseName: Nome da database onde a tabela será criada

  • inventoryTableName: Nome da tabela de inventário que será criada


No próximo bloco, estamos preenchendo as variáveis de controle, aqui estou fazendo uma checagem para validar se pasta do inventário foi criada para o dia corrente, caso o contrário usaremos a pasta do dia anterior, isso foi necessário, pois, não temos como definir o horário que o inventário rodará, logo pode ter ambiente que o inventário rode durante o dia e a pasta ainda não tenha sido criada.

Obs: Estou levando como premissa que você configurou o seu inventário como Diário.

Criando a tabela com o schema definido para atender os requisitos.


Limpando a tabela para manter somente os dados recentes, aqui você pode customizar conforme desejar, essa maneira ficou mais simples, pois, só os dados da última execução do inventário.


Por fim, inserindo os dados de inventário na nossa tabela Delta, note que aqui faço alguns tratamentos, exemplo para descobrir se é uma pasta ou não (isDir) estou usando como referência o tamanho, caso seja 0 bytes, identifico como pasta.


Agora temos a tabela no formato esperado pela rotina:


Podemos consultar tamanho de pastas especificas buscando em nossa tabela:


Podemos usar essa feature para criar um monitoramento do tamanho das nossas tabelas, entre outras utilidades e automação como essa do Vacuum.


Agora sim, podemos rodar o Vacuum usando a seguinte sintaxe:

Nessa execução, basicamente pulamos a etapa de LIST usando a busca dentro da Inventory Table, acelerando a performance da execução do Vacuum, abaixo uma comparação simples:


Essa é uma tabela pequena com pouco mais de 2000 mil pastas, tivemos um ganho por volta de 30%.


Agora vamos para um case Real e aqui teremos um bom saving:


Nesse caso tivemos uma redução de quase 4 horas, olhando em algumas tabelas, chegamos a ganhos de 50% de performance melhorada.

 

Então resumindo, com a aplicação do Vacuum inventory você pode reduzir até 50% do custo das suas operações de Vacuum, embora isso vai variar e depende da densidade da estrutura de pastas, pode haver casos onde não há ganho, exemplo tabelas pequenas e não particionadas.

 

Por isso recomendo a aplicação do Vacuum inventory para tabelas particionadas e relativamente grandes, e aqui acaba sendo subjetivo o que é relativamente grande, pois, não é necessariamente o tamanho, às vezes é a quantidade de pastas no storage.


 

Quanto custa o Azure Blob Inventory


Falamos que a operação de LIST é custosa, logo habilitamos o Blob Inventory para nos ajudar, mas, claro que ele não é de graça, embora, o seu preço é extremamente acessível.

Se pegarmos o primeiro caso de LIST onde simulei 1 milhão de LIST com valor de R$ 23,00 reais, aqui temos o mesmo milhão de LIST por R$ 0.02 reais, ou seja, compensa muito utilizar o Blob Inventory.


Ressalto a importância do planejamento, não é só sair habilitando, aplique onde é necessário, faça filtros, escolhas as colunas que você ira usar, aplique rotina de limpeza desses dados.

Cuidado com storages grandes que tenham Hierarchical Namespace habilitado.


 

Resumo


No post de hoje fizemos um recap sobre Vacuum, um tema realmente importante para manter seus custos do Storage controlado, como o Vacuum funciona e como podemos melhorar sua execução.


A junção do Azure Blob Inventory + Vacuum Inventory pode te ajudar a reduzir até 50% do tempo de execução das suas operações de Vacuum.


Caso tenha alguma dúvida, algum ponto sobre o script, fique a vontade para me contatar.

Fique bem e até a próxima.


Link Github para o script:


Referências:

https://delta.io/blog/efficient-delta-vacuum/ (Efficient Delta Vacuum with File Inventory)





389 visualizações0 comentário

Comments


Post: Blog2 Post
bottom of page