- O SQLite é muito rápido. Em um servidor comum single ~40€/m, ele consegue sustentar simultaneamente ~168.000 leituras e ~8.000 escritas
- Como é uma biblioteca embarcada projetada para aplicações do lado do cliente, como sistemas embarcados, celulares e aplicativos desktop, o banco de dados SQLite precisa ficar junto do servidor da aplicação e não pode ser acessado pela rede
- Como usar SQLite em cenários que exigem mais de uma máquina?
- Um projeto de fim de semana pode explodir em popularidade e precisar escalar rapidamente
- Um dos requisitos do CTO pode ser implantar um serviço de alta disponibilidade em pelo menos 2 datacenters diferentes
- Nos últimos anos, surgiram alguns projetos tentando adaptar o SQLite para uso como banco de dados de backend para aplicações backend.
- Este texto investiga se isso é uma mudança de paradigma que permite às organizações entregar uma experiência melhor ao usuário com mais rapidez, ou apenas hype de marketing empurrado por empresas que querem inflar sua "proposta única de venda (Unique Selling Proposition)"
Usando o SQLite como banco de dados de edge
- O SQLite está sendo promovido não como um simples banco de dados de backend, mas como um banco de dados de edge
- Os nomes mais representativos são Cloudflare D1, fly.io com LiteFS e Turso
- A maioria dos produtos derivados do SQLite funciona de forma parecida
- Há um banco de dados principal que aceita escritas em algum lugar, e ele é replicado de forma assíncrona para outras regiões
- A replicação normalmente acontece transmitindo o log de todas as transações executadas no banco de dados, ou seja, o Write-Ahead Log do SQLite
- Nessa arquitetura, em teoria as leituras podem ser atendidas em datacenters de edge, mas as escritas ainda precisam ser encaminhadas para um local central
- Na prática, ninguém quer que um cliente finalize um pedido em um aplicativo de e-commerce, o pedido seja aprovado no banco SQLite principal, mas a réplica regional de leitura ainda esteja atrasada e não tenha recebido os dados atualizados, exibindo uma mensagem de erro de item não encontrado
- Bem-vindo ao "doloroso mundo da consistência eventual"
A solução e os limites do LiteFS
- O LiteFS propõe uma solução meio gambiarra. A aplicação define um cookie
__txidpara rastrear a última transação que a réplica regional possui e, se ela estiver atrasada demais, encaminha a consulta de leitura para o banco principal. - Agora a aplicação fica fortemente acoplada ao banco de dados e ao proxy reverso
- O LiteFS não menciona o fato de suportar apenas cerca de 100 escritas por segundo
As principais desvantagens da maioria dos sistemas SQLite distribuídos
- A maioria dos sistemas SQLite distribuídos não oferece suporte a transações interativas, nas quais algum cálculo é feito entre diferentes consultas da transação.
- Apenas uma transação de escrita pode ficar ativa por vez. Em um banco SQLite comum isso geralmente é aceitável, porque a maioria das escritas não dura mais que algumas dezenas de microssegundos
- Porém, quando se introduz latência de rede entre a aplicação e o banco SQLite, o sistema quebra. O banco fica bloqueado durante o tempo de ida e volta da transação e acaba limitado a poucas escritas por segundo
- O Turso "resolve" isso com batching. Várias consultas podem ser agrupadas em lote e executadas como uma única transação. O Cloudflare D1 "resolve" o problema com batches e stored procedures
E se houver uma solução mais simples?
- Para aplicações web, já existe uma forma muito simples e poderosa de torná-las extremamente rápidas no mundo todo: cache HTTP com os cabeçalhos
Cache-ControleETag - Com cache HTTP, não é preciso recorrer a técnicas semelhantes às de bancos de dados fracamente consistentes, evitando que a aplicação web fique complexa demais ou vulnerável a condições de corrida
- O autor deste texto dedica bastante tempo em seu novo livro "Cloudflare for Speed and Security" para explicar várias estratégias de cache que não apenas tornam aplicações web rápidas, mas também permitem atender muitos usuários simultâneos com o mínimo de recursos
O banco de dados como abstração
- Latência não era o único problema que o SQLite distribuído tentava resolver. O outro era a complexidade operacional.
- Gerenciar um cluster de servidores conectados em rede é difícil e frequentemente leva a indisponibilidade e perda de receita. Sem falar na administração de bancos de dados, que exige gestão contínua e uma boa cultura de segurança para evitar desastres como o que o GitLab sofreu em 2017.
- Por isso, a ideia é empacotar o banco de dados junto com a aplicação e colocar tudo em um único servidor
- Isso é bom quando há um único desenvolvedor, mas em organizações maiores geralmente haverá uma pessoa ou equipe dedicada à manutenção dos servidores de banco de dados
- É exatamente por isso que bancos de dados acessados por socket, e não como bibliotecas embarcadas, são uma abstração tão boa: na prática, eles não são uma abstração técnica, mas organizacional. Durante o desenvolvimento, podem ser apenas um contêiner simples rodando na máquina do desenvolvedor; em produção, podem ser qualquer coisa, desde um contêiner rodando no mesmo servidor da aplicação até um cluster distribuído acessado pela rede. O desenvolvedor só precisa trocar uma única variável de configuração,
DATABASE_URL, e a equipe de operações cuida de todo o resto - Em contrapartida, o sistema de arquivos tradicional do Unix era uma abstração inadequada para computação distribuída. Claro, existe NFS (Network File System), mas o desempenho é consideravelmente ruim porque o sistema de arquivos Unix foi projetado para acesso em uma única máquina. Já o protocolo S3 é uma abstração muito boa para armazenar grandes volumes de dados não estruturados de forma eficiente, escalável e confiável. O desenvolvedor só precisa usar um SDK compatível com S3 e esquecer o assunto, enquanto a equipe de operações ou o provedor de nuvem cuida de desempenho, durabilidade, confiabilidade e tudo mais
Conclusão
- O SQLite é realmente um banco de dados incrível, mas para a maioria das equipes é melhor evitá-lo e escolher PostgreSQL
- Inúmeras horas de engenharia foram investidas para transformar o PostgreSQL no melhor banco de dados de backend. Ao escolher SQLite, inevitavelmente será preciso reinventar, de forma frágil e sujeita a bugs, coisas que o PostgreSQL já oferece há muito tempo
- O atual movimento de transformar o SQLite em banco de dados de backend é visto como nada mais que um golpe de marketing de empresas que vendem infraestrutura de edge computing e perceberam que computação não é nada sem armazenamento de dados. O conselho (não solicitado) para elas é investir em cache HTTP em vez de construir CDNs e empurrar complexidade para as aplicações. Isso traz resultados muito melhores
- Por causa da complexidade introduzida, 99,9% das aplicações de backend não verão qualquer benefício em ir para a edge e deveriam, em vez disso, focar em implantar boas estratégias de cache para oferecer uma ótima experiência global com menos de 100 ms
- E é aqui que termina o experimento do SQLite para aplicações server-side. Vitória do PostgreSQL
-
"Amadores discutem tática, profissionais discutem logística. (Amateurs discuss tactics. Professionals discuss logistics.)"
Ou seja, para o sucesso, mais importante do que decisões táticas no campo é o sistema e o processo de suporte que tornam essas decisões possíveis: logística e gestão
Opinião do GN⁺
- Como o autor argumenta, usar SQLite na maioria das aplicações de backend parece apenas aumentar a complexidade sem trazer benefícios reais. Usar um banco de dados já comprovado e maduro, como PostgreSQL, provavelmente é uma escolha melhor.
- O esforço das empresas de infraestrutura de edge computing para empurrar o SQLite parece fazer parte mais de uma estratégia de marketing do que de uma vantagem técnica. Seria mais útil para desenvolvedores de aplicações se elas investissem mais em cache HTTP e CDN.
- A maioria das aplicações de backend consegue oferecer serviços rápidos e escaláveis apenas com uma estratégia de cache adequada. A menos que edge computing seja realmente necessária, é melhor evitar complexidade excessiva.
- O SQLite distribuído pode ser útil em alguns casos de uso específicos, mas ainda parece ter limitações para servir como solução de propósito geral. Não será fácil satisfazer ao mesmo tempo conveniência de desenvolvimento, desempenho e consistência
- No fim, o mais importante é escolher a tecnologia de acordo com os requisitos da aplicação e a capacidade da equipe. Em vez de seguir modismos, é preciso analisar cuidadosamente os prós e contras e tomar decisões com cautela.
- O autor enfatiza que o SQLite ainda tem muitas limitações para uso como banco de dados de backend, mas isso não significa que deva ser totalmente descartado, já que pode haver outros casos de uso em que seus pontos fortes sejam bem aproveitados.
3 comentários
Em vez de pensar no que é melhor entre Postgres e sqlite,
será que não é melhor refletir sobre qual dos dois se encaixa melhor na sua situação?
A melhor opção vai mudar conforme o contexto.
Comentários do Hacker News