Dispositivos de IO e latência
(planetscale.com)- O armazenamento não volátil evoluiu de fita para HDD, SSD e armazenamento em nuvem via rede, mas a localização e o posicionamento dos dados ainda determinam a latência de IO
- Armazenamento em fita é forte em leitura e gravação sequenciais, mas pode levar dezenas de segundos para ler dados distantes, o que o torna inadequado para bancos de dados transacionais de alto tráfego
- HDDs reduziram muito a latência em relação à fita, mas, por causa dos pratos giratórios e do movimento da cabeça, leituras aleatórias costumam ficar na faixa de 1~3ms, e o desempenho varia bastante conforme a ordem das requisições
- SSDs operam com NAND flash sem componentes mecânicos, então leituras aleatórias podem chegar a 16μs, mas o posicionamento dos dados continua importante por causa do uso de paralelismo e da garbage collection
- A separação entre storage e compute na nuvem facilita escalabilidade e resposta a falhas, mas adiciona ida e volta de rede e limites de IOPS; o PlanetScale Metal busca reduzir esse custo com NVMe SSD conectado diretamente e replicação
Elementos básicos que determinam a latência do armazenamento
- Armazenamento não volátil preserva dados mesmo quando a energia é desligada e é a base para guardar dados como fotos, e-mails, saldos bancários e registros médicos
- Armazenamento volátil, como registradores da CPU, cache da CPU e RAM, é mais rápido, mas precisa de energia contínua
- O desempenho do armazenamento não depende só da capacidade, mas também de como se chega aos dados, da unidade de leitura e gravação, de enfileiramento, paralelismo e da existência ou não de ida e volta pela rede
- Com o lançamento do PlanetScale Metal, a PlanetScale afirmou que o Metal executa bancos de dados em nuvem com drives NVMe locais em vez de armazenamento conectado por rede
Armazenamento em fita: forte em acesso sequencial, fraco em acesso aleatório
- Computadores usam unidades de fita como armazenamento digital não volátil desde os anos 1950
- Um cartucho de fita é composto por várias trilhas e muitas células, e o estado de polarização magnética de cada célula representa dados binários
- Ao inserir o cartucho no leitor e rebobiná-lo com um motor, a IO head lê os dados que passam por ela
- Se a posição de leitura ou gravação estiver perto da cabeça, o acesso é rápido; se estiver longe, a latência aumenta
- Mesmo em sistemas modernos de fita, pode ser necessário rebobinar centenas de metros para ler dados distantes
- Nesses casos, a leitura pode levar dezenas de segundos
- Mesmo com a mesma quantidade de leituras e gravações, se os dados estiverem espalhados, leva muito mais tempo do que em um arranjo sequencial
- O exemplo do artigo mostra uma situação em que leituras e gravações dispersas levam cerca de 7 vezes mais tempo para a mesma carga de trabalho
- Fita tem latência ruim para leituras e gravações aleatórias, mas ainda é adequada para leituras e gravações sequenciais longas
- O custo por GB é menor que o de SSDs e HDDs, e a vida útil de armazenamento é longa
- O CERN gerencia mais de 400PB de dados em um data warehouse de armazenamento em fita
- A AWS também oferece serviço de arquivamento em fita
- Fita não é adequada para bancos de dados transacionais de alto tráfego
HDD: o compromisso entre discos giratórios e enfileiramento de comandos
- HDDs armazenam dados em pratos metálicos circulares em vez de fita
- Os pratos giram rapidamente dentro do gabinete, e 7200 RPM é apresentado como uma velocidade comum
- As trilhas de um HDD são circulares, e um único disco pode ter mais de 100.000 trilhas
- Cada trilha contém centenas de milhares de páginas, e cada página armazena cerca de 4KB de dados
- O HDD ajusta a posição de leitura e gravação por meio do movimento da cabeça e da rotação dos pratos
- Diferentemente da fita, os bits de toda a superfície estão sempre acessíveis
- Não é preciso rebobinar a fita até o dado desejado aparecer
- Uma leitura aleatória típica pode ser feita em 1~3ms
- A ordem das requisições tem grande impacto no desempenho
- Leituras e gravações com alta sequencialidade terminam rapidamente
- Mesmo com as mesmas 6 leituras e gravações, se a ordem estiver embaralhada, aumenta o tempo de espera até o prato chegar à posição correta
- Discos magnéticos suportam command queuing há muito tempo
- O SCSI oferece recursos relacionados desde os anos 1980, e o SATA desde os anos 2000
- O sistema operacional pode enviar vários comandos para execução em paralelo ou fora de ordem
- O controlador do disco pode usar a fila de trabalho para agendar leituras e gravações de acordo com a estrutura física do disco
- HDDs melhoraram muito em relação à fita, mas ainda podem ser lentos, especialmente em leituras e gravações aleatórias
SSD: variáveis de desempenho que continuam mesmo sem peças mecânicas
- SSDs ou armazenamento flash foram inventados nos anos 1980, mas só se tornaram predominantes no mercado consumidor nos anos 2000
- SSDs não dependem de componentes mecânicos para ler dados
- Eles usam transistores não voláteis NAND flash
- 1s e 0s são lidos, gravados e apagados por sinais elétricos, sem mover partes físicas
- Um SSD é composto por um ou mais targets, e cada target contém vários blocks, enquanto cada block contém várias pages
- SSDs leem e gravam em unidades de page
- Mesmo que só parte dos dados seja necessária, a unidade de requisição do drive é a page
- Na configuração de exemplo, se uma page tiver 4096 bits, um block tiver 16K pages, um target tiver 16K blocks e o dispositivo tiver 8 targets, o total será
4k * 16k * 16k * 8 = 8,796,093,022,208bits, ou 8TB - Leituras aleatórias em SSD podem chegar a 16μs, dependendo do modelo
- Mesmo sem componentes mecânicos, o posicionamento dos dados continua importante
- Entre os fatores de desempenho do SSD estão paralelismo e garbage collection
Paralelismo em SSD: distribuir entre targets muda o throughput
- Em geral, cada target tem uma line dedicada conectada à unidade de controle
- Cada line processa leituras e gravações, mas só pode transferir uma page por vez
- A transferência de page é muito rápida, mas ainda leva um pequeno tempo
- Se 8 gravações forem distribuídas entre 4 targets, é possível usar 4 lines em paralelo e concluir em dois intervalos de tempo
- Se as 8 gravações ficarem concentradas no mesmo target, só uma line será usada e as demais ficarão ociosas
- A ordem de leitura e gravação, bem como o posicionamento dos dados, também afetam o desempenho em SSDs
- Ao projetar software como o MySQL, é preciso prestar atenção em como os dados são armazenados em estruturas e como são posicionados no disco
Garbage collection em SSD: o custo de apagar antes de gravar
- Uma page de SSD pode ser lida várias vezes, mas, depois de gravada, não pode ser sobrescrita com novos dados até que os dados existentes sejam explicitamente apagados
- Não é possível apagar uma page individualmente; é preciso apagar o block inteiro
- SSDs precisam de algoritmos internos para gerenciar pages vazias, em uso e dirty
- Uma dirty page é uma page que foi gravada, mas cujos dados já não são mais necessários e está pronta para ser apagada
- Em alguns casos, é preciso realocar dados para receber novas gravações, e o algoritmo que gerencia isso é o garbage collector
- Se houver pages unused suficientes, novos dados podem ser gravados imediatamente
- Se faltarem pages unused e houver muitas dirty pages, a garbage collection precisa ser executada primeiro
- No exemplo, 2 pages não dirty são movidas para outro lugar para permitir a gravação de 5 novas pages
- Depois disso, todas as pages daquele target passam para estado dirty, permitindo o apagamento
- Essas etapas extras podem desacelerar muito o desempenho de gravação
- Em SSDs ocupados, com muitas leituras, gravações e exclusões, a garbage collection pode tornar outras operações mais lentas
A mudança adicionada pela nuvem: separação entre storage e compute
- A transição de fita para HDD e SSD aumentou muito o desempenho de IO durável
- A migração para a nuvem trouxe outra mudança no desempenho de IO
- A AWS é apresentada como o serviço que mais difundiu essa migração para a nuvem desde seu lançamento em 2006
- Em ambientes de nuvem, usuários alugam servidores virtualizados sobre hardware arbitrário em grandes data centers
- Esses servidores podem ser encerrados a qualquer momento por vários motivos, como falha de hardware, substituição ou interrupção de rede
- Ao construir sistemas sobre infraestrutura de nuvem alugada, é preciso tolerar falhas mais frequentes
- Essas condições, junto com a necessidade de volumes de armazenamento dinamicamente escaláveis, levaram à separação entre storage e compute
Vantagens e custos do armazenamento conectado por rede
- Tradicionalmente, servidores, desktops, notebooks e celulares conectam armazenamento não volátil diretamente
- São usados cabos SATA, interface PCIe ou integração no mesmo SoC
- O armazenamento conectado diretamente é rápido, mas tem duas limitações
- Se o servidor cair, os dados também ficam indisponíveis
- O tamanho do armazenamento é fixo
- Servidores de aplicação geralmente se adaptam bem a ambientes temporários (ephemeral), e muito do trabalho acontece em memória, então isso não costuma ser um grande problema
- Bancos de dados não podem perder dados quando o servidor cai, e o volume de dados pode crescer rapidamente até atingir o limite de armazenamento
- Muitos provedores de nuvem permitem anexar armazenamento conectado por rede, configurado separadamente, a instâncias de compute
- A configuração padrão do EC2 normalmente usa volumes de armazenamento em rede EBS
- Serviços de banco de dados como Amazon RDS, Amazon Aurora, Google Cloud SQL e PlanetScale também dependem de sistemas em que compute e storage são separados pela rede
- Essa abordagem permite ajustar dinamicamente os volumes de armazenamento conforme os dados aumentam ou diminuem
- Mesmo que o servidor caia, os dados permanecem seguros e podem ser anexados novamente a outro servidor
- Em contrapartida, há um custo de desempenho em forma de ida e volta de rede e limites de IOPS
Diferença de latência entre NVMe local e armazenamento em rede
- Um NVMe SSD conectado diretamente é um SSD que usa a especificação Non-Volatile Memory Host Controller Interface para oferecer alta velocidade de IO e largura de banda
- A ida e volta entre CPU e RAM é apresentada como cerca de 100ns
- A ida e volta entre CPU e um NVMe SSD localmente conectado é de cerca de 50.000ns, ou 50μs
- Um volume de armazenamento conectado por rede exige uma curta ida e volta de rede dentro do data center
- Armazenamento conectado por rede como o EBS é apresentado com ida e volta de cerca de 250.000ns, ou 250μs ou 0.25ms
- Mesmo usando o mesmo SSD moderno, a conexão em rede faz com que o tempo para processar cada requisição individual de leitura ou gravação seja várias vezes maior
- Em IO sequencial em grande volume, o impacto negativo pode ser reduzido, mas não eliminado
- O armazenamento conectado por rede cria latência adicional toda vez que o sistema de storage é acessado
Limites de IOPS e a diferença do armazenamento conectado diretamente
- Muitos provedores de nuvem, incluindo AWS e Google Cloud, limitam o número de operações de IO que podem ser enviadas pelo wire no modelo de armazenamento conectado por rede
- Instâncias Amazon GP3 EBS permitem por padrão 3000 IOPS por segundo
- É possível configurar valores maiores, mas isso tem custo extra
- Volumes GP2 EBS mais antigos funcionavam acumulando um pool de IOPS para permitir bursts ocasionais
- Quando o armazenamento é conectado diretamente à instância de compute, não há limite artificial de operações de IO
- Em conexão direta, é possível ler e gravar tanto quanto o hardware permitir
Como manter durabilidade e escalabilidade
- No SSD conectado diretamente, o problema 1, durabilidade dos dados, pode ser resolvido com replicação
- A abordagem comum é ter um servidor como primary recebendo todas as requisições de gravação, enquanto 2 ou mais servidores adicionais recebem réplicas dos dados
- Se os dados estiverem em três lugares, a chance de perda de dados fica pequena
- Assumindo, no exemplo, uma probabilidade mensal de falha de servidor de 1%:
- Em um único servidor, a probabilidade de perda de dados por mês é de 1%
- Em três servidores, isso cai para
1% × 1% × 1% = 0.0001%, ou seja, uma em um milhão
- A PlanetScale detecta e substitui automaticamente nós com falha e faz backups frequentes e confiáveis dos dados do banco
- O problema 2, escalabilidade do drive, exige mais intervenção manual
- É preciso monitoramento e alertas quando o disco se aproxima do limite de capacidade
- São necessárias ferramentas para aumentar a capacidade com facilidade quando preciso
A abordagem do PlanetScale Metal
- O Metal oferece clusters de banco de dados que usam NVMe SSD conectado diretamente
- Cada instância de banco de dados roda em direct-attached NVMe SSD
- Um cluster Metal é composto por padrão de 1 primary e 2 replicas
- Os clusters de banco de dados suportados são Vitess ou Postgres
- Quando o limite de armazenamento é atingido, é possível redimensionar para um servidor com drives maiores com apenas alguns cliques
- Internamente, um novo nó é iniciado e os dados são migrados da instância existente para a nova instância, e esse processo ocorre com zero downtime
- Bancos de dados Metal não têm cap artificial de IOPS
- Usuários podem executar operações de IO com baixa latência e usar tudo o que o hardware permitir, sem pagar por classes caras de IOPS do provedor de nuvem nem sofrer throttle
1 comentários
Opiniões no Hacker News
Sou o autor do blog. Foi muito divertido escrever este texto, e ele foi de longe o mais complexo que já produzi até agora
Para criar as visualizações interativas, escrevi literalmente milhares de linhas de JavaScript, então espero que todos se divirtam vendo
Porém, a expressão “1 em 1 milhão” para durabilidade me parece pessimista demais, considerando que o tempo de falha até um novo servidor entrar e replicar de novo é curto
Por exemplo, se a recuperação leva 10 minutos, mesmo que três servidores necessariamente falhem uma vez por mês, a probabilidade de todos falharem ao mesmo tempo já deve ficar por volta de 1 em 2 milhões; se a probabilidade mensal de falha for 1%, a chance de as três falhas se sobreporem fica extremamente baixa
Estou acrescentando isso porque, se você tem 1 milhão de clientes, 1 em 1 milhão não é um número tão bom assim
Sei que o tempo batendo no teclado e o tempo pensando sobre isso são bem diferentes
Conheço muito bem esse assunto, então não tenho nada a acrescentar ao conteúdo em si, e numa olhada rápida parece bom. Mas estou planejando animações para o meu blog e não gostei de algumas bibliotecas que experimentei recentemente
Por um tempo, venho defendendo a combinação SQLite+NVMe. Pessoalmente, ela me parece um novo padrão que permite ir muito mais longe do que o habitual e, em alguns casos, aguentar até o fim sem escalabilidade horizontal
Em desempenho, latência é rei, especialmente quando os itens precisam ser processados em série. Rodar SQLite sobre NVMe dá uma vantagem de latência que outros provedores não conseguem oferecer
Também não acho que, na maioria dos casos de uso reais, executar em memória seja muito melhor do que armazenamento persistente em NVMe
Em um único host pode ser um pouco mais rápido, mas, no momento em que você passa de 1 para 2 servidores web e ambos precisam escrever no banco de dados, parece que você está dificultando a própria vida
Dizer que latência é importante também pode ser enganoso. Sem consistência, desempenho não significa nada, e, assim que há vários servidores web, você precisa resolver essa consistência por conta própria
Além disso, a latência do banco de dados costuma ser muito menor do que a latência de ida e volta pela internet, e essa latência da internet também é pequena em comparação com a “latência” de esperar o carregamento de assets da página, como imagens ou bibliotecas de código
Para começar, consultas serializadas ao banco de dados devem ser evitadas ao máximo; quando possível, use joins e, quando não for possível, dispare as consultas de forma assíncrona e simultânea tanto quanto der, para que sejam executadas em paralelo
Para evitar o problema de escritas paralelas, além de configurar um modo específico e meio tosco de operação, dá para usar o truque de ter uma única thread dedicada a escritas na aplicação
Aí um código paralelo que já é complexo normalmente fica um pouco mais complexo. Com uma única thread de escrita, o SQLite funciona muito bem
fsync()em um arquivo num sistema de arquivos ext4 em um computador desktop, mesmo em discos NVMe ainda se mede latência de 1 a 2 msEm sistemas mais recentes, ficou em cerca de 800 µs
A quantidade de informação era tão boa que eu li esquecendo completamente que era promoção de produto. A visualização e a interatividade são excelentes
A animação de I/O de disco me fez lembrar de Melvin Kaye
Mel não usava loops de atraso de tempo nem quando a lenta Flexowriter precisava de uma pausa entre caracteres de saída
Em vez disso, ele ajustava a posição das instruções no tambor para que, sempre que a próxima instrução fosse necessária, a cabeça de leitura tivesse acabado de passar por ela, e o tambor precisasse dar mais uma volta para encontrar a próxima instrução
https://pages.cs.wisc.edu/~markhill/cs354/Fall2008/notes/The...
Metal parece realmente incrível, mas, quando usei SSD local de instância do GCP em um emprego anterior, tivemos problemas sérios de confiabilidade, como blocos do dispositivo perdendo dados
Fico curioso para saber se a situação mudou agora e que tipo de máquina vocês usam
Na época, o contorno foi este: https://discord.com/blog/how-discord-supercharges-network-di...
Ainda assim, operamos um sistema redundante com replicação semissíncrona do MySQL, para que todas as escritas sejam persistidas em duas máquinas em zonas de disponibilidade diferentes antes de serem confirmadas ao cliente
Um operador do Kubernetes e o processo
vtorcdo Vitess trabalham juntos para detectar e substituir ativamente réplicas com falha ou suspeitasNo GCP, tivemos os melhores resultados com máquinas n2d-highmem e, na AWS, usamos de modo geral os tipos de geração mais recente que têm instance store
Ótimo texto. Em geral, também existe o problema de o armazenamento em nuvem ser excepcionalmente lento
Isso já foi tratado em outros lugares, mas este texto resume bem o problema: http://databasearchitects.blogspot.com/2024/02/ssds-have-bec...
Recentemente, em https://github.com/feldera/feldera, foi adicionado suporte para armazenar índices incrementais em S3/armazenamento de objetos; NVMe já era suportado há mais tempo pelos benefícios óbvios de desempenho mencionados no texto anterior
Seria bom se alguém sacudisse essa área com uma forma melhor de oferecer isso
Há um ponto sobre armazenamento distribuído que não foi suficientemente avaliado neste texto
Primeiro, alguns sistemas não oferecem replicação por padrão. Um cluster Cassandra ou MySQL pode fazer replicação mestre-escravo, mas muitos sistemas não
Segundo, ao usar armazenamento NVMe na nuvem, é preciso se preocupar com janelas de manutenção e drains iniciados pela nuvem, o que torna a operação muito mais difícil
Se você não integrar isso a esses sistemas para retirar os dados para outros nós, os dados desaparecem
Ao separar armazenamento e computação, o operador de nuvem pode esvaziar e mover a computação quando necessário; os dados são independentes da computação e, como o operador de nuvem também gerencia esse sistema de dados e o drain, consegue ajustar o posicionamento das cargas de trabalho sem intervenção do cliente
Armazenamento conectado em rede e replicado, que parece uma API de sistema de arquivos “local”, é uma forma poderosa de dar durabilidade a sistemas que não têm replicação embutida, como o nosso
Muito legal, e o PlanetScale Metal também parece bem sólido. Gosto especialmente de ver a latência cair bastante no release: https://planetscale.com/blog/upgrading-query-insights-to-met...
Durante anos, não entendi por que bancos de dados replicados sempre se prendiam ao EBS e aceitavam aquela latência. Se já existe replicação, eu me perguntava por que não usar discos locais sem medo
Em uma organização anterior, quando operávamos Elasticsearch como armazenamento temporário de logs/métricas, sem grandes requisitos de confiabilidade, sugeri fazer isso, mas não consegui convencer ninguém, e acabamos usando o AWS Elasticsearch, que era pior
Sei que a capacidade dos discos locais é finita, mas a proporção entre núcleos/memória/disco não seria suficiente para a maioria dos casos de uso? Também há muitas instâncias com disco local em proporções diferentes, então dá para encontrar um equilíbrio adequado
Também seria possível implementar armazenamento quente/frio com instâncias de disco rígido local de 20 TB ou mais
Quero elogiar muito a equipe da PlanetScale por finalmente fazer algo que faz sentido. Até a AWS não roda Elasticsearch em disco local; pense em rodar coisas como ClickHouse ou Cassandra todas em disco local
O problema central era que o disco é apagado depois de um evento de stop-start. Mesmo que o restante do cluster esteja intacto e haja réplicas disponíveis, o SQL Server não consegue lidar automaticamente com isso
Como ele não recupera automaticamente o nó reinicializado, o scripting e os testes necessários para contornar isso seriam difíceis de sustentar em produção, exceto para as organizações mais ousadas e competentes
Operamos centenas de clusters ClickHouse com esse modelo. É muito mais comum redimensionarmos para resolver problemas de desempenho do que por falhas
Por exemplo, se um tenant tem um problema de desempenho no domingo de manhã, horário dos EUA, a solução mais simples é subir para uma VM maior durante o fim de semana e deixar a equipe principal investigar a causa raiz na segunda de manhã
O custo extra é pequeno e evita um burnout de funcionários muito mais caro
Texto realmente excelente, e a visualização de gravações aleatórias ficou muito bem feita
Tenho algumas perguntas talvez bobas sobre os limites de IOPS do armazenamento conectado em rede
Primeiro, fico me perguntando se o limite de “IOPS” é mesmo um limite de taxa para um tipo específico de tráfego de rede, isto é, o tráfego de ida e volta para volumes EBS. No fim, quero perguntar se “IOPS” significa “tráfego de rede do volume EBS”
Segundo, também me pergunto se essa abordagem economiza custos. Se sim, seria por causa de uma arbitragem estranha de preços da AWS ou por ganhos de eficiência decorrentes de fazer menos networking de EBS?
Parece claro que colocar armazenamento e computação na mesma máquina tem a vantagem estrutural de reduzir um salto em termos de latência, mas gostaria de saber se também há ganho em throughput por dólar
Eu costumo ver isso por outro modelo. Um volume EBS não é uma parte de uma placa física conectada ao barramento PCIe, mas uma participação em um grande sistema distribuído composto por inúmeros drives físicos, mais próximo de uma SAN com capacidade de rede dedicada de ida e volta para a computação
Pode haver economia de custo, mas no fim é um conjunto de vários trade-offs