Com a popularização das plataformas de cloud computing e do conceito de SaaS (Software as a Service), onde o cliente paga pelo acesso aos serviços que o software provê (e não ao software em si), um outro termo técnico se tornou muito frequente quando falamos de desenvolvimento de software: o termo multitenant. Softwares no “estilo” de um SaaS e que rodem em provedores de cloud quase que obrigatoriamente são implementados de maneira a suportar múltiplos inquilinos. Mas, no final das contas, o que é um software que implementa o conceito de multitenancy? Como eu posso construir um software que implemente esse conceito?
Formação Especialista Spring
Conhecer a formaçãoAntes de tudo: o que é multitenancy?
Basicamente, um software que implementa o conceito de multitenancy foi desenvolvido para suportar múltiplos inquilinos (aliás, a tradução de tenant é inquilino). Isso quer dizer que uma mesma instância de um software multitenant consegue atender a vários clientes (também designados como inquilinos) diferentes ao mesmo tempo. Pense no desenvolvimento de uma aplicação de gerência financeira, por exemplo. Pode ser que esta aplicação tenha sido concebida para ser como um produto, ou seja: ela foi feita para atender diferentes pessoas em diferentes empresas. E, falando em termos de faturamento, provavelmente este software será vendido para diferentes empresas o utilizarem… Uma possibilidade é que cada cliente tenha a sua própria máquina em um provedor de cloud computing com esse software de gestão financeira instalado. Dessa maneira, é como se todos os usuários da empresa A acessassem o software no servidor X, enquanto todos os funcionários da empresa B acessassem o software no servidor Y. Essa arquitetura certamente funciona, mas ela traz alguns problemas que podem ser difíceis para serem resolvidos, principalmente em larga escala:
- Quando o software precisar ser atualizado, a atualização precisará ser aplicada em múltiplos servidores. Há o risco de algum cliente ficar sem a atualização, caso a atualização não seja aplicada em algum servidor por esquecimento ou falhas no processo;
- O fato de cada cliente ter a sua própria máquina dedicada pode tornar a manutenção do software muito cara à medida que mais e mais clientes forem adquirindo o software, já que mais e mais instâncias no provedor de cloud computing precisarão ser contratadas.
Perceba que, com os pontos destacados acima, o software de gestão financeira em questão corre o sério risco de se tornar insustentável, seja do ponto de vista técnico, seja do ponto de vista de custos envolvidos. Porém, existe uma maneira de corrigirmos estes pontos: se o nosso software pudesse atender as empresas A e B na mesma instância ao mesmo tempo, sendo capaz de diferenciar de alguma maneira quando os dados da empresa A devem ser exibidos e manipulados; e quando os dados da empresa B devem ser exibidos e manipulados. Nessa situação, o nosso software de gestão financeira se tornaria um software multitenant, tendo como tenants as empresas A e B.
Uma arquitetura baseada no conceito de multitenancy propiciaria:
- Redução na complexidade do processo de gestão do software para múltiplos clientes. Por exemplo, o caso da atualização: não haveria o risco de algum cliente não obter a atualização em questão, tendo em vista que a instância do sotware seria única;
- Economia com infraestrutura. Por mais que, provavelmente, a instância de um software multitenant precisa ser mais poderosa pelo fato de atender múltiplos tenants ao mesmo tempo, ainda sim provavelmente o custo será menor do que se tivéssemos várias instâncias distintas servindo para vários clientes de maneira distinta;
- Maior facilidade na obtenção de métricas com relação a utilização do software em questão, tendo em vista que estamos falando nesse caso de uma única instância.
Multitenant e isolamento de dados
O fato de termos uma única instância de software traz um problema: como vamos fazer para separar os dados entre os diferentes tenants de nossa aplicação? Para resolver este problema, podemos utilizar três estratégias diferentes: chave estrangeira, schema segregado e banco de dados segregado.
Multitenancy com chaves estrangeiras
Essa é a maneira mais simples e primitiva para separarmos os dados de nossos diferentes tenants. Com essa estratégia, cada tabela envolvida na aplicação terá uma chave estrangeira para uma tabela de controle dos tenants. Todos os dados de todos os tenants ficariam juntos no mesmo banco de dados, sendo segregados justamente por essa chave estrangeira. Quando um usuário acessasse a aplicação, esta iria verificar o tenant vinculado ao usuário e mostraria somente os dados das tabelas cujas linhas tivessem a foreign key atrelada ao tenant do usuário.
A vantagem dessa estratégia é que sua implementação é muito simples e muito barata, tendo em vista que envolve somente a utilização de chaves estrangeiras e filtros. Porém, esta estratégia tem basicamente dois pontos ruins… Um ponto é que a performance pode ficar gravemente comprometida no caso de uma quantidade muito grande de dados e/ou uma quantidade muito grande de tenants. O outro ponto é que o banco de dados é único para todos os tenants, ou seja: se um dos tenants executar uma operação muito pesada no banco (como uma consulta muito extensa ou uma carga de dados muito grande), todos os outros tenants irão sofrer com a lentidão ou até mesmo com a queda do banco de dados, já que este é único para todos os usuários. Por isso, essa estratégia não é recomendada para aplicações com uma volumetria muito grande de dados e/ou de tenants.
Multitenancy com segregação via schema
Nesta estratégia, a instância do banco de dados ainda é compartilhado entre todos os tenants, como ocorre na estratégia com chaves estrangeiras. Mas, desta vez, cada tenant possui seu próprio schema, ou seja: a instância do banco é a mesma para todos, mas essa instância tem múltiplos conjuntos das tabelas da aplicação isolados para cada tenant.
A principal vantagem dessa estratégia é justamente o isolamento lógico entre os dados dos diferentes tenants, reduzindo o possível impacto que um tenant pode causar nos demais tenants da aplicação (como no caso de uma deleção de dados acidental - com schemas diferentes, essa deleção acidental ficaria restrira ao tenant/schema que a causou). Também trata-se de uma estratégia barata, pois ela ainda é fundamentada em uma única instância de banco de dados. Porém, trata-se de uma estratégia de implementação um pouco mais complexa, o que pode encarecer um pouco o processo de adoção desta estratégia. Outro ponto diz respeito ao esforço gerencial dos diferentes schemas da aplicação, que é sensivelmente maior do que na estratégia de replicação de chave estrangeira. Esta estratégia também pode gerar problemas no caso de uma volumetria de dados um pouco maior.
Formação Especialista Spring
Conhecer a formaçãoMultitenancy com segregação via banco de dados
Nesta estratégia, cada tenant tem uma instância de banco de dados dedicada, sendo a aplicação capaz de realizar conexões a múltiplos bancos de dados diferentes ao mesmo tempo.
A principal vantagem deste modelo é que agora o isolamento chega a ser “físico”, levando em consideração que cada tenant terá sua instância de banco de dados exclusiva. Isso mitiga mais ainda o impacto de operações que os tenants podem fazer e que possam prejudicar a experiência dos outros tenants. O ganho de performance nessa estratégia também é perceptível, já que estamos falando de instâncias de bancos de dados isoladas e diferentes para cada tenant. Porém, esta estratégia é sensivelmente mais complicada de ser implementada do ponto de vista técnico: a aplicação terá que ser capaz de se conectar a múltiplos bancos de dados ao mesmo tempo de acordo com o usuário que estiver acessando a aplicação. Além disso, será necessário provisionar uma instância de banco de dados para cada tenant, o que também torna esta a estratégia mais cara entre as três estratégias descritas.