Usando SQLite como repositório de conteúdo estático para servidor web
Contexto
- A Clace é uma plataforma projetada principalmente para fornecer aplicações web para ferramentas internas.
- A Clace integra funções que normalmente são tratadas separadamente por um servidor web e um servidor de aplicações.
- No início do desenvolvimento da Clace, era importante decidir como armazenar os dados e os metadados da aplicação.
- Armazenar os metadados em um banco de dados fazia sentido, e arquivos estáticos normalmente são armazenados no sistema de arquivos.
Uso do SQLite para servir arquivos
- A Clace decidiu usar SQLite em vez do sistema de arquivos para armazenar os arquivos da aplicação.
- Isso permite mudanças de versão atômicas, de modo que vários arquivos possam ser processados em uma única transação durante uma atualização.
- Na criação e atualização de apps, todos os arquivos são enviados para o banco de dados SQLite, enquanto no modo de desenvolvimento é usado o sistema de arquivos local.
Vantagens de usar SQLite
- Atualizações transacionais: vários arquivos podem ser atualizados de uma vez, garantindo que não exista uma webapp quebrada durante a atualização.
- Rollback de implantação: é possível reverter uma implantação quando ocorre um erro, e fazer rollback de transações no banco de dados é mais fácil do que limpar o sistema de arquivos.
- Deduplicação de arquivos entre versões: mesmo que o mesmo arquivo exista em várias versões, o conteúdo do arquivo é armazenado apenas uma vez.
- Deduplicação entre apps: evita duplicação quando o mesmo arquivo existe em vários apps.
- Facilidade de backup: com SQLite, é fácil fazer backup do estado do sistema.
- Hash de conteúdo: ao enviar arquivos, o SHA do conteúdo é armazenado para facilitar o cache no navegador.
- Compressão: o conteúdo dos arquivos é armazenado comprimido com Brotli, e pode ser salvo facilmente em vários formatos.
Desempenho
- A abordagem de acesso ao banco de dados SQLite da Clace oferece excelente desempenho.
- Não foi realizado um teste de benchmark direto porque não existe uma implementação equivalente usando sistema de arquivos.
- Segundo benchmarks da equipe do SQLite, em algumas cargas de trabalho o SQLite pode ter desempenho melhor do que o sistema de arquivos.
Suporte a múltiplos nós
- Atualmente, a Clace roda em um único nó.
- Quando o suporte a múltiplos nós for adicionado, o plano é usar um banco de dados Postgres compartilhado em vez de SQLite local.
- Isso pode causar problemas de latência, e o plano é usar um banco de dados SQLite local como cache de arquivos para reduzir essa latência.
Por que essa abordagem não é comum
- A maioria dos servidores web usa o sistema de arquivos por conveniência.
- É possível atualizar arquivos com ferramentas do sistema de arquivos, mas ao usar banco de dados é necessária uma interface de API para upload de arquivos.
Resumo do GN⁺
- A Clace é uma plataforma para desenvolvimento e implantação de ferramentas internas, e maximiza as vantagens do armazenamento de arquivos usando SQLite.
- Ao usar SQLite, oferece várias vantagens, como atualizações transacionais, rollback, deduplicação e facilidade de backup.
- Essa abordagem não é comum por causa da conveniência e de razões históricas ligadas ao sistema de arquivos, mas aumenta a eficiência ao aproveitar o desempenho e os recursos do SQLite.
- Projetos com funcionalidades semelhantes recomendados incluem Firebase e AWS Lambda.
1 comentários
Opiniões no Hacker News
Há alguns anos, inspirado pelo artigo "35% Faster Than The Filesystem", fiz um experimento usando SQLite para servir arquivos estáticos. Criei um plugin para servir arquivos estáticos do SQLite via Datasette, mas acabei não usando muito. Para servir arquivos com SQLite, a ferramenta de CLI
sqlite-utils insert-filespode ser útil.Atualizações transacionais são uma grande vantagem, pois permitem atualizar vários arquivos de uma vez. Mesmo que o servidor use SQLite ou o sistema de arquivos, isso não impede que a aplicação web quebre durante uma atualização. É preciso garantir que todos os sub-recursos de uma página sejam referenciados usando um hash de conteúdo específico ou um nome de versão.
Quando trabalhei em uma pequena empresa de desenvolvimento de jogos em 2011/2012, armazenávamos todos os assets em um banco de dados sqlite3 e criávamos arquivos pak para guardar os offsets dos arquivos. Isso permitia carregar assets rapidamente em jogos mobile, e também armazenávamos os metadados no banco para encontrar arquivos semelhantes com facilidade.
Há a vantagem de poder consultar arquivos usando SQLite em vez do sistema de arquivos. Consultas SQL também podem ser usadas com segurança de tipos usando Kysely.
A ideia de servir conteúdo estático com SQLite não é completa. Servidores web modernos usam estratégias ideais para lidar com arquivos estáticos. SQLite oferece suporte a I/O com memory mapping, mas não é adequado para sites de grande escala.
SQLite é adequado para sites com menos de 100K acessos por dia. O site do SQLite lida com 400K~500K requisições HTTP por dia e, na maioria dos casos, a carga média fica abaixo de 0.1.
Um CMS com gerador de site estático pode usar um banco de dados SQLite para desenvolver e atualizar o site e, depois, despejá-lo no sistema de arquivos como páginas estáticas para implantação.
Em computação científica de alto desempenho, uma das formas mais flexíveis e com melhor desempenho para acessar dados costuma ser um banco de dados SQLite somente leitura em um ramdisk.
Seria interessante comparar essa abordagem com o uso de sistemas de arquivos que oferecem deduplicação, snapshots, versionamento e compressão. Com um sistema de arquivos avançado, pode ser mais fácil trocar um diretório por uma nova versão.
A abordagem de usar um banco de dados como sistema de arquivos tem vantagens, mas quando surgem problemas, pode virar um pesadelo.