A Plataforma de Experimentação da Netflix

[:pt]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
 [:en]Ever wonder how Netflix serves a great streaming experience with high-quality video and minimal playback interruptions? Thank the team of engineers and data scientists who constantly A/B test their innovations to our adaptive streaming and content delivery network algorithms. What about more obvious changes, such as the complete redesign of our UI layout or our new personalized homepage? Yes, all thoroughly A/B tested.
In fact, every product change Netflix considers goes through a rigorous A/B testing process before becoming the default user experience. Major redesigns like the ones above greatly improve our service by allowing members to find the content they want to watch faster. However, they are too risky to roll out without extensive A/B testing, which enables us to prove that the new experience is preferred over the old. And if you ever wonder whether we really set out to test everything possible, consider that even the images associated with many titles are A/B tested, sometimes resulting in 20% to 30% more viewing for that title!
Results like these highlight why we are so obsessed with A/B testing. By following an empirical approach, we ensure that product changes are not driven by the most opinionated and vocal Netflix employees, but instead by actual data, allowing our members themselves to guide us toward the experiences they love.
In this post we’re going to discuss the Experimentation Platform: the service which makes it possible for every Netflix engineering team to implement their A/B tests with the support of a specialized engineering team. We’ll start by setting some high level context around A/B testing before covering the architecture of our current platform and how other services interact with it to bring an A/B test to life.

Overview

The general concept behind A/B testing is to create an experiment with a control group and one or more experimental groups (called “cells” within Netflix) which receive alternative treatments. Each member belongs exclusively to one cell within a given experiment, with one of the cells always designated the “default cell”. This cell represents the control group, which receives the same experience as all Netflix members not in the test. As soon as the test is live, we track specific metrics of importance, typically (but not always) streaming hours and retention. Once we have enough participants to draw statistically meaningful conclusions, we can get a read on the efficacy of each test cell and hopefully find a winner.
From the participant’s point of view, each member is usually part of several A/B tests at any given time, provided that none of those tests conflict with one another (i.e. two tests which modify the same area of a Netflix App in different ways). To help test owners track down potentially conflicting tests, we provide them with a test schedule view in ABlaze, the front end to our platform. This tool lets them filter tests across different dimensions to find other tests which may impact an area similar to their own.
netflix-1
There is one more topic to address before we dive further into details, and that is how members get allocated to a given test. We support two primary forms of allocation: batch and real-time.
Batch allocations give analysts the ultimate flexibility, allowing them to populate tests using custom queries as simple or complex as required. These queries resolve to a fixed and known set of members which are then added to the test. The main cons of this approach are that it lacks the ability to allocate brand new customers and cannot allocate based on real-time user behavior. And while the number of members allocated is known, one cannot guarantee that all allocated members will experience the test (e.g. if we’re testing a new feature on an iPhone, we cannot be certain that each allocated member will access Netflix on an iPhone while the test is active).
Real-Time allocations provide analysts with the ability to configure rules which are evaluated as the user interacts with Netflix. Eligible users are allocated to the test in real-time if they meet the criteria specified in the rules and are not currently in a conflicting test. As a result, this approach tackles the weaknesses inherent with the batch approach. The primary downside to real-time allocation, however, is that the calling app incurs additional latencies waiting for allocation results. Fortunately we can often run this call in parallel while the app is waiting on other information. A secondary issue with real-time allocation is that it is difficult to estimate how long it will take for the desired number of members to get allocated to a test, information which analysts need in order to determine how soon they can evaluate the results of a test.

A Typical A/B Test Workflow

With that background, we’re ready to dive deeper. The typical workflow involved in calling the Experimentation Platform (referred to as A/B in the diagrams for shorthand) is best explained using the following workflow for an Image Selection test. Note that there are nuances to the diagram below which I do not address in depth, in particular the architecture of the Netflix API layer which acts as a gateway between external Netflix apps and internal services.
In this example, we’re running a hypothetical A/B test with the purpose of finding the image which results in the greatest number of members watching a specific title. Each cell represents a candidate image. In the diagram we’re also assuming a call flow from a Netflix App running on a PS4, although the same flow is valid for most of our Device Apps.
netflix-2

  1. The Netflix PS4 App calls the Netflix API. As part of this call, it delivers a JSON payload containing session level information related to the user and their device.
  2. The call is processed in a script written by the PS4 App team. This script runs in the Client Adaptor Layer of the Netflix API, where each Client App team adds scripts relevant to their app. Each of these scripts come complete with their own distinct REST endpoints. This allows the Netflix API to own functionality common to most apps, while giving each app control over logic specific to them. The PS4 App Script now calls the A/B Client, a library our team maintains, and which is packaged within the Netflix API. This library allows for communication with our backend servers as well as other internal Netflix services.
  3. The A/B Client calls a set of other services to gather additional context about the member and the device.
  4. The A/B Client then calls the A/B Server for evaluation, passing along all the context available to it.
  5. In the evaluation phase:
    1. The A/B Server retrieves all test/cell combinations to which this member is already allocated.
    2. For tests utilizing the batch allocation approach, the allocations are already known at this stage.
    3. For tests utilizing real-time allocation, the A/B Server evaluates the context to see if the member should be allocated to any additional tests. If so, they are allocated.
    4. Once all evaluations and allocations are complete, the A/B Server passes the complete set of tests and cells to the A/B Client, which in turn passes them to the PS4 App Script. Note that the PS4 App has no idea if the user has been in a given test for weeks or the last few microseconds. It doesn’t need to know or care about this.
  6. Given the test/cell combinations returned to it, the PS4 App Script now acts on any tests applicable to the current client request. In our example, it will use this information to select the appropriate piece of art associated with the title it needs to display, which is returned by the service which owns this title metadata. Note that the Experimentation Platform does not actually control this behavior: doing so is up to the service which actually implements each experience within a given test.
  7. The PS4 App Script (through the Netflix API) tells the PS4 App which image to display, along with all the other operations the PS4 App must conduct in order to correctly render the UI.

Now that we understand the call flow, let’s take a closer look at that box labelled “A/B Server”.

The Experimentation Platform

netflix-3
The allocation and retrieval requests described in the previous section pass through REST API endpoints to our server. Test metadata pertaining to each test, including allocation rules, are stored in a Cassandra data store. It is these allocation rules which are compared to context passed from the A/B Client in order to determine a member’s eligibility to participate in a test (e.g. is this user in Australia, on a PS4, and has never previously used this version of the PS4 app).
Member allocations are also persisted in Cassandra, fronted by a caching layer in the form of an EVCache cluster, which serves to reduce the number of direct calls to Cassandra. When an app makes a request for current allocations, the AB Client first checks EVCache for allocation records pertaining to this member. If this information was previously requested within the last 3 hours (the TTL for our cache), a copy of the allocations will be returned from EVCache. If not, the AB Server makes a direct call to Cassandra, passing the allocations back to the AB Client, while simultaneously populating them in EVCache.
When allocations to an A/B test occur, we need to decide the cell in which to place each member. This step must be handled carefully, since the populations in each cell should be as homogeneous as possible in order to draw statistically meaningful conclusions from the test. Homogeneity is measured with respect to a set of key dimensions, of which country and device type (i.e. smart TV, game console, etc.) are the most prominent. Consequently, our goal is to make sure each cell contains similar proportions of members from each country, using similar proportions of each device type, etc. Purely random sampling can bias test results by, for instance, allocating more Australian game console users in one cell versus another. To mitigate this issue we employ a sampling method called stratified sampling, which aims to maintain homogeneity across the aforementioned key dimensions. There is a fair amount of complexity to our implementation of stratified sampling, which we plan to share in a future blog post.
In the final step of the allocation process, we persist allocation details in Cassandra and invalidate the A/B caches associated with this member. As a result, the next time we receive a request for allocations pertaining to this member, we will experience a cache miss and execute the cache related steps described above.
We also simultaneously publish allocation events to a Kafka data pipeline, which feeds into several data stores. The feed published to Hive tables provides a source of data for ad-hoc analysis, as well as Ignite, Netflix’s internal A/B Testing visualization and analysis tool. It is within Ignite that test owners analyze metrics of interest and evaluate the results of a test. Once again, you should expect an upcoming blog post focused on Ignite in the near future.
The latest updates to our tech stack added Spark Streaming, which ingests and transforms data from Kafka streams before persisting them in ElasticSearch, allowing us to display near real-time updates in ABlaze. Our current use cases involve simple metrics, allowing users to view test allocations in real-time across dimensions of interest. However, these additions have laid the foundation for much more sophisticated real-time analysis in the near future.

Upcoming Work

The architecture we’ve described here has worked well for us thus far. We continue to support an ever-widening set of domains: UI, Recommendations, Playback, Search, Email, Registration, and many more. Through auto-scaling we easily handle our platform’s typical traffic, which ranges from 150K to 450K requests per second. From a responsiveness standpoint, latencies fetching existing allocations range from an average of 8ms when our cache is cold to < 1ms when the cache is warm. Real-time evaluations take a bit longer, with an average latency around 50ms.
However, as our member base continues to expand globally, the speed and variety of A/B testing is growing rapidly. For some background, the general architecture we just described has been around since 2010 (with some obvious exceptions such as Kafka). Since then:

  • Netflix has grown from streaming in 2 countries to 190+
  • We’ve gone from 10+ million members to 80+ million
  • We went from dozens of devices to thousands, many with their own Netflix app

International expansion is part of the reason we’re seeing an increase in device types. In particular, there is an increase in the number of mobile devices used to stream Netflix. In this arena, we rely on batch allocations, as our current real-time allocation approach simply doesn’t work: the bandwidth on mobile devices is not reliable enough for an app to wait on us before deciding which experience to serve… all while the user is impatiently staring at a loading screen.
Additionally, some new areas of innovation conduct A/B testing on much shorter time horizons than before. Tests focused on UI changes, recommendation algorithms, etc. often run for weeks before clear effects on user behavior can be measured. However the adaptive streaming tests mentioned at the beginning of this post are conducted in a matter of hours, with internal users requiring immediate turn around time on results.
As a result, there are several aspects of our architecture which we are planning to revamp significantly. For example, while the real-time allocation mechanism allows for granular control, evaluations need to be faster and must interact more effectively with mobile devices.
We also plan to leverage the data flowing through Spark Streaming to begin forecasting per-test allocation rates given allocation rules. The goal is to address the second major drawback of the real-time allocation approach, which is an inability to foresee how much time is required to get enough members allocated to the test. Giving analysts the ability to predict allocation rates will allow for more accurate planning and coordination of tests.
These are just a couple of our upcoming challenges. If you’re simply curious to learn more about how we tackle them, stay tuned for upcoming blog posts. However, if the idea of solving these challenges and helping us build the next generation of Netflix’s Experimentation platform excites you, feel free to reach out to us!
Originally posted on http://techblog.netflix.com/2016/04/its-all-about-testing-netflix.html by Steve Urban, Rangarajan Sreenivasan, and Vineet Kannan.[:es]Ya se preguntó cómo Netflix brinda una excelente experiencia de streaming de video, con alta calidad y con el mínimo de interrupciones en la reproducción? Gracias al equipo de ingenieros y científicos de datos que aplican pruebas A/B constantemente a sus innovaciones para nuestros algoritmos de entrega de contenido y transmisión personalizada. Y en cuanto a los cambios más obvios, como la reformulación completa de nuestro layout de la interfaz de usuario o de nuestra nueva página inicial personalizada? Sí, todo es resultado de pruebas A/B.
Cada cambio de producto que Netflix considera pasa por un proceso riguroso de pruebas A/B antes de pasar a ser la experiencia padrón del usuario. Grandes alteraciones en el diseño, como los de arriba, mejoran mucho el servicio al permitir que miembros encuentren más rápido el contenido que ellos quieren ver. Sin embargo, es muy arriesgado publicar este tipo de rediseño sin extensas pruebas A/B, que permiten probar que la nueva experiencia tuvo más éxito que la anterior. Y si usted ya se preguntó si la intención es realmente probar todo lo que se pueda, sepa que hasta las imágenes asociadas con muchos títulos pasaron por pruebas A/B, a veces resultando de 20% a 30% más de visualización para ese título!
Resultados como estos demuestran porque somos fanáticos de las pruebas A/B. Al seguir un camino empírico, podemos garantizar que las modificaciones del producto no son guiadas por adivinanzas de los funcionarios de Netflix, y si por datos reales, permitiendo que nuestros propios clientes nos guíen en dirección de las experiencias que ellos aman.
En este post vamos a hablar sobre la Plataforma de Experimentos: el servicio que hace posible para cada equipo de ingeniería de Netflix implementar sus pruebas A/B con el apoyo de un equipo de ingeniería especializada. Vamos a comenzar definiendo un contexto de alto nivel en torno a las pruebas A/B antes de hablar de arquitectura de nuestra plataforma actual y como otros servicios se integran con la plataforma para traer una prueba A/B a la vida.

Visión General

El concepto general detrás de las pruebas A/B es crear un experimento con un grupo control y uno o más grupos experimentales (llamadas “células” dentro de Netflix) que reciben tratamientos alternativos. Cada miembro pertenece exclusivamente a una célula dentro de un experimento dado y una célula siempre que se conoce como “célula estándar”. Esta célula es el grupo de control, recibiendo la misma experiencia que todos los miembros de Netflix fuera de la prueba. Una vez que la prueba comienza a correr, seguimos las métricas específicas de más importancia, por lo general (pero no siempre) horas de streaming y retención. Una vez que tenemos suficientes participantes para sacar conclusiones estadísticamente significativas, podemos obtener una lectura sobre la efectividad de cada célula de prueba y encontrar un ganador.
Desde el punto de vista del participante, cada miembro es generalmente parte de varias pruebas A/B en un momento dado, siempre que las pruebas no entren en conflicto entre sí (dos pruebas que modifiquen la misma área de una aplicación de Netflix de diferentes maneras). Para ayudar a los propietarios a rastrear conflictos potenciales, ofrecemos un programa de pruebas schedule view en ABlaze, o front-end de nuestra plataforma. Esta herramienta le permite filtrar las pruebas en diferentes dimensiones para encontrar otras pruebas que pueden afectar a un área similar.
netflix-1
Hay un tema más para resolver antes de profundizar en los detalles: cómo los participantes se asignan a una prueba en particular. Se admiten dos formas principales de asignación: por lotes y en tiempo real.
Las asignaciones del lote dan a los analistas la máxima flexibilidad, lo que les permite completar las pruebas tanto con las consultas personalizadas simples como con las complejas, conforme sea necesario. Estas consultas devuelven un conjunto fijo y conocido de los miembros que se añaden a la prueba. Las principales desventajas de este enfoque es que no tiene la capacidad de asignar nuevos clientes y no puede asignar basándose en el comportamiento del usuario en tiempo real. Y si bien se conoce el número de miembros asignados, no podemos garantizar que todos los miembros asignados pasará la prueba (por ejemplo, si estamos probando una nueva característica en un iPhone, no podemos estar seguros de que cada participante asignado accederá al Netflix en un iPhone mientras la prueba está activa).
Asignaciones en tiempo real, proporcionan a los analistas la capacidad de configurar las reglas que se evalúan conforme el usuario interactúa con Netflix. Usuarios aceptados se incluyen en la prueba en tiempo real, siempre que cumplan los criterios especificados en las reglas y no se encuentren actualmente en una prueba en conflicto. Como resultado, este enfoque supera las debilidades inherentes en el enfoque por lotes. La principal desventaja para la asignación en tiempo real, sin embargo, es que la aplicación incurre en latencia adicional esperando los resultados de asignación. Afortunadamente, a menudo se puede realizar esta llamada en paralelo mientras la aplicación está esperando otra información. Una cuestión secundaria con la asignación en tiempo real es que es difícil estimar cuánto tiempo tomará para que el número necesario de miembros sea asignado a una prueba con el fin de determinar el momento en que puedan evaluar los resultados.

El típico flujo de trabajo de una prueba A/B

Con este background ya podemos hacer un análisis más profundo. El flujo de trabajo típico que participa la Plataforma de Experimentación (referida como A/B en los diagramas) se explica mejor con el siguiente flujo de trabajo a una prueba de selección de imágenes. Tenga en cuenta que hay matices en el siguiente diagrama, que no se tratará en profundidad, sobre todo la arquitectura de la capa API de Netflix, que actúa como puerta de enlace entre las aplicaciones externas de Netflix y servicios internos.
En este ejemplo, estamos ejecutando una prueba A/B hipotética con el fin de encontrar la imagen que se traduce en un mayor número de miembros que asisten un título específico. Cada celda representa una imagen. En el diagrama también estamos dando un flujo de llamadas a partir de un Netflix App siendo ejecutado en un PS4, aún que el mismo flujo es válido para la mayoría de nuestros Device Apps.
netflix-2

  1. 1. La aplicación de Netflix PS4 llama a la API de Netflix. Como parte de esta convocatoria, que proporciona una carga JSON que contiene información sobre el nivel de sesión relacionada con el usuario y el dispositivo.
  1. La llamada se procesa en un script escrito por el equipo de PS4 App. Este script se ejecuta en el Client Adaptor Layer de la API de Netflix, donde cada equipo de Client App agrega secuencias de comandos relevantes para su aplicación. Cada uno de estos scripts viene completo con sus propios terminales REST distintos. Esto permite que la API de Netflix tenga funcionalidad común a la mayoría de aplicaciones, dando a cada control sobre su aplicación lógica específica. La aplicación de secuencias de comandos PS4 ahora llama al Cliente A/B, una biblioteca de nuestro equipo se mantiene dentro de la API de Netflix. Esta biblioteca permite la comunicación con nuestros servidores de back-end, así como otros servicios internos de Netflix.
  1. El A/B Client llama a una serie de otros servicios para reunir un contexto adicional sobre el miembro y el dispositivo.
  1. El A/B Client llama al A/B Server para evaluación, pasando por todo el contexto del mismo.
  1. En la fase de evaluación:
  2.       El A/B Server recupera todas las combinaciones de prueba/célula a la que ya ha sido asignado a este miembro.
  3.       Para las pruebas utilizando el enfoque de asignación de lotes, las asignaciones son ya conocidas en esta etapa.
  4.       Para los ensayos que utilizan la asignación en tiempo real, el A/B Server evalúa el contexto para ver si el miembro ha de ser beneficiario de cualquier prueba adicional.
  5.       Una vez que todas las evaluaciones y tareas se han completado, el A/B Server pasa el conjunto completo de células de ensayo y para el A/B Client, que a su vez pasa a la secuencia de comandos de la PS4 App. Tenga en cuenta que la PS4 App tiene ni idea de si el usuario está en una prueba en particular durante semanas o sólo en los últimos microsegundos. Él no necesita saber o preocuparse por eso.
  1. Dada las combinaciones de prueba/célula devueltas a él, el PS4 App Script ahora funciona en todas las pruebas aplicables a la solicitud del cliente actual. En nuestro ejemplo, se utilizará esta información para seleccionar la pieza apropiada de arte asociado con el título tiene que mostrar, que es devuelto por el servicio que lleva a cabo tales metadatos título. Tenga en cuenta que la Plataforma de Experimentación en realidad no controla este comportamiento: esta es la misión de servicio que se ajusta en realidad cada experiencia dentro de una prueba en particular.
  1. El PS4 App Script (a través de la API Netflix) “dice” a la PS4 App cuál imagen se mostrará, junto con todas las demás operaciones que la App PS4 debe llevar a cabo con el fin de procesar correctamente la interfaz de usuario.

Ahora que entendemos el flujo de llamadas, vamos a echar un vistazo a lo que conocemos por “A/B Server”.

La Plataforma de Experimentación

netflix-3
Las solicitudes de asignación y recuperación descritos en la sección anterior pasan por los terminales de API REST para nuestro servidor. Metadatos de ensayo para cada prueba, incluyendo las reglas de asignación, se almacenan en un almacén de datos Cassandra.Son estas reglas de asignación que se comparan con el pasado contexto del A/B Client con el fin de determinar la elegibilidad de un miembro de participar en un test (por ejemplo, un usuario en Australia con una PS4 que nunca había utilizado esta versión de la aplicación para PS4).
Asignaciones de los miembros también son persistentes en Cassandra, dirigidas por una capa de almacenamiento en caché en forma de un cluster EVCache, que sirve para reducir el número de llamadas directas a Cassandra. Cuando una aplicación realiza una solicitud para asignaciones actuales, el A/B Client busca primero en el EVCache por los registros de asignación de este usuario. Si esta información ha sido solicitada previamente en las últimas 3 horas (TTL para nuestro caché), una copia de las asignaciones se volvió de EVCache. Si no es así, el A/B del servidor hace una llamada directa a Cassandra, pasando asignaciones de nuevo a la A/B de cliente y, simultáneamente, llenándolas en EVCache.
Cuando hay asignaciones para la prueba A/B, tenemos que decidir en qué célula colocar cada miembro. Este paso debe ser trabajado con cuidado, ya que la población en cada célula debe ser lo más homogénea posible con el fin de sacar conclusiones estadísticamente significativas del teste. La homogeneidad se mide en relación a un conjunto de cuestiones fundamentales, tales como país y tipo de dispositivo (es decir, Smart TV, consola de juegos, etc.) son los más destacados. En consecuencia, nuestro objetivo es asegurar que cada célula contiene una proporción similar de miembros de cada país, utilizando proporciones similares de cada tipo de dispositivo, etc. Un muestreo puramente aleatorio puede deteriorar los resultados de la prueba si, por ejemplo, asignar más usuarios de la consola de Australia en una célula con respecto a otra. Para mitigar este problema se emplea un método de muestreo llamado muestreo estratificado, que tiene como objetivo mantener la homogeneidad entre las principales dimensiones antes mencionadas. Hay una buena cantidad de complejidad a nuestra aplicación muestra estratificada, que tenemos la intención de compartir en un futuro post.
En el último paso del proceso de asignación, persistimos detalles de asignación de Cassandra y invalidamos los cachés A/B asociada a este miembro. Como resultado, la próxima vez que reciba una solicitud de asignación en relación con esta persona, vamos a experimentar una pérdida de memoria caché y ejecutar las etapas relacionadas con la memoria caché que describimos anteriormente.
También publicamos simultáneamente eventos de asignación a una pipeline de datos Kafka, que se alimenta de múltiples almacenes de datos. El feed publicado en las tablas Hive proporciona una fuente de datos para el análisis ad-hoc y Ignite, la herramienta interna de Netflix para la visualización y análisis de tests A/B. Es dentro de Ignite que los propietarios de prueba analizan las métricas y evalúan los resultados de una prueba. Este tema dará otro post centrado en Ignite en un futuro próximo.
Los últimos cambios en nuestra tecnología han añadido Spark Streaming, que ingiere y transforma los flujos de datos Kafka antes de ellos persisten en ElasticSearch, que nos permite mostrar actualizaciones casi en tiempo real en ABlaze. Nuestros casos de uso actuales implican métricas simples, lo que permite a los usuarios ver las asignaciones de prueba en tiempo real a través de las dimensiones de interés. Sin embargo, estas adiciones han sentado las bases para un análisis en tiempo real mucho más sofisticado en un futuro próximo.

Proyectos futuros

La arquitectura descrita aquí ha funcionado bien para nosotros hasta ahora. Seguimos apoyando un número creciente de áreas: la interfaz de usuario, recomendaciones, reproducción, búsqueda, e-mail, subscription y muchos más. A través del auto-scaling, lidiamos sin problemas con el tráfico normal de nuestra plataforma, que va desde 150K a 450K solicitudes por segundo. Del punto de vista responsivo, latencias que buscan asignaciones existentes varían de un promedio de 8 ms cuando nuestro caché es frío a <1 ms, cuando la caché está caliente. Las calificaciones en tiempo real tardan un poco más, con una latencia media de alrededor de 50 ms.
Sin embargo, como nuestra base de miembros continúa ampliando de manera global, la velocidad y el alcance de las pruebas A/B está creciendo rápidamente. Sólo para contextualizar, la arquitectura general que acabamos de describir ya fue utilizada desde 2010 (con algunas excepciones obvias, como Kafka). Desde entonces:
     – Netflix creció de streaming en dos países a más de 190
     – Hemos pasado de 10 millones de miembros a más de 80 millones
     – Pasamos de docenas de dispositivos de miles de personas, muchas de ellas con su propia aplicación de Netflix
La expansión internacional es parte de la razón por la que estamos viendo un aumento en los tipos de dispositivos. En particular, hay un aumento en el número de dispositivos móviles utilizados para transmitir Netflix. En este escenario, tenemos gran cantidad de asignaciones, como nuestro enfoque actual de asignación en tiempo real simplemente no funciona: el ancho de banda en los dispositivos móviles no es lo suficientemente confiable para una aplicación que nos espere antes de decidir lo que la experiencia sirva todo esto … mientras el usuario está impaciente mirando a una pantalla de carga.
Por otra parte, algunas nuevas áreas de innovación resultado de pruebas A/B en un tiempo mucho más corto que antes. Pruebas centradas en los cambios en la interfaz de usuario, algoritmos de recomendación y otros a menudo corren por semanas antes de que  se pueda medir con claridad sus efectos sobre el comportamiento de los usuarios. Sin embargo, las pruebas de adaptación de streaming mencionados anteriormente en esta entrada se llevan a cabo en cuestión de horas.
Como resultado, hay varios aspectos de nuestra arquitectura que estamos planeando para renovar de manera significativa. Por ejemplo, mientras que el mecanismo de asignación en tiempo real permite un control granular, las evaluaciones tienen que ser más rápidas y deben interactuar de manera más eficiente con los dispositivos móviles.
 
También tenemos la intención de aprovechar los datos que fluyen a través del Spark Streaming para comenzar a predecir tasas de asignación de testes, teniendo en cuenta las reglas de asignación. El objetivo es resolver la segunda principal desventaja del enfoque de atribución en tiempo real, que es la incapacidad de predecir la cantidad de tiempo necesario para obtener suficientes miembros asignados en el teste. Dar a los analistas la capacidad de predecir las tasas de asignación permitirá la planificación y coordinación de testes con más precisión.
Estos son sólo algunos de nuestros próximos desafíos. Si usted está simplemente curioso por saber más acerca de cómo trataremos con ellos, permanezca atento a las próximas entradas. Sin embargo, si la idea de resolver estos retos y ayudar a construir la siguiente generación de plataforma de ensayos Netflix te excita, no dude en ponerse en contacto con nosotros!
Texto original por Steve Urbano, Rangarajan Sreenivasan y Vineet Kannan.
 [:]