Servidores de banco de dados e bancos de dados embarcados: comparação de arquitetura e características de E/S

Servidor de banco de dados
Um servidor de banco de dados refere-se a um banco de dados que é executado como um processo de servidor independente e processa as requisições de aplicações por meio da rede. A maioria dos RDBMS familiares, como MySQL, PostgreSQL e Oracle DB, pertence a esse modelo. O servidor de banco de dados apresenta as seguintes vantagens.
- Gerenciamento centralizado: os dados são gerenciados de forma integrada em um único local, o que facilita a consistência, a segurança, o backup e a recuperação.
- Independência de recursos: por receber CPU, memória e armazenamento próprios, garante desempenho estável independentemente do estado da aplicação.
- Alta concorrência e escalabilidade: é otimizado para o acesso simultâneo de muitos usuários e, por meio de clusterização ou replicação, a escalabilidade horizontal é relativamente simples.
Graças a essas características, o servidor de banco de dados se consolidou como padrão da infraestrutura de software ao longo das últimas décadas. No entanto, devido aos avanços tecnológicos e às mudanças no ambiente, as limitações do servidor de banco de dados começaram a se evidenciar em alguns contextos, e, como alternativa, os bancos de dados embarcados voltaram a receber atenção.
Uma nova tendência: banco de dados embarcado
Um banco de dados embarcado é um mecanismo de banco de dados que, sem processo de servidor separado, é incluído na aplicação na forma de biblioteca e é executado dentro do mesmo processo. SQLite, LevelDB e RocksDB são exemplos representativos de bancos de dados embarcados. Os motivos pelos quais esses bancos de dados embarcados surgiram como alternativas robustas no ambiente tecnológico atual são os seguintes.
O surgimento do SSD
Em sistemas com predominância de HDD, o desempenho de acesso aleatório era significativamente inferior ao de leitura e escrita sequenciais. Assim, minimizar o I/O de disco e maximizar o cache em memória era o núcleo da otimização de desempenho. Os servidores de banco de dados, nesse contexto, operavam caches de grande porte e agrupavam operações de escrita para processá-las, superando as limitações físicas do HDD.
Contudo, o surgimento do SSD alterou completamente essa premissa. O SSD apresenta desempenho de I/O aleatório milhares de vezes superior ao do HDD e latência drasticamente menor. Como resultado, a percepção tradicional de que "o I/O de disco é o principal gargalo" deixou de valer, e a latência decorrente do acesso remoto ao servidor de banco de dados pela rede passou a emergir como o novo gargalo.
MSA e independência de dados
No passado, era comum a estrutura em que uma grande aplicação monolítica dependia de um único banco de dados centralizado. Embora esse método fosse simples, à medida que a escala do serviço aumentava, tornava-se difícil alterar o esquema dos dados e todos os serviços compartilhavam o mesmo banco, o que gerava um acoplamento excessivamente forte.
Na arquitetura de microsserviços contemporânea, o princípio "Database per Service" é considerado importante para resolver esses problemas. Ao possuir e encapsular seu próprio repositório de dados exclusivo, cada serviço garante independência entre serviços, e o isolamento de falhas e a escalabilidade tornam-se mais fáceis. Nesse processo, o banco de dados embarcado torna-se uma escolha ideal como repositório de dados em nível de serviço. Por ser leve e rápido e poder ser implantado junto com o código do serviço, ele se adapta muito bem ao ambiente MSA.
Em particular, em ambientes Kubernetes, é amplamente utilizado o padrão sidecar, que posiciona um banco de dados embarcado ao lado do contêiner da aplicação para otimizar o processamento local de dados. Isso reduz gargalos de rede e minimiza a latência de acesso aos dados.
Simplificação do ambiente operacional
Os servidores de banco de dados exigem procedimentos operacionais complexos, como instalação, aplicação de patches, backup, recuperação de falhas, replicação e monitoramento de desempenho, e para isso são necessários DBAs dedicados e equipes operacionais especializadas. Especialmente em ambientes de grande escala, essa carga de gerenciamento é muito pesada.
O banco de dados embarcado alivia significativamente esses problemas. Quando o banco de dados é integrado ao interior da aplicação, testes unitários, build, controle de versões e implantação são realizados em conjunto, dispensando a operação de um servidor separado. Além disso, quando a aplicação sofre Scale-out, o banco de dados embarcado também se expande junto, e torna-se possível o gerenciamento automatizado por meio da cultura DevOps e de pipelines de CI/CD. Especialmente em startups, serviços de pequeno porte e ambientes de desenvolvimento de protótipos, o banco de dados embarcado reduz drasticamente a complexidade operacional e aumenta significativamente a velocidade de desenvolvimento e implantação.
Linguagens de sistema de alto desempenho e evolução do ecossistema
No passado, era comum que o banco de dados e a aplicação fossem escritos em linguagens diferentes. Por exemplo, os mecanismos de banco de dados que exigiam alto desempenho eram escritos principalmente em C e C++, enquanto as aplicações eram desenvolvidas em linguagens como Java, Python e PHP. Esse método era eficaz para a otimização de desempenho, mas apresentava limitações como problemas de segurança de memória, tratamento complexo de concorrência, latência e dificuldades de integração de bibliotecas e de implantação.
No entanto, com a ascensão de linguagens de programação de sistemas modernas, como Go e Rust, essas limitações foram significativamente atenuadas. Em especial, o Go é adequado tanto para aplicações de alto desempenho quanto para a escrita de programas de baixo nível, como mecanismos de banco de dados, o que permite tratar o banco de dados e a aplicação dentro de um mesmo ecossistema linguístico.
De fato, no Golang, bancos de dados embarcados de alto desempenho como BadgerDB e PebbleDB são amplamente utilizados. Isso significa que o banco de dados embarcado vai além de ser simplesmente uma alternativa leve ao servidor de banco de dados, consolidando-se como uma escolha importante com competitividade própria.
Conclusão
Em condições que exigem gerenciamento centralizado de grandes volumes de dados, transações complexas e alta concorrência, o servidor de banco de dados continua sendo a solução mais poderosa. Contudo, em serviços individuais de um ambiente MSA, dispositivos de borda IoT, prototipagem rápida e projetos em que a eficiência operacional é importante, o banco de dados embarcado pode se tornar uma escolha mais eficiente e racional. Em última análise, o essencial é selecionar a ferramenta ótima que melhor se ajuste à situação e aos requisitos dados, e o desenvolvimento dos bancos de dados embarcados nos oferece opções mais amplas e diversificadas.