1 pontos por GN⁺ 2024-08-11 | 1 comentários | Compartilhar no WhatsApp

Construindo um serviço web de alta disponibilidade sem banco de dados

Exploração

  • No caso de uma nova startup, normalmente escolhe-se um framework web como Rails, Django ou Node, junto com um banco de dados como MySQL, PostgreSQL ou MongoDB
  • Mas e se fosse possível unir o serviço web e a instância do banco de dados em uma coisa só? Dá para adotar uma abordagem em que todos os dados ficam armazenados na RAM
  • Ao usar a RAM como banco de dados, deixa de ser necessário serializar os dados por meio de consultas SQL
  • Os índices podem ser implementados usando tabelas hash em memória
  • Tarefas em segundo plano podem ser processadas como threads dentro de um processo grande
  • Se o processo falhar, é possível se recuperar tirando snapshots periódicos da RAM e gravando as alterações em disco

Escala

  • Quando surgem clientes que exigem alta disponibilidade, os servidores são replicados usando o algoritmo de consenso Raft
  • Se o servidor líder cair, um novo líder é eleito para processar as requisições
  • Dessa forma, também é possível fazer deploy contínuo em rolling sem reiniciar os servidores

Extração

  • Quando passam a existir muitos clientes grandes, é possível dividir o serviço web por meio de sharding
  • Cada cliente enterprise recebe um cluster dedicado
  • O principal gargalo pode ser o desempenho da thread de commit

Nossa stack

  • Uso de Common Lisp: excelente suporte a multithreading e ideal para hot reloading de código
  • Uso de bknr.datastore e bknr.cluster: a biblioteca Braft, da Baidu, é usada para implementar o Raft
  • Uso de EFS para armazenar arquivos de imagem: mais fácil de lidar com erros e testar do que o S3

Resumo

  • Essa arquitetura é adequada para novas startups, e com Common Lisp muitas ferramentas já estão prontas
  • Agradecimentos às contribuições de bknr.datastore, Braft e Raft

Resumo do GN⁺

  • Este artigo apresenta uma nova arquitetura para construir um serviço web de alta disponibilidade sem banco de dados
  • A RAM é usada como banco de dados, e a alta disponibilidade é garantida por meio do algoritmo de consenso Raft
  • O uso de Common Lisp oferece suporte a multithreading e hot reloading de código
  • Essa arquitetura é adequada para novas startups e permite desenvolvimento e depuração rápidos
  • Projetos com funcionalidades semelhantes incluem Redis e Memcached

1 comentários

 
GN⁺ 2024-08-11
Comentários do Hacker News
  • É estranho criar um log de transações próprio sem usar SQLite

    • Se os dados cabem em um único servidor, é melhor simplesmente rodar o banco de dados nesse servidor
    • Se os dados cabem na RAM, usar um ramdisk e replicar para armazenamento permanente com ferramentas padrão é mais simples
  • Criar um banco de dados próprio em memória sem usar MySQL, Postgres, Redis, MongoDB etc. é complexo

    • É preciso serializar as transações e gravá-las em disco
    • É preciso sincronizar o log de transações entre os servidores web e atualizar o banco de dados em memória
    • É preciso escrever um algoritmo de resolução de conflitos
    • É preciso fazer sharding dos servidores web por tenant e escrever uma camada de balanceamento de carga
  • Não querer aprender os aspectos básicos de MySQL ou Postgres é perda de tempo

    • Ao rodar em um provedor de nuvem pública, é possível resolver problemas de concorrência com o tuning padrão
    • Adicionar 10 milhões de linhas não é um grande problema
    • É mais sensato esperar até que uma situação pior apareça e então resolvê-la
  • É uma arquitetura semelhante à de Nomad, Consul e Vault da HashiCorp

    • A experiência do desenvolvedor é boa
    • Dá para configurar o estado em memória do jeito que quiser
    • Não é adequada para startups novas
    • Atualizações são especialmente difíceis
  • Existe o equívoco de que RAM é muito barata

    • O desempenho de SSDs e vCPUs melhorou bastante, mas o preço da RAM não caiu muito
    • Os preços de DRAM variam ciclicamente, e só recentemente ficaram um pouco mais baratos
  • Já vi um projeto que usava diretórios do sistema de arquivos como tabelas e arquivos JSON como linhas

    • Consideraram Redis, Mongo e Postgres, mas acabaram construindo o próprio banco de dados
    • Usar tokens inovadores para construir um banco de dados é ineficiente
  • Usar um banco de dados relacional é mais estável

    • Há redundância embutida, log de transações, backup e recursos de recuperação
    • Na maioria dos casos, é melhor usar um banco de dados
  • Implementaram uma camada própria de consenso Raft para evitar coisas complexas

    • Usar Redis pode ser mais simples
  • Aplicativos modernos de desktop e mobile frequentemente usam bancos de dados como SQLite

    • Armazenamento e consultas relacionais são úteis
  • Construir um banco de dados próprio em memória não é mais simples do que instalar Postgres ou SQLite

    • Escrever SQL é mais fácil do que escrever código de concorrência