A Plataforma de Experimentação da Netflix

 A Plataforma de Experimentação da Netflix

Já se perguntou como a Netflix serve uma excelente experiência de streaming de vídeo, com alta qualidade e o mínimo de interrupções na reprodução? Graças à equipe de engenheiros e cientistas de dados que aplicam testes A/B constantemente suas inovações para os nossos algoritmos de entrega de conteúdo e transmissão personalizada. E quanto a mudanças mais óbvias, como a reformulação completa do nosso layout da interface de usuário ou a nossa nova página inicial personalizada? Sim, tudo resultado de testes A/B.
Cada mudança de produto que a Netflix considera passa por um processo rigoroso de testes A/B antes de se tornar a experiência padrão do usuário. Grandes alteraçoes no design, como os acima, melhoram muito o serviço ao permitir que membros encontrem mais rápido o conteúdo que eles querem assistir. No entanto, é muito arriscado publicar este tipo de redesign sem extensos testes A/B, que permitem provar que a nova experiência é teve mais sucesso do que a anterior. E se você já se perguntou se a intenção é realmente de testar tudo o que der, saiba que até as imagens associadas com muitos títulos passaram por testes A/B, às vezes resultando em 20% a 30% a mais de visualização para esse título!
Resultados como esses demonstram por que somos fãs de carteirinha de testes A/B. Ao seguir uma abordagem empírica, garantimos que as alterações do produto não são guiadas por achismos dos funcionários da Netflix, mas por dados reais, permitindo que os nossos próprios clientes nos guiem em direção as experiências que amam.
Neste post vamos falar sobre a Plataforma de Experimentação: o serviço que torna possível para cada equipe de engenharia da Netflix implementar os seus testes A/B com o apoio de uma equipe de engenharia especializada. Vamos começar definindo um contexto de alto nível em torno de testes A/B antes de falar da arquitetura de nossa plataforma atual e como outros serviços interagem com a plataforma para trazer um teste A/B à vida.

Visão geral

O conceito geral por trás dos testes A/B é criar uma experiência com um grupo controle e um ou mais grupos experimentais (chamados de “células” dentro da Netflix) que recebem tratamentos alternativos. Cada membro pertence exclusivamente a uma célula dentro de um dado experimento e uma das células é sempre designada a “célula padrão”. Esta célula representa o grupo de controle, que recebe a mesma experiência que todos os membros da Netflix fora do teste. Assim que o teste começa a rodar, nós acompanhamos as métricas específicas de importância, geralmente (mas nem sempre) número de horas de streaming e de retenção. Uma vez que temos número suficiente de participantes para tirar conclusões estatisticamente significativas, podemos obter uma leitura sobre a eficácia de cada célula de teste e encontrar um vencedor.
Do ponto de vista do participante, cada membro é geralmente parte de vários testes A/B, em determinado momento, desde que os testes não entrem em conflito um com o outro (dois testes que modificam a mesma área de um Netflix App de diferentes maneiras) . Para ajudar os proprietários dos testes a rastrear conflitantos em potencial, nós fornecemos um test schedule view no ABlaze, o front-end da nossa plataforma. Esta ferramenta permite filtrar testes em diferentes dimensões para encontrar outros testes que podem impactar uma área semelhante a sua.
netflix-1
Há mais um tópico para resolver antes de nos aprofundarmos em detalhes: como os participantes são alocados a um determinado teste. Apoiamos duas formas primárias de alocação: lote e em tempo real.
Alocações de lote dão aos analistas a máxima flexibilidade, permitindo-lhes preencher testes usando tanto consultas personalizadas simples como complexas, conforme for necessário. Estas consultas retornam um conjunto fixo e conhecido de membros que são então adicionados ao teste. As principais desvantagens desta abordagem é que ela não tem a capacidade de alocar novos clientes e não consegue alocar com base no comportamento do usuário em tempo real. E enquanto o número de membros alocado é conhecido, não se pode garantir que todos os membros alocados vão passar pelo teste (por exemplo, se estamos testando um novo recurso em um iPhone, não podemos ter certeza de que cada participante alocado irá acessar a Netflix em um iPhone enquanto o teste estiver ativo).
Alocações em tempo real fornecem aos analistas a capacidade de configurar regras que são avaliadas conforme o usuário interage com a Netflix. Usuários elegíveis são alocados para o teste em tempo real, contanto que atendam aos critérios especificados nas normas e não estejam atualmente em um teste conflitante. Como resultado, esta abordagem supera as fraquezas inerentes à abordagem de lote. A principal desvantagem para a alocação em tempo real, no entanto, é que a aplicação incorre latências adicionais à espera de resultados de alocação. Felizmente, muitas vezes pode executar esta chamada em paralelo enquanto o aplicativo está aguardando outras informações. A questão secundária com a alocação em tempo real é a dificuldade em estimar quanto tempo levará para que o número desejado de membros seja atribuído a um teste, a fim de determinar quando eles podem avaliar os resultados.

O típico fluxo de trabalho de um teste A/B

Com esse background, já podemos mergulhar mais a fundo. O fluxo de trabalho típico envolvido na Plataforma de Experimentação (referida como A/B nos diagramas) é melhor explicado usando o seguinte fluxo de trabalho para um teste de seleção de imagens. Note-se que há nuances para o diagrama abaixo, que não serão abordadas em profundidade, em particular a arquitetura da camada API da Netflix, que atua como um gateway entre aplicativos Netflix externos e serviços internos.
Neste exemplo, nós estamos executando um teste A/B hipotético com a finalidade de encontrar a imagem que resulta em um maior número de membros assistindo a um título específico. Cada célula representa uma imagem. No diagrama também estamos assumindo um fluxo de chamadas a partir de um Netflix App sendo executado em um PS4, embora o mesmo fluxo é válido para a maioria dos nossos Device Apps.
 
netflix-2
1. O Netflix PS4 App chama a API Netflix. Como parte dessa chamada, ele oferece uma carga JSON contendo informações sobre o nível da sessão relacionadas ao usuário e seu dispositivo.
2. A chamada é processada em um script escrito pela equipe de PS4 App. Esse script é executado na Client Adaptor Layer da API Netflix, onde cada equipe de Client App acrescenta scripts relevantes para o seu app. Cada um desses scripts vêm completos com seus próprios terminais REST distintos. Isso permite que a API da Netflix possua funcionalidades comuns à maioria dos aplicativos, dando a cada app controle sobre a sua lógica específica. O PS4 App Script agora chama o A/B Client, uma biblioteca nossa equipe mantém dentro da API Netflix. Esta biblioteca permite a comunicação com nossos servidores back-end, bem como outros serviços internos da Netflix.
3. O A/B Client chama um conjunto de outros serviços para reunir contexto adicional sobre o membro e o dispositivo.
4. O A/B Client então chama o A/B Server para avaliação, passando por todo o contexto de que dispõe.
5. Na fase de avaliação:
      a. O A/B Server recupera todas as combinações de teste/célula à qual este membro já está alocado.
      b. Para os testes que utilizam a abordagem de alocação de lotes, as alocações já são conhecidas nesta fase.
      c. Para os testes que utilizam a alocação em tempo real, o A/B Server avalia o contexto para ver se o membro deve ser alocado para quaisquer testes adicionais.
      d. Uma vez que todas as avaliações e atribuições são concluídas, o A/B Server passa o conjunto completo de testes e células para o cliente A/B, que por sua vez passa para o PS4 App Script. Note que o PS4 App não tem idéia se o usuário está em um determinado teste por semanas ou só nos últimos microssegundos. Ele não precisa saber ou se preocupa com isso.
6. Dadas as combinações de teste/célula devolvidas a ele, o PS4 App Script agora atua em todos os testes aplicáveis à solicitação do cliente atual. No nosso exemplo, ele vai usar essas informações para selecionar a peça adequada de arte associada com o título ele precisa exibir, que é devolvido pelo serviço que detém esses metadados de título. Note-se que a Plataforma de Experimentação na verdade não controla este comportamento: isso é tarefa do serviço que realmente implementa cada experiência dentro de um determinado teste.
7. O PS4 App Script (através da API Netflix) “conta” à PS4 App qual imagem será exibida, juntamente com todas as outras operações que o PS4 App deve realizar, a fim de processar corretamente a interface do usuário.
Agora que entendemos o fluxo de chamadas, vamos dar uma olhada naquela rotulada “A/B Server”.

A Plataforma de Experimentação

netflix-3
Os pedidos de atribuição e recuperação descritos na seção anterior passam por terminais de API REST para o nosso servidor. Metadados de teste referentes a cada teste, incluindo regras de alocação, são armazenados em um armazenamento de dados Cassandra. São essas regras de alocação que são comparadas com o contexto passado do A/B Client, a fim de determinar a elegibilidade de um membro para participar de um teste (por exemplo, um usuário na Austrália, em um PS4, que nunca tinha usado esta versão do app PS4).
Alocações membros também são persistentes em Cassandra, liderada por uma camada de cache na forma de um cluster EVCache, que serve para reduzir o número de chamadas diretas para Cassandra. Quando um aplicativo faz uma solicitação para alocações atuais, o A/B Client verifica primeiro o EVCache para registros de alocação referentes a este membro. Se esta informação foi previamente solicitada dentro das últimas 3 horas (o TTL para o nosso cache), uma cópia das alocações será devolvida a partir do EVCache. Se não, o A/B Server faz uma chamada direta para Cassandra, passando as atribuições de volta para o A/B Client e, simultaneamente, preenchendo-as em EVCache.
Quando ocorrem alocações para um teste A/B, temos de decidir em que célula colocar cada membro. Esta etapa deve ser trabalhada com cuidado, uma vez que a população em cada célula deve ser o mais homogênea possível, a fim de tirar conclusões estatisticamente significativas a partir do teste. A homogeneidade é medida  em relação a um conjunto de dimensões fundamentais, dais que país e tipo de dispositivo (isto é, SmartTV, console de jogos, etc.) são os mais proeminentes. Consequentemente, o nosso objetivo é assegurar que cada célula contenha proporções semelhantes de membros de cada país, utilizando proporções semelhantes de cada tipo de dispositivo, etc. Uma amostragem puramente aleatória pode prejudicar os resultados do teste caso, por exemplo, aloque mais australianos usuários do console em uma célula em relação a outra. Para mitigar esse problema que empregam um método de amostragem chamado amostragem estratificada, que visa manter a homogeneidade entre os principais dimensões acima mencionadas. Há uma boa quantidade de complexidade para a nossa implementação de amostragem estratificada, que pretendemos compartilhar em um futuro post.
Na etapa final do processo de atribuição, nós persistimos detalhes de alocação em Cassandra e invalidamos os caches A/B associados a este membro. Como resultado, na próxima vez que receber um pedido de alocação referente a este membro, vamos experimentar uma perda de cache e executar os passos relacionados a cache descritos acima.
Também publicamos simultaneamente eventos de alocação a um pipeline de dados Kafka, que alimenta em vários armazenamentos de dados. O fed publicado em tabelas Hive fornece uma fonte de dados para análise ad-hoc, bem como Ignite, a ferramnta interna da Netflix para visualização e análise de testes A/B. É dentro do Ignite que os proprietários de teste analisam métricas de interesse e avaliar os resultados de um teste. Este assunto vai render outro post, focado em Ignite, no futuro próximo.
As atualizações mais recentes para na nossa tecnologia faísca acrescentaram o Spark Streaming, que ingere e transforma dados de Kafka streams antes de persisti-los em ElasticSearch, o que nos permite exibir perto de atualizações em tempo real no ABlaze. Nossos atuais casos de uso envolvem métricas simples, permitindo aos utilizadores visualizar as alocações de teste em tempo real através das dimensões de interesse. No entanto, estas adições têm lançado os alicerces para análises em tempo real muito mais sofisticadas no futuro próximo.

Projetos futuros

A arquitetura que descrevemos aqui tem funcionado bem para nós até agora. Continuamos a dar suporte a um conjunto cada vez maior de domínios: UI, recomendações, playback, busca, e-mail, assinatura e muitos mais. Através de auto-scaling, lidamos tranquilamente com o tráfego normal da nossa plataforma, que varia de 150K a 450K pedidos por segundo. Do ponto de vista responsivo, latências que buscam a alocações existentes variam de uma média de 8 ms quando o nosso cache é frio para <1ms quando o cache é quente. avaliações em tempo real demorar um pouco mais, com uma latência média de cerca de 50ms.
No entanto, como nossa base de membros continua a se expandir globalmente, a velocidade e a variedade de testes A/B está crescendo rapidamente. Só para contextualizar, a arquitetura geral que acabamos de descrever já era usada desde 2010 (com algumas exceções óbvias, como Kafka). Desde então:
      – A Netflix cresceu de streaming em 2 países para mais de 190
      – Passamos de 10 milhões de membros para mais de 80 milhões
      – Fomos de dezenas de dispositivos a milhares, muitos deles com seu próprio app Netflix
A expansão internacional é parte da razão pela qual estamos vendo um aumento nos tipos de dispositivos. Em particular, há um aumento no número de dispositivos móveis usados para transmitir Netflix. Nesta arena, contamos com alocações de lote, como a nossa atual abordagem de alocação em tempo real simplesmente não funciona: a largura de banda em dispositivos móveis não é confiável o suficiente para uma aplicação esperar por nós antes de decidir qual experiência servir … tudo isso enquanto o usuário está impaciente olhando para uma tela de carregamento.
Além disso, algumas novas áreas de inovação conduzem testes A/B em um tempo muito mais curto do que antes. Testes focados em mudanças de interface do usuário, algoritmos de recomendação, etc. muitas vezes correm por semanas antes que seus efeitos sobre o comportamento do usuário possam ser medidos com clareza. No entanto, os testes de streaming adaptativo mencionados no início deste post são realizadas em uma questão de horas.
Como resultado, existem vários aspectos da nossa arquitetura que estamos planejando reformular significativamente. Por exemplo, enquanto o mecanismo de atribuição em tempo real permite o controle granular, as avaliações precisam ser mais rápidas e devem interagir mais eficientemente com dispositivos móveis.
Nós também planejamos alavancar os dados que fluem através do Spark Streaming para começar a prever taxas de alocação por teste, dadas as regras de alocação. O objetivo é resolver a segunda principal desvantagem da abordagem de atribuição em tempo real, que é a incapacidade de prever a quantidade de tempo necessária para obter membros suficientes alocados no teste. Dando analistas a capacidade de prever as taxas de alocação vai permitir um planejamento e coordenação de testes mais precisos.
Estes são apenas alguns dos nossos próximos desafios. Se você está simplesmente curioso para saber mais sobre como lidamos com eles, fique atento para os próximos posts. No entanto, se a idéia de resolver estes desafios e nos ajudar a construir a próxima geração de plataforma de experimentação da Netflix te excita, sinta-se livre para falar conosco!
Texto original, por Steve Urban, Rangarajan Sreenivasan e Vineet Kannan.
Adaptação e tradução: Maria Sebastiany
 

douglasgarcia96

Deixe uma resposta

Se inscreva para receber nossas novidades.
%d blogueiros gostam disto: