Blog

Como eu enxergo a arquitetura do YouTube.

Terceiro texto da série em que eu leio arquiteturas conhecidas a partir de material público de engenharia. Não é a planta interna: é a leitura do que organiza o resto.

O YouTube tem duas coisas que eu considero de escola: o tratamento do upload e o formato da recomendação. Os dois carregam padrões que dá pra usar em sistema muito menor.

Upload não é uma requisição

A intuição errada é tratar upload como um POST que termina quando o arquivo chega.

Um vídeo enviado precisa virar dezenas de arquivos diferentes: várias resoluções, vários formatos, vários perfis de compressão, faixas de áudio separadas, miniaturas, legendas. Isso é minutos ou horas de processamento pesado.

Se isso acontecer dentro da requisição, você tem uma conexão pendurada, um timeout garantido e nenhum jeito de retomar quando falhar.

O desenho é um pipeline com estados.

Upload retomável Fatiar pedaços curtos worker · 2160p worker · 1080p worker · 720p worker · 480p worker · áudio Empacotar manifesto + segmentos Borda CDN cada etapa tem estado próprio · cada pedaço é reprocessável isoladamente
Upload como pipeline — o trabalho é fatiado para poder ser paralelo e retomável

Duas decisões dentro disso me interessam mais que o resto.

Fatiar antes de processar. Transcodificar um vídeo de duas horas como uma unidade é um trabalho de horas que, se falhar aos 90%, recomeça do zero. Fatiado em pedaços curtos, o trabalho vira paralelo em centenas de máquinas e a falha custa um pedaço, não o vídeo.

Qualidade progressiva. Não é preciso ter todas as resoluções prontas pra publicar. A menor fica pronta primeiro e o vídeo já pode ser assistido, enquanto as outras chegam. O usuário percebe “já está no ar” bem antes de o trabalho terminar.

Esse padrão de entregar o resultado parcial cedo é transferível pra qualquer processamento demorado, e quase ninguém usa.

O streaming é o cliente decidindo

O que sai do empacotamento não é um arquivo de vídeo. É um manifesto que descreve as qualidades disponíveis e os pedaços de cada uma.

O reprodutor baixa o manifesto, escolhe uma qualidade, baixa alguns segundos, mede quanto tempo levou e decide sozinho se sobe ou desce de qualidade no próximo segmento.

Isso inverte a responsabilidade de um jeito que eu acho elegante: o servidor não sabe nada sobre a conexão de quem assiste, e é justamente quem assiste que tem essa informação. Em vez de tentar adivinhar do lado errado, o desenho entrega as opções e deixa a decisão onde o dado está.

Como consequência, o servidor só entrega arquivo estático. Nada de estado de sessão, nada de transcodificação sob demanda no caminho quente. Tudo cacheável na borda, porque nada é personalizado.

A recomendação é um funil, não uma escolha

Aqui está o padrão que eu mais uso de referência.

O problema parece ser “escolher os melhores vídeos pra essa pessoa” num acervo de bilhões. Pontuar bilhões de itens por usuário, em tempo de requisição, é impossível.

A solução publicada é dividir em duas etapas com naturezas opostas.

Acervo — bilhões de vídeos nunca pontuado item a item Geração de candidatos modelo barato · centenas de itens · alta cobertura Ranking — modelo caro · dezenas de itens custo por item ↑
O funil — reduza barato, depois pontue caro

A geração de candidatos é barata e generosa: reduz bilhões pra algumas centenas, com modelos simples e muita heurística. Ela pode errar pra mais, e o custo de um candidato ruim aqui é baixo.

O ranking é caro e exigente: pontua algumas centenas com um modelo pesado, considerando muito mais sinal. Ele só existe porque a etapa anterior tornou o volume tratável.

A lição, que vale pra qualquer busca ou recomendação: você nunca aplica a lógica cara no conjunto todo. Você reduz primeiro com algo barato, e a qualidade final depende muito mais da etapa de redução do que do modelo sofisticado. Um item que não vira candidato nunca vai ser recomendado, por melhor que o ranking seja.

Vi o mesmo padrão no Twitter, com outro nome.

A contagem de visualizações que não bate

Um detalhe pequeno que vale como aula de sistemas distribuídos: por muito tempo, contagem de visualização em vídeo viral ficava travada num número enquanto o resto subia.

A razão é que contar de verdade é caro. Cada visualização é um evento em algum lugar do mundo, e somar isso com precisão em tempo real, num sistema distribuído, custa mais do que o número vale.

A escolha foi: mostre um valor aproximado rápido, e reconcilie depois com o número exato, que é apurado com calma, com filtro antifraude.

O que me interessa aqui não é o truque, é o reconhecimento explícito de que nem todo número precisa ser exato agora. A contagem de visualização pode ser aproximada. O número que paga o criador não pode.

Sistemas que tratam os dois com o mesmo rigor gastam demais no primeiro, ou de menos no segundo. É a mesma distinção que aparece em saldo calculado ou materializado: descubra qual número é opinião e qual é verdade.

O que eu levo pra sistema pequeno

Todo processamento longo é um pipeline com estado, não uma requisição. Se leva mais de alguns segundos, precisa de fila, de estados persistidos e de retomada por etapa.

Fatie o trabalho até que a falha seja barata. A unidade de reprocessamento deveria ser pequena o suficiente pra que refazer não doa.

Entregue o resultado parcial. A versão de baixa qualidade pronta primeiro vale mais que a versão perfeita dez minutos depois.

Reduza antes de pontuar. Qualquer coisa que ordene por relevância deveria ter uma etapa barata de corte antes da etapa cara. Isso vale pra recomendação, pra busca e pra qualquer relatório que ordene muita coisa.

← Voltar pro blog