Introdução à camada de abstração de dados TimeSeries da Netflix
(netflixtechblog.com)- Com a expansão da Netflix para áreas como VoD e Gaming, tornou-se essencial a capacidade de armazenar e processar grandes volumes de dados temporais, na escala de petabytes, com latência de milissegundos.
- Com base na abstração de Key-Value e na plataforma Data Gateway, a empresa desenvolveu a abstração TimeSeries para oferecer uma solução capaz de armazenar e consultar com eficiência dados de eventos temporais em vários casos de uso.
Desafios
- Na Netflix, dados temporais são continuamente gerados e usados em interações de usuários, exposição de assets e atividades de redes complexas de microsserviços.
- Gerenciar esses dados de forma eficaz é essencial para garantir a experiência do usuário e a confiabilidade do sistema.
- Principais desafios:
- Alta vazão: é necessário lidar com até 10 milhões de gravações por segundo mantendo alta disponibilidade.
- Consultas eficientes em conjuntos de dados de grande escala: é preciso armazenar dados em escala de petabytes, retornar leituras por chave principal em poucos milissegundos e oferecer suporte a busca e agregação por vários atributos secundários.
- Leitura e escrita globais: é necessário suportar operações de leitura e escrita em qualquer lugar do mundo, com modelos de consistência ajustáveis.
- Configuração ajustável: é preciso oferecer a capacidade de particionar conjuntos de dados em armazenamentos single-tenant ou multi-tenant.
- Tratamento de tráfego em rajadas: é necessário gerenciar picos de tráfego em lançamentos de novos conteúdos ou em recuperação de falhas regionais.
- Eficiência de custos: é preciso minimizar os custos de infraestrutura ao mesmo tempo em que se otimiza a retenção de longo prazo.
Abstração TimeSeries
- Particionamento de dados: usa uma estratégia própria de particionamento temporal e uma abordagem de event buckets para lidar com cargas em rajada de forma eficiente e simplificar consultas.
- Armazenamento flexível: foi projetada para integrar-se a diferentes backends de armazenamento, como Apache Cassandra e Elasticsearch.
- Configurabilidade: oferece várias opções ajustáveis por dataset, dando flexibilidade para se adaptar a diferentes casos de uso.
- Escalabilidade: suporta escalabilidade horizontal e vertical para lidar com o aumento de throughput e volume de dados conforme crescem a base de usuários e os serviços da Netflix.
- Infraestrutura de shards: aproveita a Data Gateway Platform para implantar infraestrutura single-tenant e/ou multi-tenant com o nível necessário de isolamento de acesso e tráfego.
Modelo de dados
- Segue um modelo de dados de eventos específico que encapsula os dados de evento para permitir consultas eficientes.
- Event item: um event item é um par chave-valor usado pelo usuário para armazenar dados de um evento específico. Ex.: {"device_type": "ios"}
- Evento: um evento é uma coleção estruturada composta por um ou mais event items. O evento ocorre em um ponto específico no tempo e é identificado por um timestamp gerado no cliente e por um identificador de evento, como um UUID. A combinação de event_time e event_id forma parte de uma chave de idempotência única do evento, permitindo que o usuário refaça a requisição com segurança
- ID de série temporal: time_series_id é um conjunto de um ou mais eventos ocorridos durante o período de retenção de um dataset. Por exemplo, device_id armazena todos os eventos ocorridos em um dispositivo específico durante esse período. Todos os eventos são imutáveis, e o serviço TimeSeries apenas acrescenta eventos ao ID de série temporal fornecido
- Namespace: um namespace é uma coleção de IDs de série temporal e dados de eventos, representando o dataset completo de TimeSeries. O usuário pode criar um ou mais namespaces para cada caso de uso. A abstração aplica várias opções ajustáveis no nível do namespace
API
- WriteEventRecordsSync: esse endpoint grava um lote de eventos e retorna ao cliente uma confirmação de durabilidade. É usado quando o usuário exige garantia de durabilidade
- WriteEventRecords: esta é a versão fire-and-forget do endpoint acima. Ele apenas enfileira o lote de eventos sem confirmação de durabilidade. É usado em casos como logging ou tracing, quando o usuário prioriza throughput e pode tolerar alguma perda de dados
- ReadEventRecords: dado um namespace, timeSeriesId, timeInterval e eventFilters opcionais, este endpoint retorna todos os eventos correspondentes em ordem decrescente por event_time, com baixa latência de milissegundos
- SearchEventRecords: dado um critério de busca e um intervalo de tempo, este endpoint retorna todos os eventos correspondentes. Esses casos de uso se encaixam bem em leituras eventualmente consistentes
- AggregateEventRecords: dado um critério de busca e um modo de agregação, como DistinctAggregation, este endpoint executa a agregação especificada dentro do intervalo de tempo fornecido. Assim como no endpoint Search, o usuário pode aceitar consistência eventual e latência potencialmente mais alta, na casa de segundos
Camada de armazenamento
- A camada de armazenamento do TimeSeries é composta por um data store primário e um data store de índice opcional.
- Apache Cassandra é preferido como data store para garantir durabilidade em cenários de alta vazão.
- Elasticsearch é preferido como data store para indexação.
Data store primário
- Usa Apache Cassandra para lidar com os casos de uso do TimeSeries.
- Gerencia os dados com particionamento temporal, dividindo-os em chunks conforme o intervalo de tempo
- Fatia temporal: mapeada para uma tabela do Cassandra correspondente ao período de retenção
- Time bucket: reparticiona os dados dentro da fatia temporal para otimizar consultas por intervalos específicos
- Event bucket: reparticiona novamente o time bucket para lidar com grandes volumes de escrita em séries temporais em curtos períodos
- A tabela de dados armazena os dados reais dos eventos, e a tabela de metadados armazena informações de configuração de fatias temporais por namespace
Data store de índice
- Para suportar padrões de acesso secundários por atributos que não são chave primária, os dados são indexados no Elasticsearch.
- O usuário pode configurar, por namespace, a lista de atributos que serão usados para busca e agregação.
Plano de controle
- O plano de dados lida com operações de leitura e escrita, enquanto o plano de controle configura todos os aspectos do comportamento dos namespaces
- O plano de dados se comunica com a pilha de controle do TimeSeries, que por sua vez interage com o plano de controle do Data Gateway
- A configuração de namespaces permite ajustar com flexibilidade vários aspectos, como particionamento temporal, buffering, consistência e retenção
Configuração de namespace
- Por meio de snippets de configuração que mostram a flexibilidade do serviço, é possível ajustar vários elementos por namespace.
Provisionamento de infraestrutura
- Considerando vários parâmetros, a configuração ideal é derivada por meio de um workflow automatizado de provisionamento.
- O sistema provisiona a infraestrutura inicial e depois escala de acordo com a carga de trabalho do usuário.
Escalabilidade
- Como a previsão de uso inicial é limitada no momento do provisionamento, ajustes posteriores são necessários
- Escalabilidade horizontal: as instâncias do servidor TimeSeries escalam automaticamente para cima ou para baixo conforme a demanda de tráfego.
- Escalabilidade vertical: as instâncias do servidor TimeSeries ou de armazenamento podem ser ampliadas verticalmente para obter mais CPU, RAM e/ou capacidade de armazenamento anexado.
- Expansão de disco: é possível anexar EBS para armazenar dados e expandir o volume EBS quando o uso de disco atinge determinados limites.
- Reparticionamento de dados para ajustar datasets superparticionados ou subparticionados
Princípios de projeto
- Idempotência de eventos: a idempotência é incorporada em todos os endpoints de mutação para permitir que o usuário repita requisições com segurança.
- Hedging baseado em SLO: metas de objetivo de nível de serviço (SLO) são atribuídas a diferentes endpoints para garantir desempenho.
- Retorno parcial: se o cliente for sensível à latência, ele pode aceitar conjuntos de resultados parciais.
- Paginação adaptativa: quando a camada de serviço determina que um dataset de série temporal é denso, ela ajusta dinamicamente o fator de fan-out.
- Janela de escrita limitada: os dados se tornam imutáveis o mais rápido possível para permitir a aplicação de otimizações.
- Buffering de escrita: para lidar com cargas em rajada, os eventos são mesclados por um curto período para distribuir a carga de forma mais uniforme.
- Compactação dinâmica: quando os dados se tornam imutáveis, estratégias de compactação são usadas para otimizar o desempenho de leitura.
Desempenho real
- O serviço consegue gravar dados com latência de poucos milissegundos e manter latência estável em leituras pontuais.
Uso do TimeSeries na Netflix
A abstração TimeSeries desempenha um papel importante nos principais serviços da Netflix. Alguns casos de uso de destaque incluem:
- Tracing e insights: realiza rastreamento de logs em todos os apps e microsserviços da Netflix para entender a comunicação entre serviços, ajudar na depuração de problemas e responder a solicitações de suporte
- Rastreamento de interações do usuário: acompanha milhões de interações de usuários, como reprodução de vídeo, buscas e engajamento com conteúdo, para melhorar em tempo real os algoritmos de recomendação da Netflix e gerar insights que aprimoram a experiência geral
- Lançamento de funcionalidades e análise de desempenho: acompanha o lançamento e o desempenho de novos recursos de produto, permitindo que os engenheiros da Netflix meçam como os usuários interagem com esses recursos, apoiando decisões orientadas por dados para melhorias futuras
- Rastreamento e otimização de impressões de assets: monitora a exposição de assets para garantir que conteúdos e assets sejam entregues de forma eficiente, ao mesmo tempo em que fornece feedback em tempo real para otimização
- Cobrança e gestão de assinaturas: armazena dados históricos relacionados a cobrança e gerenciamento de assinaturas para garantir a precisão dos registros de transações e dar suporte a atendimentos ao cliente
Melhorias futuras
À medida que os casos de uso evoluem e cresce a necessidade de tornar a abstração ainda mais eficiente em custos, a Netflix planeja melhorar bastante o serviço nos próximos meses. Algumas dessas melhorias incluem:
- Armazenamento em camadas para eficiência de custos: suporte para mover dados antigos e menos acessados para object storage mais barato, com maior tempo até o first byte, o que pode economizar milhões de dólares para a Netflix
- Event bucketing dinâmico: em vez de ter uma configuração um tanto estática ao provisionar um namespace, a ideia é suportar o particionamento em tempo real das chaves em partições de tamanho ideal à medida que os eventos são transmitidos. Essa estratégia tem a grande vantagem de reduzir o custo total de amplificação de leitura ao não particionar
time_series_idque não precisam de particionamento. Além disso, no Cassandra 4.x há melhorias importantes na leitura de subconjuntos de dados em partições amplas, o que pode reduzir a necessidade de particionar agressivamente todo o dataset antecipadamente - Caching: uso da imutabilidade dos dados para fazer cache de forma inteligente para intervalos de tempo individuais
- Contagens e outras agregações: alguns usuários estão interessados apenas na contagem de eventos em um determinado intervalo de tempo, em vez de recuperar todos os dados de eventos
Conclusão
- A abstração TimeSeries é um componente crítico da infraestrutura de dados online da Netflix, apoiando decisões em tempo real e de longo prazo.
- À medida que a Netflix se expande para novas áreas, a abstração TimeSeries continuará sendo um elemento central da plataforma, contribuindo para ampliar as possibilidades do streaming e além dele
Opinião do GN⁺
- É impressionante o know-how da Netflix para processar com estabilidade enormes volumes de dados de séries temporais, garantindo ao mesmo tempo escalabilidade, flexibilidade e eficiência de custos por meio da abstração TimeSeries. Em especial, chamam atenção técnicas otimizadas para as características dos dados e os padrões de acesso, como particionamento temporal, buffering de escrita e compactação dinâmica
- Não se trata apenas de um banco de dados de séries temporais, mas de uma camada de abstração que permite usar com flexibilidade diferentes armazenamentos, como Cassandra e Elasticsearch, além de contar com um sistema de controle capaz de provisionar e operar a infraestrutura de acordo com as características da carga de trabalho. Com a abstração, o usuário pode ocultar a complexidade e se concentrar nos dados
- Atualmente, o sistema já acomoda dados em escala de petabytes e apresenta desempenho de 15 milhões de eventos por segundo, o que o torna uma referência para empresas que desejam construir pipelines de dados de séries temporais de alto desempenho. Isso sugere que, em serviços de grande escala, é preciso considerar de forma integrada não apenas volume e velocidade dos dados, mas também o custo
- Ele é usado de várias formas em áreas centrais do negócio da Netflix, como tracing, análise de comportamento do usuário e gestão de cobrança, mostrando que dados de séries temporais são a força motriz por trás de decisões orientadas por dados e inovação em serviços. Não é apenas logging: também serve de base para serviços em tempo real apoiados por ML/AI, como recomendações
- Os planos de melhoria futura, incluindo armazenamento em camadas, particionamento dinâmico e operações de agregação, mostram a intenção de evoluir continuamente. Para responder a demandas de negócios em rápida mudança, esse tipo de inovação constante parece indispensável. Fica a expectativa de que o know-how acumulado nesse processo venha a ser compartilhado por meio de open source e outros meios
Ainda não há comentários.