Pular para o conteúdo

Papers

Designs, Lessons and Advice from Building Large Distributed Systems

Jeff Dean · LADIS 2009 (keynote), 2009

O que é esta palestra: conselhos de design destilados de sistemas em larga escala

Este material é uma keynote de Jeff Dean, Google Fellow, apresentada no workshop LADIS 2009 sobre sistemas distribuídos de larga escala. Trata-se de um conjunto de slides, não de um paper clássico, então não há um único algoritmo ou teorema: há lições de design e regras práticas tiradas da construção de sistemas grandes. Os slides partem de uma pergunta: dado um problema básico, como escolher a melhor solução? E lembram que 'melhor' pode significar a mais simples, a de maior desempenho, a mais fácil de estender, entre outras. Em seguida apontam uma habilidade como importante: estimar o desempenho de um design sem precisar construí-lo antes. Este material cobre a parte de conselhos de design da palestra: a tabela de custos de operações básicas e uma estimativa resolvida passo a passo (ferramentas dessa habilidade), além de orientações sobre projetar para crescimento, infraestrutura compartilhada e aplicações de baixa latência. O restante dos slides descreve sistemas do Google (GFS, MapReduce, BigTable, entre outros), que não entram aqui. Um alerta é essencial para quem lê hoje: todos os números da palestra são de hardware de 2009. Servem para dar ordens de grandeza e proporções entre operações, não como especificações atuais. Em trabalho real de capacidade, substitua os valores por medições atuais.

Numbers Everyone Should Know (valores de 2009)

Um slide lista custos aproximados de operações básicas, com valores da época (2009). Uma referência ao cache L1 custa 0,5 ns, um branch mispredict 5 ns, uma referência ao cache L2 7 ns e um lock/unlock de mutex 25 ns. Uma referência à memória principal custa 100 ns. Comprimir 1 KB com Zippy (compressor rápido usado no Google) aparece como 3.000 ns. Enviar 2 KB por uma rede de 1 Gbps custa 20.000 ns, ler 1 MB sequencialmente da memória 250.000 ns e um round trip dentro do mesmo datacenter 500.000 ns. Um disk seek custa 10.000.000 ns (10 ms), ler 1 MB sequencialmente do disco 20.000.000 ns (20 ms) e um pacote indo da Califórnia à Holanda e voltando 150.000.000 ns (150 ms). O valor está nas diferenças entre as linhas. Por divisão simples dos valores listados, um disk seek custa cerca de 100.000 vezes uma referência à memória principal, e um round trip intercontinental custa cerca de 300 vezes um round trip dentro do datacenter. Ler 1 MB sequencialmente do disco leva apenas o dobro de um único seek nesta tabela, o que mostra por que evitar acessos aleatórios importa tanto. Essas proporções orientam decisões como usar cache em memória, manter dados próximos ou agrupar trabalho em lotes.

Cálculo de cabeça na prática: a página de resultados com 30 thumbnails

A palestra mostra como usar esses números numa estimativa concreta: quanto tempo leva para gerar uma página de resultados de imagens com 30 thumbnails? O primeiro design lê as imagens em série e gera thumbnails a partir de imagens de 256 KB na hora. Com seek de 10 ms e leitura a 30 MB/s, o slide soma 30 seeks de 10 ms mais 30 leituras de 256 KB a 30 MB/s e chega a cerca de 560 ms. O segundo design dispara as leituras em paralelo: a página espera apenas um seek e uma leitura de 256 KB, o que dá cerca de 18 ms. O slide acrescenta uma ressalva: a conta ignora a variância, então o valor realista seria algo como 30 a 60 ms. Os slides ainda listam variações a explorar, como cache (de imagens individuais ou de conjuntos inteiros de thumbnails) e pré-cálculo dos thumbnails. Duas lições seguem. Primeiro, poucos minutos de aritmética com os custos certos separam dois designs antes de existir código: pela divisão dos dois totais do slide (560 ms / 18 ms), o serial sai cerca de 30 vezes mais lento na estimativa que ignora a variância. Segundo, a estimativa só é tão boa quanto seu modelo do que o sistema faz, e o que foi ignorado deve ser declarado. Estimar capacidade segue a mesma receita: liste as operações, multiplique pelos custos e diga o que deixou de fora.

Projetar para crescimento: 10X ou 20X, não 100X

Os slides trazem uma regra curta e específica sobre escala. Tente antecipar como os requisitos vão evoluir e mantenha em mente as funcionalidades prováveis ao desenhar o sistema base. Depois, garanta que o design continue funcionando se a escala mudar por 10X ou 20X. O mesmo slide traz o contrapeso: a solução certa para uma escala X muitas vezes não é a ideal para 100X. Uma leitura possível, que é nossa e não está nos slides: um design dimensionado para a carga de hoje, mas verificado contra um aumento de dez vezes, tende a sobreviver ao crescimento por um bom tempo, enquanto projetar para cem vezes paga custo de complexidade agora por uma demanda que talvez nunca chegue. Isso se liga à estimativa: para checar um design a 10X, refaz-se a conta de cabeça com dez vezes mais requisições ou dados e vê-se qual recurso acaba primeiro, seja memória, seeks de disco ou rede. Os slides também advertem, no tema de infraestrutura, contra imaginar necessidades improváveis que não existem de fato. Antecipar mudanças prováveis é incentivado; especular sobre as improváveis é o tipo de excesso de engenharia que a palestra desaconselha.

Lições sobre infraestrutura e aplicações de baixa latência

Dois grupos de conselhos nos slides merecem destaque. O primeiro trata da construção de infraestrutura compartilhada: identifique problemas comuns e construa software que os resolva de forma geral, mas não tente ser tudo para todos. Os slides ilustram com clientes que exigem oito coisas diferentes: atender seis é fácil, atender sete exige reflexão real, e tentar atender as oito costuma resultar num sistema pior e mais complexo, que compromete os outros clientes. Não construa infraestrutura por si só e não imagine necessidades que não existem. A abordagem sugerida é usar a própria infraestrutura, especialmente no início, porque isso dá feedback muito mais rápido sobre o que funciona. O segundo grupo trata de aplicações interativas que exigem baixa latência. Mire tempos médios baixos, mas os percentis 90 e 99 também são muito importantes, então preocupe-se com a variância. Pense em quanto dado você movimenta: dezenas de RPCs de 1 MB por requisição de usuário deixam a latência ruim. Para domar a cauda de latência, os slides citam redundância ou timeouts; como medidas gerais de baixa latência, listam uso criterioso de cache, prioridade maior para requisições interativas e paralelismo. Tudo isso se liga à tabela de números, pois cada megabyte movimentado ou round trip extra tem um custo que se pode somar.

Veja as ideias em ação

Pratique na escola de System Design os desenhos que usam este paper.