Fundamentos
O que escala, object storage, formato físico, cardinalidade e layout.
Formato físico, organização em disco e propriedades distribuídas do armazenamento, com a construção de um lakehouse local em MinIO e DuckDB sobre os dados da Olist.
Computação 2 · Prof. Afonso Brandão · 01/09/2026
Continuidade · das Aulas 2-9 para a Aula 10
A modelagem define o que é gravado, e a governança define quem responde por ele. Esta aula trata de onde, como e em quantas cópias o dado fica guardado.
Roteiro · 120 minutos · uma hora de exposição, uma hora de prática
A segunda hora é atividade em grupo: ingerir os dados da Olist em MinIO e DuckDB, modelar dimensionalmente e responder a três perguntas de negócio.
O que escala, object storage, formato físico, cardinalidade e layout.
Partição, réplica, quórum, consistência e o efeito no pipeline.
Vocabulário, camadas por contrato, ciclo de vida e custo.
MinIO e DuckDB, modelo dimensional e três respostas com SQL executado.
Bloco 1 · O que escala
O dimensionamento por volume isolado desconsidera as variáveis que determinam o comportamento do sistema sob carga.
Quanto entra por unidade de tempo e em que tamanho de lote.
MB/s · eventos/sQuantos consumidores simultâneos disputam o mesmo conjunto.
consultas simultâneasO tempo de resposta aceitável para cada classe de consumo.
segundos · minutosPoucos arquivos grandes ou muitos pequenos mudam o gargalo.
MB por arquivoPor quanto tempo se guarda e em quanto tempo se restaura.
meses · RTOBytes varridos por pergunta respondida, somados ao custo de guarda.
bytes varridosBloco 1 · Object storage
Buckets e objetos oferecem escala e durabilidade, mas exigem convenções de nome, controle de acesso, versionamento e catálogo externo.
O objeto é gravado integralmente e identificado por uma chave. A hierarquia de diretórios é aparente: o segmento que se assemelha a pasta constitui prefixo da chave, e a renomeação equivale a uma reescrita.
A convenção de prefixo constitui, portanto, a única estrutura disponível, e deve ser definida antes da gravação do primeiro arquivo.
Padronize a convenção de prefixo antes do primeiro arquivo.
Ative versionamento e defina explicitamente quem pode apagar.
Mantenha catálogo externo: o bucket não descreve o dado.
Separe zonas de ingestão, processamento e consumo por prefixo.
Registre a política de exclusão junto com a de retenção.
Bloco 1 · Formato físico
Cada formato otimiza um padrão de acesso e onera o padrão oposto.
Bloco 1 · Por dentro do arquivo colunar
O arquivo guarda, por bloco e por coluna, mínimo, máximo e contagem de nulos. Esse metadado permite descartar a leitura sem abrir o dado.
A projeção descarta as colunas não requisitadas, e o predicado descarta os blocos cujo intervalo não satisfaz o filtro. As duas se somam, e a segunda depende de o dado estar ordenado de forma coerente com o filtro.
Essa métrica revela a qualidade do layout. O tempo de resposta varia com o cache, e os bytes lidos refletem a estrutura física do dado. Meça antes e depois de cada alteração estrutural.
Bloco 1 · Pruning em uma consulta
Fato particionado por ano e mês em vinte e cinco diretórios, com dez colunas gravadas no arquivo e as linhas ordenadas por data_pedido dentro de cada partição. Cada nível reduz o conjunto antes do seguinte.
| Nível de descarte | O que o motor consulta | Efeito nesta consulta |
|---|---|---|
| Diretório · partição | Os prefixos ano= e mes= das chaves | Apenas os arquivos sob ano=2017/mes=11 são abertos; os demais são descartados pelo caminho, sem leitura de conteúdo. |
| Bloco · row group | O rodapé, com mínimo e máximo de data_pedido por bloco | O bloco cujo intervalo declarado está inteiramente após 15 de novembro é descartado sem que o dado seja lido. |
| Coluna · projeção | O schema declarado no rodapé | Duas das dez colunas gravadas são lidas, data_pedido e valor_total; ano e mes vêm do caminho e não são lidas do arquivo. |
Bloco 1 · Por dentro do arquivo orientado a registro
O cabeçalho declara o schema em JSON, e cada bloco seguinte guarda registros inteiros em binário. A leitura devolve o registro completo, sem descarte de coluna.
O consumidor resolve o schema de escrita contra o próprio schema de leitura. O valor padrão do campo acrescentado permite ao consumidor novo ler registros antigos, o consumidor antigo ignora o campo que desconhece, e o alias permite renomear a coluna sem quebrar o contrato. A compatibilidade é verificável antes da publicação.
O marcador de sincronização divide o arquivo, e o consumidor lê a partir de qualquer ponto, o que preserva o paralelismo. O acréscimo de registros é barato, enquanto o Parquet se torna legível apenas quando o rodapé é gravado.
Bloco 1 · Layout
A partição só ajuda quando aparece na cláusula de filtro e quando sua cardinalidade não pulveriza o conjunto.
Confirme que a coluna de partição aparece nos filtros mais frequentes.
Monitore o tamanho médio de arquivo e compacte quando ele cair.
Meça bytes lidos por consulta como indicador da qualidade do layout.
Evite níveis de partição que gerem diretórios com poucos registros.
Reordene o dado dentro da partição pela coluna de filtro secundária.
Bloco 1 · Cardinalidade
Candidatas medidas no conjunto da Olist, sobre os 112 650 itens de pedido. A coluna serve como critério quando produz partições grandes o bastante para justificar um arquivo.
| Coluna candidata | Valores distintos | Itens por partição | Veredito |
|---|---|---|---|
| ano | 3 | 37 550 | Grosseira: o filtro por mês varre o ano inteiro. |
| ano e mês | 24 | 4 694 | Adequada: filtro frequente e cardinalidade estável ao longo do tempo. |
| customer_state | 27 | 42% em SP | Enviesada: uma partição concentra a carga e anula o paralelismo. |
| product_id | 32 951 | 3,4 | Pulverizada: o rodapé de cada arquivo supera o dado que ele descreve. |
| order_id | 98 666 | 1,1 | Pulverizada: aproximadamente uma linha por arquivo. |
| timestamp da compra | 98 112 | 1,1 | Pulverizada: a precisão de segundo torna a coluna quase única. |
Bloco 1 · Compactação
Cada arquivo custa uma abertura, uma leitura de rodapé e uma entrada de metadado. Em escala, esse custo fixo domina o tempo de resposta.
| Sintoma observável | Causa provável | Correção | Evidência de que funcionou |
|---|---|---|---|
| Tamanho médio de arquivo em queda | Ingestão em micro-lotes sem consolidação. | Rotina de compactação por partição fechada. | Tamanho médio volta à faixa alvo. |
| Listagem lenta antes da consulta | Excesso de objetos por prefixo. | Compactação e revisão dos níveis de partição. | Tempo de planejamento cai. |
| Consulta filtrada lê o conjunto inteiro | Filtro não corresponde à coluna de partição. | Reparticionar ou reordenar pela coluna de filtro. | Bytes lidos por consulta caem. |
| Custo de varredura acima do orçado | Formato sem estatística ou partição ausente. | Converter para colunar e particionar. | Custo por consulta cai com o mesmo resultado. |
Bloco 2 · Sistemas distribuídos
O conjunto excede a capacidade de um disco e a confiabilidade de uma máquina isolada. As duas respostas estruturais são a divisão e a repetição do dado.
O conjunto é fatiado por uma chave e cada fatia reside em um nó. O mecanismo acrescenta capacidade e paralelismo, ao custo de distribuição desigual quando a chave é enviesada e de consultas que precisam cruzar fatias.
Cada fatia é gravada em mais de um nó. O mecanismo acrescenta durabilidade e disponibilidade de leitura, ao custo de espaço adicional e da necessidade de manter as cópias coerentes entre si.
Bloco 2 · Réplica e quórum
O quórum estabelece a relação entre latência e garantia: quanto maior o número de réplicas exigidas na confirmação, maior o tempo de resposta e menor a probabilidade de perda.
Declare o fator de replicação e o que ele custa em espaço.
Distinga durabilidade, que preserva o dado gravado, de disponibilidade, que garante a leitura no instante solicitado.
Registre o comportamento esperado quando um nó cai durante a escrita.
Distribua as réplicas em domínios de falha distintos.
Trate o reprocessamento como rotina, uma vez que a falha parcial constitui evento esperado.
Bloco 2 · Consistência
Sob partição de rede, o sistema opta entre responder com estado possivelmente desatualizado e recusar a resposta. Na ausência de partição, a opção se dá entre consistência e latência.
Exige coordenação entre réplicas antes de responder, ao custo de latência e de disponibilidade durante falhas. Constitui o regime esperado do catálogo de tabelas.
A leitura pode devolver estado anterior por algum tempo. Aceitável para a listagem de objetos e para as réplicas de leitura, e inaceitável para o ponteiro que indica a versão vigente da tabela.
Havendo partição de rede, a escolha recai entre consistência e disponibilidade, e na ausência de partição, entre consistência e latência. Toda arquitetura de dados realiza essa escolha, e explicitá-la integra o trabalho de projeto.
Bloco 2 · Consequências práticas
Cada garantia ausente se converte em regra de engenharia na ingestão e na publicação do dado.
| Propriedade distribuída | Efeito observável no lakehouse | Regra de engenharia correspondente |
|---|---|---|
| Escrita não atômica | A consulta enxerga arquivos de uma carga ainda incompleta. | Publicar por troca de ponteiro: só o commit no catálogo torna a versão visível. |
| Listagem eventual (depende do serviço) | Arquivo recém-gravado pode não aparecer de imediato. S3 (desde dez/2020) e MinIO listam de forma consistente, mas a listagem inclui arquivos de carga em andamento. | Registrar os arquivos no manifesto da tabela e consultá-lo no lugar da listagem do bucket. |
| Reentrega de mensagens | O mesmo pedido é ingerido duas vezes após uma falha parcial. | Ingestão idempotente por chave natural e janela, com deduplicação na camada silver. |
| Falha parcial de carga | Metade das partições atualizada, metade não. | Reprocessar a partição integralmente, tratando a carga como unidade atômica. |
| Relógios distintos | Eventos chegam fora de ordem e com atraso. | Separar data do evento da data de ingestão e declarar a janela de atraso aceita. |
Bloco 3 · Vocabulário
Os quatro coexistem no mesmo projeto. A distinção decorre do momento de aplicação do schema e do público atendido.
| Repositório | Schema | Dado que aceita | Público | Uso típico |
|---|---|---|---|---|
| Data warehouse | Definido na escrita | Estruturado e tratado | Analista de negócio | Relatório, BI, série histórica |
| Data lake | Aplicado na leitura | Bruto: estruturado, semi e não estruturado | Engenheiro e cientista de dados | Exploração e aprendizado de máquina |
| Data mart | Definido na escrita, recortado | Estruturado, muitas vezes agregado | Uma área específica | Análise departamental |
| Lakehouse | Declarado no catálogo, sobre arquivo aberto | Bruto e tratado, na mesma plataforma | Os três públicos acima | Uma cópia servindo BI e ciência de dados |
Bloco 3 · Lakehouse
Formatos de tabela acrescentam atomicidade, histórico e evolução de schema a arquivos que continuam abertos e legíveis por vários motores.
A tabela publica um novo snapshot apenas quando a escrita conclui. Quem lê continua vendo a versão anterior até a troca do ponteiro.
O histórico de snapshots permite reprocessar um período e comparar versões. O histórico torna reversível a operação de apagar e regravar.
Acrescentar coluna, renomear e alterar tipo passam pelo catálogo, com registro de quando a mudança entrou em vigor.
Bloco 3 · Camadas
A existência de uma camada se justifica pela mudança do compromisso de qualidade que ela assume.
Bloco 3 · Ciclo de vida
A transição entre classes é definida como regra automática, aplicada conforme a frequência de acesso decresce.
Acesso frequente e latência baixa. Maior custo de guarda, menor custo de leitura.
Acesso ocasional. Guarda mais barata, com custo de recuperação por leitura.
Acesso raro, com tempo mínimo de permanência e taxa de recuperação relevante.
Retenção legal. Recuperação sob demanda, medida em horas.
Bloco 3 · Custo e segurança
O baixo custo de guarda favorece o acúmulo. A despesa relevante decorre da leitura repetida de dados que poderiam ter sido movidos para classe mais fria ou expurgados.
Aplique regra de lifecycle automática para transição e expurgo.
Atribua orçamento e alerta de custo por domínio.
Conceda acesso mínimo por prefixo e audite o uso.
Cifre em repouso e em trânsito, com chave sob custódia declarada.
Separe dado pessoal por prefixo próprio, com retenção própria.
A classificação, a propriedade e a retenção definidas na governança têm efeito quando se convertem em política de acesso, regra de lifecycle e rótulo de custo no próprio storage.
O rótulo por domínio decompõe o custo do armazenamento e atribui a cada parcela um responsável pela redução.
Segunda hora · Card de trabalho em sala
Em grupo, sobre os dados da Olist: ingerir, modelar dimensionalmente e responder com SQL executado sobre a camada analítica.
Declare antes o que é volume — receita ou quantidade de itens — e mantenha a definição nas três respostas.
Diga se "produto" é o item individual ou a categoria, e por que essa escolha responde melhor à pergunta do negócio.
Série mensal do primeiro ao último mês de venda, com a leitura do que explica os picos e os vales.
Segunda hora · Arquitetura
A arquitetura de um lakehouse em nuvem reproduzida em dois processos locais: um serviço compatível com S3, um motor analítico e Parquet como formato de intercâmbio.
Segunda hora · Preparação · 10 minutos
Três comandos no terminal e um bloco de configuração no DuckDB estabelecem o ambiente do laboratório.
Segunda hora · Camada bronze · 15 minutos
A camada preserva o conteúdo de origem. O ganho é de formato e de layout, e a contagem verifica a integridade da carga.
Segunda hora · Modelagem · 20 minutos
As três perguntas se respondem sobre o mesmo fato, variando a dimensão de análise: geografia, produto e tempo.
Grão: um item de um pedido entregue. Medidas: preço, frete e valor total. Constitui o grão mais fino disponível, e as agregações em níveis superiores derivam dele.
Do cliente deriva a UF e, por regra explícita, a região. O dado bruto não contém o atributo região: ele é produzido nesta dimensão.
Produto e categoria, com a tradução da categoria aplicada. Declare qual dos dois níveis responde a pergunta.
Mês da compra, derivado do carimbo do pedido. O mês constitui o eixo da sazonalidade e a chave de partição da bronze.
Segunda hora · Modelagem · dimensão de produto
A dimensão tem uma linha por produto e a categoria em inglês, que é o domínio usado nas consultas das perguntas 2 e 3. A junção com a tradução é externa, para que nenhum produto se perca.
Segunda hora · Silver e gold
A silver garante a chave única e os tipos, e a gold junta o fato às dimensões e grava o resultado particionado pela coluna que as perguntas filtram.
Segunda hora · Respostas · 10 minutos
O modelo dimensional adequado reduz cada pergunta a um recorte do mesmo fato.
Segunda hora · Conferência
Ordens de grandeza para comparação, medindo o volume por receita, sobre pedidos entregues e no grão do item.
| Etapa | O que verificar | Referência |
|---|---|---|
| Bronze | Contagem do CSV contra a do Parquet no bucket. | 99 441 pedidos, idênticos dos dois lados. |
| Fato | Linhas do fato após o filtro de entregues. | Ordem de 110 mil itens, distribuídos em cinco regiões. |
| Pergunta 1 | Região de menor receita. | Norte, com margem ampla sobre a penúltima região: cerca de 2 mil itens e R$ 0,40 milhão. |
| Pergunta 2 | Categoria líder no Norte, por número de itens. | health_beauty, à frente de computers_accessories e sports_leisure. |
| Pergunta 3 | Série mensal dessa categoria no Norte. | Vinte e um meses, de out/2016 a ago/2018, com volume crescente e picos em nov/2017 e jun-ago/2018. |
Segunda hora · Uso de IA · em paralelo
O assistente acelera a escrita e o reconhecimento do schema. A verificação permanece atribuição do grupo e determina a correção do resultado.
"Estes são os cabeçalhos das oito tabelas do Olist. Proponha chaves primárias e estrangeiras e o caminho de junção para responder: qual região vende menos."
"Escreva SQL DuckDB que grave os CSVs em Parquet no bucket s3://lakehouse via MinIO e monte um fato no grão do item entregue com dimensões de região, produto e mês."
"Aponte, neste SQL, o que duplica linhas na junção, o que quebra se a carga rodar duas vezes e o que altera o resultado em vez do desempenho."
Toda saída da IA é executada e conferida antes de entrar no repositório.
Verifique a contagem de linhas em cada camada e explique cada diferença.
Confirme os tipos com DESCRIBE: a inferência automática exige verificação.
Verifique a contagem do fato antes e depois de cada junção.
Registre o prompt junto do SQL, uma vez que ele integra o registro da decisão.
Verifique cada nome de coluna contra o schema: o assistente preenche lacunas por inferência.
Segunda hora · Medição
O registro das medidas antes e depois da alteração sustenta a decisão de layout.
| Evidência | Como obter no DuckDB | O que ela demonstra |
|---|---|---|
| Volume por formato | Tamanho do CSV contra o do prefixo no bucket, pelo console do MinIO. | O efeito da codificação colunar e da compressão. |
| Número e tamanho de arquivos | SELECT * FROM parquet_file_metadata('s3://lakehouse/bronze/orders/**/*.parquet') | Se a estratégia de partição gerou arquivos pequenos. |
| Estatística por bloco | SELECT * FROM parquet_metadata('s3://lakehouse/gold/fato_item_venda/**/*.parquet') | Que mínimo e máximo por row group tornam o pruning possível. |
| Custo da consulta | EXPLAIN ANALYZE na pergunta 3, lendo do CSV e lendo da gold particionada. | Quanto do ganho vem do formato e quanto vem do layout. |
| Idempotência | Após duas execuções da carga bronze, cada uma precedida da remoção do prefixo: SELECT count(*) AS arquivos, sum(num_rows) AS linhas FROM parquet_file_metadata('s3://lakehouse/bronze/orders/**/*.parquet') | Que a reexecução não acumula arquivos nem duplica linhas: os dois números se repetem, com 99 441 linhas. |
Ponte com a Aula 1 · Spec-Driven Development
A decisão de armazenamento entra no projeto como requisito, decisão registrada e critério verificável.
Manter cinco anos de eventos brutos consultáveis sob demanda para auditoria.
Tamanho médio de arquivo entre 128 MB e 1 GB; dados com mais de 12 meses em classe fria; carga idempotente sob reentrega; custo mensal dentro do orçamento do domínio.
Parquet particionado por ano e mês, publicado por commit no catálogo. Descartado: JSON por dia, que impede pruning por coluna e multiplica arquivos pequenos. Consequência: exige compactação e manutenção de snapshots.
Dado um diretório com 10 000 arquivos de 1 MB, quando executo a compactação, então restam arquivos de pelo menos 128 MB e a mesma consulta lê menos bytes.
Entrega do card de trabalho
O que o grupo entrega ao final da segunda hora, e o que será conferido.
O SQL da ingestão, do modelo e das consultas; as três respostas com número; e uma frase por pergunta que declare o significado daquele número para o negócio do parceiro.
Os dados estão no bucket do MinIO em Parquet, com partição declarada e justificada.
A contagem da bronze coincide com a do CSV de origem.
O fato tem grão declarado e as dimensões que as três perguntas exigem.
A definição de volume e o recorte de status estão declarados por escrito.
As três consultas são executadas sobre a camada gold e devolvem valores medidos.
Há ao menos uma evidência medida: tamanho, número de arquivos ou bytes lidos.
Autoestudos · antes do próximo encontro
Quando o repositório de dados deixa de servir à decisão, e o que precisa mudar na arquitetura para que volte a servir?
Leia identificando os sintomas de armazenamento e integração, e proponha, com o vocabulário da aula, qual camada resolveria cada um.
notion.site · leitura VídeoCompare a distinção apresentada no vídeo com a tabela discutida em aula e anote onde o lakehouse muda os termos do problema.
youtube.com · vídeo Referência técnicaUse como referência de vocabulário: schema na escrita e na leitura, tipos de dado aceitos, público e caso de uso de cada repositório.
aws.amazon.com · documentaçãoAula 10 · Síntese
Armazenamento em Grande Escala · 01/09/2026 · Prof. Afonso
Ao final do encontro, o estudante deve ser capaz de escolher formato, organização física, camadas e política de ciclo de vida para os dados do projeto, justificando as decisões pelas propriedades distribuídas do armazenamento, e de construir um lakehouse que responda a perguntas de negócio com SQL executado.
Primeira hora de exposição dialogada em três blocos, cada um encerrado por checklist de aplicação e erro comum. Segunda hora de atividade em grupo: os estudantes ingerem os dados públicos da Olist em um lakehouse local com MinIO e DuckDB, modelam dimensionalmente no grão do item de pedido entregue e respondem a três perguntas de negócio, usando IA para gerar o SQL e verificando cada etapa por contagem, tipo e medição.