Fala dataholics, hoje compartilho com vocês um script de manutenção que já uso há um tempo e tem entregue valor para os ambientes de Lakehouse, trabalhei muitas horas nesse script de manutenção e achei que já é valido compartilhar, espero que ajude.
O que veremos nesse post:
Introdução a rotina de manutenção
Resultados do script - Monitoramento
Como funciona o script
Como executar manualmente ou via Job
Parametrizações do script
Parâmetro vacuumThreshold - Economizando tempo de Vacuum
Objetos criados no ambiente
Considerações finais e recomendações
Com esse script você vai ter a possibilidade de:
Acompanhar o crescimento das suas tabelas
Criar um baseline de consumo do seu storage
Criar um monitoramento de espaço consumido no Storage VS tamanho real da tabela
Executar limpeza de versões em tabelas Delta
Reduzir custos com armazenamento
Sou um curioso pela engine do Delta, inclusive ja fiz uma palestra de Delta lake internals que ficou bem legal, espero gravar ela no YouTube, um dos tópicos que sempre menciono por aqui é o famoso TIME TRAVEL e VACUUM.
Não entrarei em detalhes da engine nesse post, se ainda não leu meu último artigo sobre Backup de Data Lake, da uma olhada, lá dou mais detalhes de como isso funciona.
Em resumo o TIME TRAVEL é a capacidade de olhar para o passado, olhar alterações que já aconteceram na tabela, isso só é possível, pois, a Delta Table trabalha com versionamento, cada operação na tabela Delta é gerada uma nova versão e novos arquivos de dados são adicionados ou marcados como Removidos, mas, eles só são removidos do Storage quando uma operação VACUUM é executada.
Por padrão os arquivos marcados como removidos da tabela não são excluídos automaticamente, exceto se você utiliza Delta Live Tables e configurou o cluster de manutenção, caso contrario uma operação de Vacuum nunca é executada e você ira acumular versões infinitamente.
Para efeitos de curiosidade, os arquivos marcados como removidos, são arquivos de dados .PARQUET, não estamos falando dos arquivos de Logs que ficam na pasta _DELTA_LOG, os arquivos na pasta de Log são mantidos por 30 dias e excluídos automaticamente a cada checkpoint que ocorre na tabela.
Sabendo disso, você como engenheiro de dados ou administrador do Databricks precisa pensar em uma rotina de manutenção para limpeza dessas versões antigas, se não isso vira uma bola de neve e aumenta o custo $ do seu Storage.
Já peguei um cenário de uma tabela que tinha na sua versão atual 25 GB, você pode conferir pelo decribe detail, contudo, na pasta no Storage tinha 1.5 TB, isso mesmo 1500 GB de dados, ou seja, 1475 GB eram dados que não faziam parte da tabela e na teoria poderiam ser excluídos.
Na descrição do script deixei alguns casos reais onde liberamos mais de 250 TB de storage, imagine o custo disso, é uma entrega de valor grande para o seu ambiente e bolso $.
Resultados do script - Monitoramento
Esse é o resultado que esperamos, ter um monitoramento de como está o armazenamento das nossas tabelas.
Nesse gráfico vemos a linha em Azul que é o armazenamento no Storage e a linha vermelha a quantidade de dados real, note que na primeira execução eu tinha 350 GB de storage, mas apenas 10 GB de dados na versão atual das tabelas, na próxima execução ele já cai para 50 GB de storage.
Note que fiquei 1 dia sem rodar (dia 12/04) e deu um pico no Storage de 120 GB.
Esse gráfico é do meu ambiente de teste e deixei o Job rodando por alguns dias com alguns processos estressando as tabelas Delta, pois, não posso compartilhar dados dos clientes que já utilizam.
Rodei diário apenas para simular um ambiente, o ideal é rodar semanal ou mensal.
Esse são os dados sumarizados, temos algumas informações legais, como:
Quantidade de Databases analisados naquela execução
Quantidade de tabelas analisadas
Quantidade de tabelas que passaram pelo Vacuum naquela execução (Ou seja atingiu o threshold do parametro vacuumThreshold)
Tamanho total do storage (somanto todas as versões da tabela, famoso time travel)
Tamanho total das tabelas (versão atual)
Hora de início e fim da análise
Hora de início e fim do Vacuum
E demais parâmetros de execução
Temos também o resultado detalhado no nível de tabela e database, que pode nos gerar relatórios mais customizados.
O resultado fica gravado nessas duas tabelas: tbVacuumSummary e tablesSizeMonitor.
As demais tabelas podem ser apenas transiente (ser sobrescritas nas execuções), contudo, você pode configurar para manter o histórico delas e ter mais detalhes, exemplo, manter histórico da operação describe detail, para isso basta habilitar o parametro enableHistory.
Reginaldo, como funciona esse trem?
No script explico o funcionamento e claro, é código aberto você pode analisar, mas vale um resumo:
Na primeira versão criei apenas um monitoramento do Describe Detail salvando em uma tabela delta, já é um monitoramento interessante, contudo, quando eu somava todo o tamanho das tabelas dava um valor muito pequeno, perto do tamanho do Storage, então comecei a pensar em como eu poderia relacionar o quanto uma operação de Vacuum poderia ajudar.
Mas, não foi nada trivial, gastei muitas horas desvendando o código do Vacuum em Scala e não consegui replicá-lo de forma simples. O código do Vaccum em Scala te da informação do tanto que será excluído, mas não consegui recuperar essa informação.
Então, basicamente criei um código que faz uma varredura recursiva para mapear todas as pastas na tabela e calcular o tamanho do seu storage, depois cruzo com o tamanho atual dela.
Bom, é claro que isso não ficou tão performático, pois, preciso executar muitas operações de DBUTILS.FS.LS, isso é demorado e custoso.
Apesar de ser demorado, ainda valeu muito apena, o Job demora algumas horas para rodar, porém, o resultado gerado é ótimo, então rodamos pelo menos 1x por semana nos ambientes com Delta.
Meu objetivo é futuramente refatorar utilizando apenas o Delta Log, melhorando a performance e custo.
Como executo esse trem?
Para utilizar no seu ambiente, basta baixar o script e importar no ambiente Databricks, parametrize as variáveis e pronto, você pode rodar ele manualmente.
A ideia principal dele é ser executado via Job, então você pode passar todas as parametrizações via Databricks Job.
Para rodar manualmente, basta executar o comando 2, ele irá instanciar os Widgets e aí você pode parametrizar visualmente:
Os parâmetros mais importantes para você preencher:
databaseTarget: Qual database será analisado, pode informar '*' para pegar todos, ou 'bronze*' para pegar todos que iniciam com a palavra bronze.
tablesTarget: A mesma ideia do database target, você pode filtrar tabelas, por padrão é '*'
storageLocation: Informar o local onde as tabelas de controle serão armazenadas
Os demais parâmetros já assumem um valor padrão, contudo, você pode customizar para o seu ambiente.
Para rodar via Job: Crie um Job no seu ambiente, nesse Job crie uma Task chamando o notebook importado, por padrão o nome é TablesSizeVacuum.
Crie parâmetros na Task e preencha o nome do parâmetro com o mesmo nome do Widget e o valor conforme o seu ambiente.
Rodando via Job você terá histórico de duração no Workflow.
Agende seu job 1x por semana ou 1x por mês e monitore.
Demais parâmetros:
Todos os parâmetros estão documentados no script, mas destaco aqui o preenchimento de alguns:
runVacuum: Rode a primeira vez como FALSE, entenda como está seu ambiente.
vacuumHours: O recomendado é 168 horas, entenda o melhor valor para o seu ambiente, esse é o tempo que será mantido para TIME TRAVEL na sua tabela.
vacuumThreshold: Esse parâmetro define se a tabela irá executar Vacuum, aqui vale uma explicação exclusiva para ele.
enableLogs: Se esse parâmetro for True, será marcado a hora de início e fim de cada tabela, isso é legal para saber qual tabela demora mais, porém, isso aumenta relativamente o custo e tempo total de execução.
enableHistory: Se esse parâmetro for TRUE, as tabelas tableCatalog, tableDetails e tableStorageFiles não são sobrescritas e mantém log de todas as execuções, caso contrário, elas serão sempre excluídas, mas os logs sumarizados não, eles ficam nas tabelas: tbVacuumSummary e tablesSizeMonitor.
Parâmetro vacuumThreshold
Esse parâmetro defini quando uma tabela será executada Vacuum, valor padrão é 5, isso quer dizer que o Vacuum só irá rodar em tabelas onde o Storage é 5 vezes maior do que a versão atual.
Você pode customizar, talvez 5x para tabelas muito grade não faça sentido e você pode diminuir para 2 ou 3x.
Utilizei dessa maneira por ficar menos complexo do que utilizar percentual.
Esse parâmetro é bastante importante, ele evita que uma tabela passe pela operação de Vacuum sem necessidade, gastando tempo de processamento à toa.
Objetos criados no ambiente:
1x Database nomeado através da variáve databaseCatalog, por padrão o nome será db_controle
1x Tabela de catálogo, irá armazenar a listagem, por padrão o nome será tbCatalog, se o parâmetro enableHistory estiver desabilitado ela será sobrescrita em cada execução
1x Tabela para armazenar o resultado do describe detail, por padrão será chamada de bdaTablesDetails, se o parâmetro enableHistory estiver desabilitado ela será sobrescrita em cada execução
1x Tabela para armazenar o resultado do List files, por padrão será chamada de tableStorageFiles, se o parâmetro enableHistory estiver desabilitado ela será sobrescrita em cada execução
1x Tabela para armazenar o resultado agregado da execução com detalhes no nível de tabela, por padrão será chamada de tablesSizeMonitor, essa tabela nunca é truncada
1x Tabela para armazenar o resultado agregado da execução, por padrão será chamada de tbVacuumSummary, essa tabela nunca é truncada
As tabelas tablesSizeMonitor e tbVacuumSummary, não são sobrescritas automaticamente, elas são sumarizadas e com todo o histórico para criarmos um baseline do nosso ambiente.
Caso elas estejam ficando muito grande execute um expurgo manualmente.
Utilize as tabelas tablesSizeMonitor e tbVacuumSummary para criar seu monitoramento e dashboards de acompanhamento.
Considerações finais e recomendações
Espero que esse script te ajude, se você liberar alguns TB no ambiente, me chame para um café rsrs, brincadeiras a parte, esse script pode ser muito útil se monitorado de perto e bem parametrizado.
Ressalto mais uma vez, rode a primeira vez sem o Vacuum habilitado apenas para analisar o seu ambiente, ele pode demorar muito se seu ambiente tiver muitas tabelas com particionamentos muito granulares, ou com muitas pastas.
Utilize um cluster com Driver mais potente que o Worker, ajuste a quantidade de paralelismo se estiver tomando erros.
Comece com um cluster pequeno e monitore, cluster inicial: Driver: Standard_DS4_v2 · 2 x Workers: Standard_DS3_v2 · Runtime >11.3.
Leia a documentação do Script no primeiro comando.
Antes de mais nada, segue o link do script:
Fique bem e até a próxima.
Referências:
Comments