O que é codificação just-in-time?
A codificação just-in-time cria uma representação de mídia solicitada sob demanda, em vez de calcular antecipadamente todas as variantes de resolução, codec ou qualidade. O resultado pode então ser armazenado em cache para requisições posteriores.
Como funciona a codificação just-in-time
Um sistema just-in-time coloca o codificador por trás da URL de entrega. Uma requisição especifica uma origem e uma receita; o cache é consultado em busca de um resultado armazenado, e a codificação só é executada em caso de ausência no cache, após o que a saída é retornada e armazenada para requisições posteriores. Esse cache pode ser uma CDN à frente do codificador, um armazenamento gerenciado pelo próprio serviço ou ambos. Um codificador que não dispõe de nenhum dos dois repete o trabalho a cada requisição, e um resultado armazenado só é reutilizado até expirar ou ser removido do cache. Para imagens, a unidade de trabalho é uma URL. Para vídeo, a unidade prática é um segmento de um fluxo adaptativo, em vez do arquivo inteiro: um reprodutor HLS primeiro solicita listas de reprodução, que o serviço gera dinamicamente, e depois solicita segmentos curtos, cada um codificado quando é solicitado pela primeira vez. Apenas as representações e os intervalos de tempo solicitados são codificados; os reprodutores carregam segmentos adiante da posição de reprodução, por isso esse processo pode incluir segmentos que ninguém chega a assistir. A Mux, que chama isso de transcodificação just-in-time, descreve a transmissão de quadros a partir do transcodificador antes que o processamento do restante do arquivo esteja concluído.
Informações essenciais
- Empacotamento just-in-time é a mesma coisa? Não. O empacotamento just-in-time reempacota representações já existentes no formato de streaming solicitado por um reprodutor. O AWS Elemental MediaPackage descreve isso como a criação de um manifesto em um formato compatível com o dispositivo solicitante; seu conteúdo de origem vem de um codificador anterior na cadeia de processamento para vídeo ao vivo e, para vídeo sob demanda, de arquivos HLS ou MP4 armazenados no Amazon S3. O nginx-vod-module descreve o reempacotamento dinâmico de arquivos MP4 para DASH, HDS, HLS e MSS. Nenhum dos dois descreve a codificação em uma nova resolução ou taxa de bits, portanto a escada de codificação ainda precisa ser produzida antecipadamente. A codificação just-in-time também adia essa etapa.
- Quanto custa a primeira requisição e o que acontece se várias chegarem ao mesmo tempo? A primeira requisição de uma saída aguarda a obtenção do conteúdo de origem e a codificação; as requisições seguintes são acertos de cache enquanto o resultado permanecer em cache. A documentação do imgproxy observa que as CDNs normalmente excluem conteúdo raramente acessado, então uma saída pouco solicitada pode ser codificada mais de uma vez. Requisições iniciais simultâneas para a mesma saída podem iniciar uma codificação cada uma, a menos que o cache à frente as agrupe em uma única requisição ou o próprio codificador compartilhe o trabalho em andamento, como faz o servidor de imagens imagor. Esse agrupamento tem condições: a Cloudflare agrupa por data center, no NGINX,
proxy_cache_lockestá desativado por padrão e, na Fastly, uma resposta que não pode ser armazenada em cache faz com que as requisições na fila sejam encaminhadas ao servidor de origem uma após a outra. - O que acontece com a saída em cache quando as configurações de codificação mudam? Nada de imediato, a menos que a mudança altere a chave de cache. Um resultado armazenado é encontrado pela sua chave, normalmente composta pela origem, pelas opções de processamento e pelo formato de saída, então uma mudança em uma predefinição do lado do servidor, no valor padrão de qualidade ou em uma marca-d’água que não se reflita na requisição mantém a saída antiga até que ela expire ou seja invalidada. O imgproxy documenta uma opção de URL chamada
cachebusterexatamente para esse caso e observa que seu cache interno não permite invalidação manual, apenas a expiração configurada no armazenamento subjacente. Adicionar uma versão à URL quando uma receita muda atribui imediatamente uma nova chave à nova saída. - O que deve acontecer quando uma codificação falha? A resposta de erro precisa de sua própria política de cache. Se ela tiver o mesmo prazo de validade de um resultado bem-sucedido, uma falha transitória persiste: um usuário do imgproxy relatou uma resposta 504 enviada com um cabeçalho
Cache-Controlque definia validade de um ano e armazenada por um cache NGINX posterior na cadeia. Se os erros nunca forem armazenados em cache, cada requisição de uma origem com problema repete a falha custosa. Sem cabeçalhos explícitos de cache, o HTTP permite que um cache armazene e reutilize uma resposta 404, que pode ser armazenada em cache por heurística, mas não uma resposta 500, 503 ou 504. As diretivas deCache-Controlmudam isso nos dois sentidos:max-ageoupublicpermite armazenar esse tipo de erro, eno-storeproíbe o armazenamento de qualquer resposta.
Quando a codificação just-in-time é relevante
A codificação just-in-time compensa quando você não consegue prever quais representações, ou quais partes de um arquivo, serão solicitadas: grandes acervos e uploads de usuários em que a maior parte do material raramente é assistida, ou tamanhos de imagem que dependem de layouts que você ainda não criou. As codificações que ninguém solicita nunca são executadas. Para materiais raramente solicitados, o tempo que um resultado permanece em cache determina com que frequência uma solicitação repetida exige pagar novamente pela codificação. Prefira codificar antecipadamente quando todas as saídas precisarem estar prontas antes da publicação, quando alguém precisar revisá-las primeiro ou quando a primeira solicitação precisar ser tão rápida quanto todas as seguintes. Uma escala fixa de representações não é, por si só, motivo para codificar antecipadamente: um codificador just-in-time pode fornecer representações predefinidas e ainda ignorar os segmentos que ninguém solicita.
Como a Transloadit ajuda com a codificação just-in-time
A Transloadit oferece codificação just-in-time por meio do Smart CDN. Para vídeos, o Robot /video/ondemand gera playlists e segmentos HLS sob demanda: um reprodutor solicita a playlist multivariante de uma URL tlcdn.com, cada segmento é codificado na primeira vez em que é solicitado, e o Smart CDN armazena playlists e segmentos em cache para os próximos espectadores. Para imagens e outros arquivos, uma URL do Smart CDN executa um Template quando não há um resultado no cache e fornece o resultado em cache até que ele expire.
A documentação de /video/ondemand descreve a saída HLS. O Robot /file/serve define por quanto tempo os resultados ficam em cache: por padrão, ele instrui as CDNs a manter um resultado por 24 horas e os navegadores por 72 horas, e cache_duration altera ambos os prazos. Quando as URLs das playlists são assinadas com sign_urls_for, prazos de expiração mais curtos reduzem o reaproveitamento do cache e podem aumentar a regeneração dos segmentos. As páginas vinculadas não informam o que acontece com resultados que já estão em cache quando um Template é editado, nem o que um reprodutor recebe quando a codificação de um segmento falha, então teste as duas situações antes de confiar nesses comportamentos.
Fontes
- Blog de engenharia da Mux: transcodificação just-in-time e o que ela evita codificar
- AWS Elemental MediaPackage: conceitos e terminologia (empacotamento just-in-time)
- README de kaltura/nginx-vod-module: reempacotamento dinâmico e recomendações de cache
- RFC 8216: HTTP Live Streaming, seção 6.3.3 (os clientes carregam segmentos antecipadamente)
- RFC 9110: semântica HTTP, seção 15.1 (códigos de status que podem ser armazenados em cache por heurística)
- RFC 9111: cache HTTP (armazenamento e reutilização de respostas, requisições agrupadas, diretivas Cache-Control)
- Cloudflare: comportamento padrão do cache, incluindo o agrupamento de requisições
- NGINX ngx_http_proxy_module: proxy_cache_lock e proxy_cache_valid
- Fastly: agrupamento de requisições
- Código-fonte de cshum/imagor: requisições simultâneas para o mesmo resultado compartilham uma única operação em andamento
- imgproxy: chave do cache interno, expiração e limitações
- imgproxy: opções de processamento, incluindo cachebuster
- Problema 686 do imgproxy: um mantenedor comenta sobre deixar o cache a cargo de CDNs e servidores de cache
- Problema 1677 do imgproxy: Cache-Control enviado em uma requisição que falhou