Re-arquitetando o porteiro de vídeo

De Drew Koszewnik

Blog de Tecnologia da Netflix Seguir Jul 12 · 10 min ler

Esta é a história sobre como a equipe de Engenharia de Configuração de Conteúdo usou a Hollow, uma tecnologia Netflix OSS, para reprojetar e simplificar um componente essencial em nosso pipeline de conteúdo – fornecendo uma grande quantidade de valor comercial no processo.

O contexto

Cada filme e programa no serviço Netflix é cuidadosamente organizado para garantir uma experiência de visualização ideal. A equipe responsável por essa curadoria é a Title Operations . Operações de título confirmarão, entre outras coisas:

  • Estamos em conformidade com os contratos – os intervalos de datas e os locais em que podemos mostrar um vídeo são configurados corretamente para cada título
  • Vídeos com legendas, legendas e recursos secundários de “dub” de áudio são originados, traduzidos e disponibilizados para as populações certas em todo o mundo
  • O nome do título e a sinopse estão disponíveis e traduzidos
  • Os ratings de vencimento apropriados estão disponíveis para cada país

Quando um título atende a todos os requisitos mínimos acima, ele pode entrar em operação no serviço. O Gatekeeper é o sistema da Netflix responsável por avaliar a “vivacidade” dos vídeos e ativos no site. Um título não se torna visível para os membros até que o Gatekeeper o aprove – e se ele não puder validar a configuração, ele ajudará o Title Operations apontando o que está faltando na experiência básica do cliente.

O Gatekeeper realiza sua tarefa prescrita agregando dados de vários sistemas a montante, aplicando alguma lógica de negócios e produzindo uma saída detalhando o status de cada vídeo em cada país.

The Tech

O Hollow , uma tecnologia de OSS que lançamos há alguns anos, foi melhor descrita como um cache próximo de alta densidade total :

  • Total : o conjunto de dados inteiro é armazenado em cache em cada nó – não há política de remoção e não há erros de cache.
  • Alta Densidade : técnicas de codificação, empacotamento de bits e desduplicação são empregadas para otimizar a pegada de memória do conjunto de dados.
  • Próximo : o cache existe na RAM em qualquer instância que requer acesso ao conjunto de dados.

Uma coisa empolgante sobre a natureza total dessa tecnologia – porque não precisamos nos preocupar em trocar registros de dentro e fora da memória, podemos fazer suposições e fazer alguma pré-computação da representação na memória do conjunto de dados que não seria caso contrário, seria possível. O resultado líquido é, para muitos conjuntos de dados, um uso muito mais eficiente da RAM. Enquanto que com uma solução de cache parcial tradicional, você pode se perguntar se pode economizar apenas 5% do cache de dados ou se precisa reservar espaço suficiente para 10% para obter uma taxa de acertos / erros aceitável – com o mesmo quantidade de memória O Hollow pode armazenar em cache 100% do seu conjunto de dados e atingir uma taxa de acerto de 100%.

E, obviamente, se você obtiver uma taxa de acerto de 100%, você elimina toda a E / S necessária para acessar seus dados – e pode alcançar um acesso de dados mais eficiente em termos de ordem de grandeza, o que abre muitas possibilidades.

O status quo

Até muito recentemente, o Gatekeeper era um sistema completamente orientado a eventos. Quando uma alteração de um vídeo ocorreu em qualquer um de seus sistemas upstream, esse sistema enviava um evento ao Gatekeeper. O Gatekeeper reagiria a esse evento alcançando cada um de seus serviços de upstream, reunindo os dados de entrada necessários para avaliar a vivacidade do vídeo e seus recursos associados. Em seguida, produziria uma saída de registro único detalhando o status desse único vídeo.

Arquitetura do antigo gatekeeper

Este modelo teve vários problemas associados a ele:

  • Este processo foi completamente ligado a E / S e colocou muita carga nos sistemas upstream.
  • Consequentemente, esses eventos faziam fila durante o dia e causavam atrasos de processamento, o que significava que os títulos talvez não entrassem em vigor na hora.
  • Pior, eventos que ocasionalmente ficam esquecidos, ou seja, títulos não iria ao vivo em tudo até que alguém de Operações Título percebeu que havia um problema.

A atenuação desses problemas era "varrer" o catálogo, para que os vídeos que correspondessem a critérios específicos (por exemplo, programados para lançamento na semana seguinte) recebessem eventos automaticamente injetados na fila de processamento. Infelizmente, essa atenuação adicionou muitos outros eventos à fila, o que exacerbou o problema.

Claramente, uma mudança de direção era necessária.

A ideia

Decidimos empregar um cache próximo de alta densidade total (isto é, Hollow) para eliminar nossos gargalos de I / O. Para cada um dos nossos sistemas upstream, criaríamos um conjunto de dados Hollow que engloba todos os dados necessários para o Gatekeeper realizar sua avaliação. Cada sistema upstream agora seria responsável por manter seu cache atualizado.

Nova arquitetura de gatekeeper

Com esse modelo, a avaliação da vivacidade é conceitualmente separada da recuperação de dados dos sistemas upstream. Em vez de reagir a eventos, o Gatekeeper processaria continuamente a vitalidade de todos os recursos em todos os vídeos em todos os países em um ciclo repetitivo. O ciclo interage sobre todos os vídeos disponíveis no Netflix, calculando os detalhes de vivacidade de cada um deles. No final de cada ciclo, ele produz uma saída completa (também um conjunto de dados oco) que representa os detalhes do status de atividade de todos os vídeos em todos os países.

Esperávamos que esse modelo de processamento contínuo fosse possível porque a remoção completa de nossos gargalos de E / S significaria que deveríamos ser capazes de operar ordens de magnitude com mais eficiência. Também esperávamos que, ao mudar para esse modelo, percebêssemos muitos efeitos positivos para o negócio.

  • Uma solução definitiva para o excesso de carga nos sistemas upstream gerados pelo Gatekeeper
  • Uma eliminação completa dos atrasos de processamento de atividade e datas de ativação perdidas.
  • Uma redução no tempo gasto pela equipe de engenharia de configuração de conteúdo em problemas relacionados ao desempenho.
  • Melhor depuração e visibilidade do processamento de atividade.

O problema

Oco também pode ser pensado como uma máquina do tempo. À medida que um conjunto de dados muda ao longo do tempo, ele comunica essas alterações aos consumidores dividindo o cronograma em uma série de estados de dados discretos. Cada estado de dados representa um instantâneo de todo o conjunto de dados em um momento específico no tempo.

Oco é como uma máquina do tempo

Normalmente, os consumidores de um conjunto de dados oco estão carregando o estado de dados mais recente e mantendo seu cache atualizado à medida que novos estados são produzidos. No entanto, eles podem apontar para um estado anterior – o que reverterá sua visão de todo o conjunto de dados para um ponto no passado.

O método tradicional de produzir estados de dados é manter um único produtor que executa um ciclo de repetição. Durante esse ciclo , o produtor repete todos os registros da fonte da verdade. Como itera, adiciona cada registro à biblioteca oca. O Hollow calcula as diferenças entre os dados adicionados durante este ciclo e os dados adicionados durante o último ciclo, e publica o estado em um local conhecido pelos consumidores.

Uso oco tradicional

O problema com esse modelo de iteração total da fonte da verdade é que ele pode levar muito tempo. No caso de alguns dos nossos sistemas a montante, isso pode levar horas. Essa latência de propagação de dados era inaceitável – não podemos esperar horas pelo processamento de atividade se, por exemplo, o Title Operations adiciona uma classificação a um filme que precisa ser transmitido em tempo real.

O melhoramento

O que precisávamos era de uma máquina do tempo mais rápida – uma que pudesse produzir estados com uma cadência mais frequente, para que as mudanças pudessem ser percebidas mais rapidamente pelos consumidores.

Incremental Hollow é como uma máquina do tempo mais rápida

Para conseguir isso, criamos uma infraestrutura Hollow incremental para Netflix, aproveitando o trabalho que havia sido feito na biblioteca Hollow anteriormente e sendo pioneira no uso da produção pela equipe da Streaming Platform no Target (e agora é uma API pública não beta ).

Com essa infraestrutura, cada vez que uma alteração é detectada em um aplicativo de origem, o registro atualizado é codificado e emitido para um tópico do Kafka. Um novo componente que não faz parte do aplicativo de origem, o serviço Produtor Incremental Vazio , executa um ciclo de repetição em uma cadência predefinida. Durante cada ciclo, ele lê todas as mensagens que foram adicionadas ao tópico desde o último ciclo e altera o mecanismo de estado oco para refletir o novo estado dos registros atualizados.

Se uma mensagem do tópico Kafka contiver exatamente os mesmos dados já refletidos no conjunto de dados Hollow, nenhuma ação será executada.

Serviço de Produtor Incremental Oco

Para atenuar problemas decorrentes de eventos perdidos, implementamos um mecanismo de varredura que periodicamente repete todo um conjunto de dados de origem. Como itera, emite o conteúdo de cada registro para o tópico Kafka. Desta forma, quaisquer atualizações que possam ter sido perdidas acabarão sendo refletidas no conjunto de dados Hollow. Além disso, como esse não é o mecanismo principal pelo qual as atualizações são propagadas para o conjunto de dados Hollow, isso não precisa ser executado com a mesma rapidez ou frequência que um ciclo deve iterar a origem no uso oco tradicional.

O Produtor Incremental Hollow é capaz de ler uma grande quantidade de mensagens do tópico Kafka e alterar seu estado Hollow internamente muito rapidamente – assim, podemos configurar seus tempos de ciclo para serem muito curtos (atualmente estamos padronizando isso para 30 segundos).

Foi assim que construímos uma máquina do tempo mais rápida. Agora, se o Title Operations adicionar uma classificação de maturidade a um filme, em 30 segundos, esses dados estarão disponíveis no conjunto de dados Hollow correspondente.

O resultado tangível

Com o problema de latência de propagação de dados resolvido, pudemos reimplementar o sistema do Gatekeeper para eliminar todos os limites de E / S. Com a implementação anterior do Gatekeeper, reavaliar todos os recursos para todos os vídeos em todos os países seria impensável – isso uniria todo o pipeline de conteúdo por mais de uma semana (e ainda estaríamos atrasados em uma semana, já que nada mais poderia ser processado nesse meio tempo). Agora nós reavaliamos tudo em cerca de 30 segundos – e fazemos isso a cada minuto.

Não existe mais uma avaliação de atividade perdida ou atrasada, e a desativação do sistema anterior do Gatekeeper reduziu a carga em nossos sistemas upstream – em alguns casos, em até 80%.

Redução de carga em um sistema upstream

Além desses benefícios de desempenho, também obtemos um benefício de resiliência. No sistema anterior do Gatekeeper, se um dos serviços do upstream estivesse inativo, não poderíamos avaliar a atividade, pois não é possível recuperar nenhum dado desse sistema. Na nova implementação, se um dos sistemas upstream ficar inativo, ele deixará de ser publicado, mas ainda assim, os dados obsoletos serão armazenados para o conjunto de dados correspondente, enquanto todos os outros progridem. Por exemplo, se o sistema de sinopse traduzido ficar inativo, ainda podemos trazer um filme para o site em uma região se ele foi retido e receber as legendas corretas.

O resultado intangível

Talvez ainda mais benéfico do que os ganhos de desempenho foi a melhoria em nossa velocidade de desenvolvimento neste sistema. Agora podemos desenvolver, validar e liberar alterações em minutos, o que pode ter levado dias ou semanas antes, e podemos fazê-lo com uma qualidade de liberação significativamente maior.

O aspecto da máquina do tempo do Hollow significa que todo processo determinístico que usa o Hollow exclusivamente como dados de entrada é 100% reproduzível. Para o Gatekeeper, isso significa que uma repetição exata do que aconteceu no momento X pode ser realizada revertendo todos os nossos estados de entrada para o tempo X e, em seguida, reavaliando tudo novamente.

Usamos esse fato para iterar rapidamente as alterações na lógica de negócios do Gatekeeper. Mantemos uma instância do Gatekeeper PREPROD que “segue” nossa instância do PROD Gatekeeper. O PREPROD também avalia continuamente a vitalidade de todo o catálogo, mas publica sua saída em um conjunto de dados oco diferente. No início de cada ciclo, o ambiente PREPROD reunirá o estado produzido mais recente do PROD e configurará cada um de seus conjuntos de dados de entrada para as mesmas versões exatas que foram usadas para produzir a saída do PROD.

A instância do Gatekeeper PREPROD " segue" a instância do PROD

Quando queremos fazer uma mudança na lógica de negócios do Gatekeeper, fazemos isso e depois publicamos no nosso cluster PREPROD. O estado de saída subsequente do PREPROD pode ser diferenciado com o estado de saída correspondente do PROD para visualizar o efeito preciso que a alteração lógica causará. Desta forma, num relance, podemos validar que as nossas alterações têm precisamente o efeito pretendido e zero consequências não intencionais.

Um diff oco mostra exatamente o que muda

Isso, juntamente com alguma iteração no processo de implantação, resultou na capacidade da nossa equipe de codificar, validar e implementar mudanças impactantes no Gatekeeper em literalmente minutos – pelo menos uma ordem de magnitude mais rápida do que no sistema anterior – e podemos faça isso com um nível de segurança maior do que era possível na arquitetura anterior.

Conclusão

Essa nova implementação do sistema Gatekeeper abre oportunidades para capturar o valor adicional dos negócios, que planejamos seguir nos próximos trimestres. Além disso, esse é um padrão que pode ser replicado para outros sistemas dentro do espaço de Engenharia de Conteúdo e em outros locais da Netflix – já foram lançados alguns projetos de acompanhamento para formalizar e capitalizar os benefícios dessa entrada n-oca, um arquitetura de saída de derivação.

A Engenharia de Configuração de Conteúdo é um espaço empolgante no momento, especialmente à medida que aumentamos nosso pipeline para produzir mais conteúdo a cada trimestre que passa. Temos muitas oportunidades para resolver problemas reais e fornecer valor maciço para os negócios – e para isso com um foco profundo em ciência da computação, usando e frequentemente sendo pioneiros em tecnologias de ponta. Se esse tipo de trabalho soar atraente para você, entre em contato com Ivan para dar o pontapé inicial.