42 mensagens, 20 participantes

Abordagens de multitenant

#multitenant #arquitetura

 
Avatar Guilherme Si...
Líder técnico
353 mensagens

Em um produto que estamos trabalhando temos a necessidade de disponibilizar o mesmo para múltiplos clientes.

Pensando nisso, existem diversas abordagens possíveis. A de infraestrutura mais fácil seria a de colocar o sistema no cloud e a cada novo cliente, criar uma instância nova de uma máquina na cloud mínima, e instalar o mesmo lá.

A desvantagem dessa abordagem é que as máquinas minimas de cloud disponibilizadas no mercado brasileiro e no exterior são potentes o suficiente para aguentar cerca (mais) de 10 produtos simultâneos utilizando o pico do serviço contratado.

Nesse caso, estamos subutilizando o valor pago no cloud para os clientes que atenderemos.

Visando diminuir isso, podemos levantar na mesma instancia de cloud diversos contextos (em um servidor de aplicação/servidor), cada um responsável por um cliente, até 10 clientes, com bancos distintos. Dessa maneira vimos que conseguimos aguentar até 30% mais produtos na mesma máquina (13, nesse exemplo), mas com um custo de scripts de operação maior.

A terceira opção é utilizar diversos clientes em um mesmo contexto, um mesmo banco, fazendo o multi-tenant “na unha”. Ainda não temos os dados mas a desvantagem é ter que cuidar de detalhes de segurança e requisitos não funcionais que não precisávamos antes.

Existem outras sugestões? Vantagens, desvantagens?

Share |
 
Avatar sérgio lopes
51 mensagens

Pelo que entendi, o que você quer priorizar é trabalho mínimo e possível escalabilidade, certo? E pela descrição, a única parte da aplicação que muda de cliente pra cliente são os dados e não a lógica.

Na minha opinião, colocar contextos de banco separados para cada cliente é o que dá mais trabalho. Evoluir esquemas separados, fazer o switch da base dinamicamente, manter Conexões/Sessions específicas por clientes de maneira escalável, performática e segura etc. Eu realmente não entendi a frase que manter tudo no mesmo contexto exige “fazer o multi-tenant na unha”. Não vejo como seria mais fácil manter tudo duplicado.

Pra mim o natural é uma aplicação, um banco. Se seu negócio atende vários clientes, faça sua modelagem de banco atender vários clientes. Acho bem mais fácil que manter várias instâncias ou qualquer outra coisa. (vide todas as empresas “Web 2.0” e serviços online; imagine se cada cliente tivesse uma instância própria do GMail, GitHub, Twitter etc etc)

PS. Nunca tinha ouvido essa palavra “multitenant”, palavra bonita :)

 
Avatar Guilherme Si...
Líder técnico
353 mensagens

Oi Sergio,

Existem quatro processos que são afetados por cada abordagem: desenvolvimento,deploy novo, update, manutencao da infra.

Mantendo um contexto por tenant significa que:
a) desenvolvimento não se preocupa com usuários de um tenant acessando dados de outro, o servidor cuida disso
b) deploy novo é fácil, basta copiar o arquivo de contexto e criar um banco limpo
c) processo de update é complicado, tem que passar por todos os contextos e bancos atualizando. essa abordagem permite tenants atualizarem o sistema para a versao nova quando bem entenderem.
d) para escalar um cliente será necessário muda-lo de maquina (ou mudar algum outro de maquina). o processo é simples, basta copiar tudo deum lugar para outro (contexto e banco).

Mantendo tudo em um contexto só:
a) desenvolvimento fica mais complicado: preocupacao de seguranca de multi tenant fica dentro da sua aplicacao
b) deploy é feito programaticamente, os devs se preocuparam com isso e fazem um insert no banco
c) update é feito em todos os clientes de uma vez só. eles nao podem escolher quando sera feito pois sera feito para todos ou para nenhum. o processo de update é mais simples, so tera um banco e um contexto para ser atualizado. mas ao mesmo tempo é um single point of failure
d) escalar aqui é escalar horizontal, adicionar mais maquinas de webserver e de banco (em geral master/slave)
Essa é a abordagem que você citou como natural sua modelagem atender varios clientes.
Do wikipedia “In addition, the actual development of a multitenancy system is somewhat more complex, and the testing necessary for security needs to be more stringent.”

Concordo que o natural é uma aplicacao um banco. A questao seria: “uma aplicacao é um cliente de seu produto?” ou “uma aplicação são varios clientes de seu produto?”.

Não são todas as empresas Web 2.0 e servicos online que fazem isso. O GMail existe uma instância para cada empresa e, de fora, não sabemos dizer se a instância é a mesma internamente ou não. Github existe um produto que você compra e roda ele só para você.
Como usuário final você não tem como saber se o produto que sua empresa comprou está tendo os dados armazenados em uma só maquina de dados ou em multiplos separados – essa é a mágica da transparencia dessas arquiteturas. Se o salesforce guarda um banco para cada cliente, nós como usuários não sabemos disso e nunca descobriremos.

Em alguns casos, empresas que fornecem um produto para empresas concorrentes não podem manter – por contrato – os dados das duas empresas na mesma estrutura – que obrigaria a primeira abordagem. Já vi esse caso na prática, eles são obrigados a usar bancos distintos.

A definição de multitenancy nao wikipedia comenta sobre a diferença com virtualização. O interessante é que parece que multitenancy vai na contramão do cloud. A virtualização atraves de cloud é justamente para que não nos preocupemos com quem nos fornece o serviço e permitiria fazer a otimização de escalabilidade que o multitenancy tenta nos dar. Claro que podemos misturar as duas coisas:

http://en.wikipedia.org/wiki/Multitenancy

Há quem argumente que sem multitenancy, um cloud não é cloud:

http://www.infoworld.com/d/cloud-computing/the-…

 
Avatar fabio kung
1 mensagem

Outra coisa importante de se considerar é o chargeback. Para aplicações e produtos em que isso é importante é MUITO difícil fazer com uma aplicação monolítica única cuidando de todos os “tenants”.

Ex. de chargeback é fazer com que quem esteja “ferrando” os servidores pagar mais por isso. Nessa mesma linha, com tenants separados em instâncias/contextos diferentes, também é mais fácil garantir que alguns poucos usuários afetem a performance de outros.

Virtualização e Cloud IaaS ajudam nesse caso, pois garantem uma fatia mínima da infraestrutura para cada tenant. Isolamento total, tanto no nível da segurança como o Guilherme comentou, quanto no nível mais baixo da infraestrutura. Alguns produtos que precisam garantir isolamento e fazer chargeback sofrem muito por causa disso. Vide o caso da Force.com que precisou criar a própria linguagem de programação “multitenant”, a própria linguagem de query e um preprocessador de queries que faz otimizações e garante que nenhum tenant acesse a área de outro.

Vale o custo?

Como já comentaram também, a principal desvantagem de separar cada tenant em uma instância diferente é ter que lidar com muitas instâncias/aplicações/contextos, ao invés de apenas uma. Fazer updates separados, escalar cada um separadamente, etc. Automação da infra aqui ajuda bastante (principalmente configuration management – puppet, chef, CF Engine, …).

 
Avatar Guilherme Si...
Líder técnico
353 mensagens

Muito boa a explicação. Minha preocupação é o chargeback mesmo, não conhecia o nome oficial dele.

Se cinco contextos estão na máquina e um começa a afetar, jogamos ele para outra máquina (ou os outros para outra máquina), mas levamos para nível de scripts de management o que a infra de cloud estaria fazendo para nós, correto?

Alguma sugestão? No caso do produto que estamos fazendo, o custo de uma máquina de cloud (em qualquer provider) é muito alto para ficar um tenant por máquina de cloud, então precisamos ou de um por contexto, ou tudo no banco. Acho que o contexto é o meio termo que facilitará?

Muito legal o exemplo dos problemas do salesforce

Abraço!

 
Avatar sérgio lopes
51 mensagens

Ótimos pontos, Guilherme e Kung! Realmente é um trade-off, há vantagens e desvantagens nos dois. Eu ainda acho o contexto único muito mais fácil e, a não ser que haja um requisito muito forte para separar contextos diferentes, iria sempre pelo caminho de uma coisa só.

O exemplo do GitHub acho que você confundiu. O serviço deles é único pra todo mundo (github.com). Se você quiser instalar na sua infra por algum motivo (segurança?) você compra o produto e você instala. (pelo que entendi do produto que estamos desenvolvendo, o cliente não vai instalar na máquina dele, vamos oferecer tudo com serviço, certo?)

E, Gui, a sua aplicação realmente vai ter o chargeback? Pelo que o Kung explicou me parece que chargeback é pra cobrar o cliente pelo uso de recursos ou eventualmente restringir o uso de recursos de um cliente só (pra isso é mais fácil mesmo ter contextos separados). Mas pela sua descrição, Gui, me parece que você só quer é que todo mundo não caia se algum cliente usar mais que os outros (mas não me parece que você vai cobrar por isso ou restringir esse cara). E se você quer apenas escalabilidade “infinita” independente do uso do cliente, nada melhor que uma aplicação só, um contexto só e jogar tudo no cloud e ele se vira (elástico).

Vejo pela minha experiência no AppEngine. Jogo minha App lá com um Datastore só e podem aparecer quantos clientes quiserem que ele aguenta e escala sozinho sem eu fazer absolutamente nada. Aliás, já que entramos em cloud, me parece que toda preocupação que você está tendo com custo/máquina/contextos é porque está usando IaaS. Como já disse o Paulo no Blog, PaaS é o futuro! Dá muito trabalho gerenciar máquinas e instâncias mesmo no cloud :)

[]’s

 
Avatar Guilherme Si...
Líder técnico
353 mensagens

Oi Sérgio,

Isso mesmo, disponibilizar instalar em multiplas maquinas, seja no ambiente dos clientes ou no meu, é distribuir a responsabilidade. O que acontece se o github vendido nas maquinas dos clientes precisam ser updatados? O mesmo processo que manter multiplas instancias rodando… os problemas e as vantagens sao as mesmas…

No nosso caso, temos que o servico possui niveis de uso, podem usar mais ou menos (tem restricoes de uso), entao dependendo do nivel de uso de um cliente podemos colocar mais ou menos clientes na mesma maquina: o chargeback.

Pois é, essas sao as questoes que estamos levantando. Implementar o multi-tenant na unha permite o uso elastico maravilhoso, mas adiciona os custos mencionados ate aqui… esses sao os + e -, acho que é isso.

Abraco

 
Avatar sérgio lopes
51 mensagens
> Isso mesmo, disponibilizar instalar em multiplas maquinas, seja no ambiente dos clientes ou no meu, é distribuir a responsabilidade. O que acontece se o github vendido nas maquinas dos clientes precisam ser updatados? O mesmo processo que manter multiplas instancias rodando… os problemas e as vantagens sao as mesmas…

Perfeito, ai matou. Se vai rodar na maquina do cliente e nao só como servico aí é tem que ter varios contextos mesmo. Meus pontos são validos pra algo 100% serviço mesmo, nao pensando em infra do cliente (é que eu tinha pensado que o produto era só hosted)


Do chargeback, acho que eu entendi errado então a definicao do Kung. Tinha entendido que se aplica só quando voce quer cobrar preços especiais baseado na carga de cada usuário ou quando voce quer limitar o uso de algum guloso. Achei que esse caso de só aguentar o tranco dos clientes (sem cobrar ou limitar) era escalabilidade simples

 
Avatar luciano costa
1 mensagem

Caros,

Desculpem o atraso no tópico, mas só agora conheci o site, por meio de um tweet…

Iniciamos um projeto com essas dúvidas há alguns meses. Ele ainda não está em produção, logo não poderei dizer o que é melhor, mas considero que tomamos a melhor decisão que poderíamos no momento: fazer da forma mais simples e assumir que não temos como prever o que irá acontecer quando o software for para produção.

Adotamos a solução: 1 banco, N clientes.

Nosso projeto utiliza vraptor3 e hibernate, com o famoso DAO genérico, customizado para este projeto. Colocamos nesse GenericDAO um mecanismo que garante que toda a operação feita sobre a base de dados inclua o campo “clientId” e dispare erros alertando o desenvolvedor no caso de ele ter esquecido. É possível anotar um pojo para que ele não utilize esse recurso, se necessário (exceção).

Se de 10 clientes, apenas 1 realmente necessitar mais recursos, ou exigir ambiente separado por motivos contratuais, terá valido a pena contratar os outros 9 ambientes? E se de 10, aumentarmos esse número para 50, ou 100 ou N?

Acredito que poderemos rapidamente identificar casos que realmente necessitem infra específica (exceção) e aí sim montarmos um ambiente distinto para ele. Nesse caso, em vez de 10 ambientes, teremos 2: um com 9 clientes e outro com 1.

O resumo disso é que vejo uma solução híbrida, e que só saberemos o que realmente é necessário a medida em que as coisas forem acontecendo (learn as you go!).

Acho que essa foi a escolha de menor impacto, em caso de possível mudança: se a coisa realmente apertar, dividimos a solução em N.

Claro, cada caso é um caso. Esse, por enquanto, é o nosso.

 
Avatar Rafael Mendo...
1 mensagem

Olá pessoal. Muito boa a discussão. Não sei se vocês conhecem mas existe um video que foi gravado durante a acts_as_conference 2009 que fala sobre como criar uma aplicação muiti-tenant utilizando Rails. http://aac2009.confreaks.com/06-feb-2009-14-30-…

Eu particularmente utilizo a abordagem de um banco para cada cliente. Estou utilizando o MongoDB para gerenciar os dados da aplicação. Claro que para essa abordagem preciso tratar de todos os requisitos não funcionais na aplicação, mas esta abordagem está sendo satisfatória

 
Avatar Guilherme Si...
Líder técnico
353 mensagens

Bom dia Luciano,

Mesma coisa por aqui… acabamos pela solução de 1 banco, N clientes. A capacidade está bem alta de escalabilidade de uma máquina de cloud simples então otimizamos o custo dos clientes assim.

Muito boa a idéia do DAO, com hibernate também seria possível implementar um interceptador pensando agora, muito boa a solução. Principalmente para permitir a customização de lógica por cliente, onde o cliente será capaz de fornecer código java que rodará no ambiente, mas ainda protegendo os outros clientes.

Rafael, também pareceu que para nós o 1 banco 1 cliente era suficiente, só corremos para o mais genérico pois potencializamos o consumo da máquina (ganhamos cerca de 30% mais de capacidade por dividir o banco entre vários tenants). Claro, esses dados são baseados em números de testes, não chutes :)

Com o tempo veremos outras soluções hibridas que o pessoal encontrou tambem, como de se esperar, todas podem dar certo. Bom saber que estamos procurando a melhor para cada caso

Abraço

 
Avatar Bruno Taboada
80 mensagens

Guilherme contexto voce se refere a um contexto web em um tomcat?

 
Avatar Guilherme Si...
Líder técnico
353 mensagens

Isso, contexto web em tomcat ou exemplos similares em outros servidores de aplicações (ou similares).

 
Avatar vinícius maia
1 mensagem

Olá,
Se a aplicação em si for a mesma para todos os clientes, então seria mais rápido, e talvez mais gerenciavel, criar um tipo de ClienteSessionManenger, que diponibilize a conecção (sessão do hibernate no meu caso) para os Daos.
No projeto em que trabalho tenho um interceptor que gerencia isso e por injeção passa as session para frente, assim mantenho apenas um aplicativo que aponta para varios bancos diferentes. Não sei se ajuda mas deve servir para alguem esta ideia.

 
Avatar Bruno Taboada
80 mensagens

Bom quero dar pitaco tb! :)

Bom acho que decisões de multi-tenant depende muito do que o seu cliente necessita e a maneira que você deseja entregar essa solução.

Acredito que você possa desenhar uma boa solução para o cliente e que também seja bom para você manter, reutilizar e atualizar.

Se sua aplicação possui serviços que você possa torna-los multi-tenant e que atenda as premissas de segurança exigidas, acredito que você possa desenhar sua aplicação SaaS de maneira composta, onde você tenha uma granularidade alta dessas funcionalidades que você deseja entregar ganhando uma boa manutenbilidade e atualização a todos seus tenants em alguns desses serviços.

Fora os benefícios que você citou essa nova pespectiva de utilizar recursos computacionais pagando somente o que você usa, você pode ter tenants que use sua aplicação e uma certa funcionalide que venha a ocasionar o chargeback, por isso o kung disse, aplicações monolítica é complicado em arquitetura multi-tenant.

A divisão do banco de dados para cada tenant ou um banco de dados e N tenants, depende também do seu cliente e a forma de como você quer entregar isso para ele, na minha opinião se o seu cliente é o mesmo e possui escritórios espalhados geograficamente pelo o globo talvez seja mais fácil voce projetar um armazenamento único dividindo ele apenas em uma instância diferente de cloud, caso seja necessário e matendo todos no mesmo contexto. Apenas atento a funcionalidade em que você pode torna-los um serviço e talvez voce possa ter um contexto somente para aquelas funcionalidade ou um grupo das mesmas.

Agora se seu aplicativo é para atender vários clientes com missão,objetivos e processos organizacionais diferentes, acho melhor cada um ficar com sua própria cópia de banco, seu próprio contexto e sua própria instância do cloud.

Bom a criatividade é bem grande.

Com certeza não tirei sua dúvida e nem te ajudei, mas eu tenho essa visão.

Abraço.

 
Avatar sérgio lopes
51 mensagens

O AppEngine anunciou ontem umas facilidades para trabalhar com multitenant na mesma aplicação, separando apenas persistência, cache etc

http://code.google.com/appengine/docs/java/mult…

 
Avatar Guilherme Si...
Líder técnico
353 mensagens

A api do google parece ser suja (ThreadLocal?) mas efetiva, com certeza. É a vantagem de uma abordagem que já provê a infra e a plataforma como serviço: já está nos dando a plataforma para multitenancy também. Muito bom, já está usando Sergio?

 
Avatar sérgio lopes
51 mensagens

Não usei, não tenho nenhuma app que precise disso…

 
Avatar mauricioaniche
26 mensagens

Existe um artigo muito bom no MSDN chamado “Multi tenant Data Architecture”, que discute isso: http://msdn.microsoft.com/en-us/library/aa47908…

Estou passando pelo mesmo problema ultimamente. Meu sentimento atual sobre isso é:

1) O ideal seria realmente um cloud por cliente. Além de cada cliente estar realmente isolado um do outro, você pode se proteger de outros problemas como deploys problemáticos, utilizando estratégias como blue-green deployment (http://martinfowler.com/bliki/BlueGreenDeployme…. O processo de deploy é mais chato, mas com um pouco de tempo pode ser totalmente automatizado.

Mas como o Guilherme disse, sai caro. A máquina mais simples oferecida hoje ainda seria sub-utilizada.

2) Uma aplicação com uma base é a solução mais simples para se implementar. Mas a ideia de misturar os dados de todo mundo não me agrada muito (no meu caso estou trabalhando com dados sigilosos). Além disso, segurança e backup/restore de dados por tenant é um trabalho um pouco assustador! :)

3) Uma aplicação e vários bancos gera uma pequena complicação na parte técnica, afinal, como o Sérgio levantou, você passa a ser obrigado a ficar trocando a base o tempo todo. Além disso o deploy é chato, pois você tem que rodar suas migrations em todas bases. Eu estou arriscando ir por esse caminho. O spike que fiz apenas mostrou que isso vai funcionar, mas preciso medir melhor. Assim que tiver novidades, volto aqui!

 
Avatar sérgio lopes
51 mensagens

Várias pessoas já argumentaram aqui que um dos maiores motivos para se fazer multitenant com bancos separados é segurança, apesar de ficar 10x mais complicado. Eu acho bem estranha essa preocupação grande com segurança, como se houvesse alguma implicação a mais só por ser multitenant. Toda aplicação deve ser segura, não interessa se tá no mesmo banco de dados, se são clientes separados ou qualquer coisa do tipo.

Fico imaginando uma aplicação de Banco onde temos milhões de correntistas cadastrados na mesma base de dados e cada um fazendo suas operações de forma segura. Se realmente precisasse quebrar em vários bancos para ser seguro, um Banco estava ferrado, precisaria de milhões de bases diferentes.

No fundo o que quero dizer é que multitenant não traz requisitos a mais de segurança do que qualquer outra aplicação. Se alguém acha isso talvez precisasse dar um tapinha na segurança das suas aplicações não-multitenant :)

Formatação

Faça o login

CADASTRE-SE AGORA

. .