26 pontos por xguru 2023-11-27 | Ainda não há comentários. | Compartilhar no WhatsApp
  • O futuro dos serviços de dados em nuvem está em uma arquitetura de "grande escala e multi-tenant"
    • O motivo pelo qual serviços SaaS de primeira linha como o S3 oferecem simplicidade, confiabilidade, durabilidade, escalabilidade e baixo custo é que suas tecnologias foram estruturalmente projetadas para fornecer essas características
    • Prestar serviços aos clientes por meio de grandes pools de recursos garante eficiência e confiabilidade em escala

[Definição de sistemas serverless multi-tenant (Serverless Multi Tenant)]

Definição de "Multi-Tenancy"

  • Multi-tenancy diz respeito ao compartilhamento de recursos por meio da colocação conjunta de cargas de trabalho em hardware compartilhado
  • Construir sistemas na nuvem significa que vários tenants são atendidos em instâncias de computação compartilhadas (por exemplo, Amazon EC2 ou Google Compute) ou em serviços PaaS compartilhados (por exemplo, armazenamento de objetos em nuvem)
  • Multi-tenancy é definido como "prestar serviço a vários tenants em recursos compartilhados (como servidores virtualizados, discos e serviços básicos de PaaS)"
  • É possível usar vários modelos de compartilhamento de recursos, e alguns sistemas combinam vários deles em diferentes componentes
    • Processo compartilhado: o mesmo processo de software atende vários tenants. O isolamento de dados e segurança é lógico
    • Contêineres: executam um nó de tenant único e empacotam vários contêineres por host. Em geral isso é feito por meio do Kubernetes, em que um nó específico de K8s hospeda pods de vários tenants
    • Virtualização: executa um nó de tenant único em uma VM (por exemplo, QEMU) ou microVM (por exemplo, Firecracker) e empacota várias VMs por host. O Kubernetes também pode ser usado com VMs por meio do Kata Containers
  • Também existe um método de isolamento do V8 em que os tenants podem compartilhar o mesmo processo do V8 em contextos leves separados, mas ainda não vi isso em sistemas de dados

Definição de serverless

  • O cliente não escolhe o tipo de servidor nem seleciona explicitamente o hardware
  • Esses sistemas dependem de certo nível de elasticidade e mobilidade para lidar com a demanda de todas as cargas de trabalho sem que o cliente precise ajustar explicitamente o tamanho do hardware
    • Elasticidade: capacidade de expandir/reduzir o serviço e escalar para cima/baixo conforme a necessidade da carga de trabalho
    • Mobilidade: capacidade do serviço de mover e balancear internamente as cargas de trabalho para atender aos requisitos de desempenho e estabilidade
  • O modelo serverless usa cobrança por uso, algo cada vez mais importante para os clientes
    • Muitos clientes não querem assumir grandes compromissos antecipados e preferem simplesmente pagar pelo que usarem
    • A cobrança por uso tem várias variações que dependem bastante da carga de trabalho e da implementação do sistema subjacente
      • Pagamento por (milhão de) operações
      • Pagamento pelo uso de CPU e memória da carga de trabalho
      • Pagamento por GB de armazenamento
      • Pagamento por unidades virtuais de desempenho/capacidade relacionadas a recursos e taxa de operação (por exemplo, RCU/WCU do DynamoDB)
      • Modelos híbridos em que o cliente paga por certa capacidade base e pelo uso que exceder esse nível ("pague a base, pague o pico")

[Desafios em comum]

Trabalhar dentro das restrições impostas pela carga de trabalho

  • Muitas das restrições impostas pela carga de trabalho de um sistema de dados específico são direcionadores importantes da arquitetura subjacente
    • Requisitos de latência/disponibilidade
    • Requisitos de consistência
    • Correlação/dependência entre requisições e dados
    • Padrões de acesso sequencial vs. acesso aleatório
    • Variedade do trabalho executado por requisição
    • Tamanho dos dados
    • Protocolos orientados a sessão vs. orientados a requisição, mecanismos push vs. pull
    • Intensidade computacional do trabalho
  • Requisitos mais flexíveis de latência e consistência dão mais liberdade aos engenheiros
    • Um bom exemplo é aproveitar o baixo custo e a alta durabilidade do armazenamento de objetos em nuvem, algo que em sistemas de baixa latência é limitado pela introdução de componentes com maior latência
    • Sistemas com consistência eventual podem evitar esse dilema gravando os dados de forma assíncrona no armazenamento de objetos, sem incluí-lo no caminho crítico síncrono de dados
    • Sistemas com baixa latência e consistência forte não têm esse tipo de carta na manga
  • Quando restrições como baixa latência se combinam, a localidade espacial e temporal da carga de trabalho pode influenciar as escolhas de arquitetura
    • Por exemplo, em cargas de trabalho caracterizadas por varreduras sequenciais, é melhor manter intervalos contíguos de dados juntos para permitir scans rápidos e eficientes em disco
    • Subdividir esses intervalos em subintervalos menores ajuda a lidar com hotspots, mas essas duas coisas entram em conflito, então é preciso encontrar um equilíbrio
    • Padrões de acesso aleatório com pouca correlação entre requisições individuais podem se beneficiar de um espaço de endereçamento plano que pode ser distribuído de forma uniforme e fina entre vários servidores
  • Protocolos orientados a sessão, que estabelecem conexões persistentes, em geral são mais difíceis do que protocolos orientados a requisição, em que cada requisição é independente da anterior
    • Conexões persistentes podem exigir connection pooling, e perturbações como rolling de nós e balanceamento de dados podem ter impactos visíveis externamente para o cliente
  • Existem sistemas com APIs simples de armazenamento, como object storage ou a API do Kafka, e também sistemas intensivos em computação, como bancos de dados SQL
    • Isso leva ao tema da previsibilidade e da variabilidade da quantidade de trabalho necessária para processar cada requisição
    • Em um extremo há APIs de streaming de dados como o Kafka, que precisam apenas recuperar blocos contíguos de registros; no outro extremo está o SQL, em que cada consulta pode gerar grandes diferenças na carga de trabalho

Isolamento entre tenants

  • O compartilhamento de recursos aumenta a utilização do hardware, mas pode gerar contenção de recursos em que a carga de trabalho de um tenant afeta outros tenants
  • Em sistemas multi-tenant, deve-se garantir que tenants atendidos em recursos de hardware compartilhados se comportem como se estivessem sendo atendidos por um serviço dedicado próprio

Separação entre storage e compute

  • A separação entre storage e compute é um princípio central de projeto implementado, em algum grau, por todos os sistemas analisados até agora
  • Devido às tendências de hardware, essa separação está se tornando cada vez mais viável, em parte porque a rede já não representa o mesmo gargalo de antes
  • A vazão de rede está aumentando, mas ainda há novos desafios nessa separação, especialmente porque o armazenamento de objetos em nuvem passa a ter papel central
    • O armazenamento de objetos em nuvem ainda tem latência relativamente alta, excelente durabilidade e baixo custo
    • Mas pode ser difícil introduzi-lo em cargas de trabalho normalmente de baixa latência, como bancos de dados OLTP
    • Além disso, o modelo econômico do armazenamento de objetos em nuvem desfavorece arquiteturas que dependem de muitos objetos pequenos, exigindo a agregação de dados em objetos maiores com menos requisições, o que complica ainda mais a vida de sistemas de baixa latência
  • Engenheiros podem incluir armazenamento de objetos em sistemas de baixa latência e mitigar o problema de latência colocando, à frente do object storage lento, um cache de escrita durável e tolerante a falhas, além de um cache de leitura preditivo
    • Esse cache de escrita durável é, basicamente, um cluster de servidores que implementa um protocolo de replicação e grava dados em block storage
      • Em segundo plano, o cluster faz upload assíncrono dos dados para o armazenamento de objetos seguindo um padrão econômico de gravar um número menor de arquivos grandes
      • Um cache de escrita tolerante a falhas atende bem escritas de baixa latência
    • O que pode ser problemático nessa arquitetura é o cache de leitura
      • Cargas de trabalho sequenciais, como event streaming, são simples e muito eficazes
      • Desde que o Aggregate Prefetching acompanhe a demanda, as leituras devem sempre atingir o cache de leitura local
      • Bancos de dados têm um problema mais difícil por causa de padrões de acesso aleatório difíceis de prever, embora table scans ainda possam se beneficiar de leitura antecipada
  • Implementar um cache de escrita distribuído e tolerante a falhas com protocolo de replicação não é algo simples, e em ambientes multi-AZ podem surgir outros custos, como tarifas de tráfego entre AZs
    • Mas, por enquanto, não há alternativa para sistemas de baixa latência que desejam usar armazenamento de objetos barato e durável como repositório principal de dados
    • Outros sistemas de baixa latência devem evitar completamente o uso de armazenamento de objetos em nuvem, priorizando acima de tudo latência curta e previsível
    • O armazenamento em nuvem é amplamente usado, mas não é universal por causa dos trade-offs de latência

Gerenciamento de calor

  • Gerenciamento de calor consiste em distribuir a carga da forma mais uniforme possível entre vários nós de armazenamento para evitar hotspots que possam causar problemas de desempenho visíveis externamente, como picos de latência ou queda no número de operações por segundo
  • Isso também poderia ser chamado de balanceamento de carga, mas normalmente o termo load balancer é usado para nós stateless
  • Em sistemas stateful, podem surgir hotspots quando objetos com alta demanda ficam agrupados em nós de armazenamento específicos, gerando contenção
  • Um load balancer pode distribuir uniformemente a carga entre um conjunto de nós stateless com estratégias simples como aleatória, least connections ou alguma variação de FIFO, mas sistemas stateful precisam rotear as requisições para os nós com base em onde os dados estão
  • Mover dados para redistribuir carga é comumente chamado de rebalancing
  • Um problema ainda mais complexo é que a distribuição de carga pode mudar ao longo do tempo
    • A distribuição de dados torna-se um processo dinâmico que precisa lidar com tudo, desde picos de curto prazo que afetam pequenos subconjuntos de dados até mudanças maiores de carga causadas por padrões diários ou eventos sazonais em vários tenants
  • Conjuntos de dados grandes, como grandes bancos de dados ou streams de eventos de alta vazão, precisam ser fragmentados (sharding) para distribuir a carga com eficácia
    • O rebalancing passa a ser o rebalanceamento de shards, e o sistema também pode dividir e mesclar shards conforme a distribuição de carga muda
    • No entanto, pode haver trade-offs, como localidade de dados, relacionados ao número e ao tamanho dos shards
    • Por um lado, quanto mais co-localização de dados houver, mais eficiente será a recuperação
    • Por outro lado, o custo de tarefas computacionais que precisam buscar dados em shards demais pode superar os benefícios obtidos ao distribuir a carga por mais servidores
  • Gerenciamento de calor também pode ser necessário em sistemas single-tenant, então não é um problema exclusivo de multi-tenancy
    • No entanto, em sistemas de dados MT, ele se torna ainda mais importante para garantir que os tenants não sofram variações na qualidade do serviço

Alcançar alta utilização de recursos

  • Um dos principais motivos para implementar uma arquitetura serverless multi-tenant é oferecer melhor eficiência econômica por meio do uso mais eficiente dos recursos de hardware subjacentes
  • Aumentar a utilização dos recursos por meio de pooling é o mais importante, mas alcançar isso com isolamento entre tenants e desempenho previsível é um desafio difícil

Cold start

  • Sistemas serverless que escalam os recursos até zero por tenant podem enfrentar o problema de cold start quando o tenant retoma sua carga de trabalho
  • Cold start tem sido um foco desde o início das funções serverless e também pode afetar alguns sistemas de dados serverless
  • Em alguns sistemas, o cold start não acontece de forma alguma, enquanto em outros ele é inevitável por causa da arquitetura e da oferta de produto com scale to zero
  • Em todos os casos que vi, o problema de cold start é uma decisão de produto, e o nível de redução de recursos pode variar conforme o plano e o modelo de precificação
  • No fim, clientes e fornecedores podem escolher os trade-offs que melhor atendem às suas necessidades

Sistemas analisados

  • Group 1 - Storage APIs (compute-light)
    • Amazon DynamoDB (chapter 1)
    • Kora - Serverless Kafka engine inside Confluent Cloud (chapter 2)
    • Backblaze B2 (planned)
  • Group 2 - SQL OLTP databases (compute-heavy)
    • Neon - serverless PostgreSQL (chapter 3)
    • CockroachDB’s serverless multi-tenant architecture. (in progress)
    • Planetscale (planned)
  • Group 3 - SQL OLAP databases and data warehouses (compute-heavy)
    • Google BigQuery (planned)
    • ClickHouse Cloud (in progress).
  • Este trabalho continuará, mas está previsto algum tipo de postagem de "conclusão" em janeiro/fevereiro de 2024

Ainda não há comentários.

Ainda não há comentários.