Como criar um banco de dados multilocatário com estruturas de tabela compartilhadas?

129

Atualmente, nosso software é executado no MySQL. Os dados de todos os inquilinos são armazenados no mesmo esquema. Como estamos usando Ruby on Rails, podemos determinar facilmente quais dados pertencem a qual inquilino. Entretanto, é claro que algumas empresas temem que seus dados sejam comprometidos, por isso estamos avaliando outras soluções.

Até agora, vi três opções:

  • Multi-banco de dados (cada inquilino obtém o seu próprio - quase o mesmo que 1 servidor por cliente)
  • Multi-esquema (não disponível no MySQL, cada inquilino obtém seu próprio esquema em um banco de dados compartilhado)
  • Esquema compartilhado (nossa abordagem atual, talvez com registro de identificação adicional em cada coluna)

O esquema múltiplo é o meu favorito (considerando os custos). No entanto, criar uma nova conta e fazer migrações parece bastante doloroso, porque eu teria que repetir todos os esquemas e alterar suas tabelas / colunas / definições.

P: O esquema múltiplo parece ter sido projetado para ter tabelas ligeiramente diferentes para cada inquilino - não quero isso. Existe algum RDBMS que me permita usar uma solução de vários inquilinos com vários esquemas, em que a estrutura da tabela é compartilhada entre todos os inquilinos?

PS Por multi, quero dizer algo como ultra-multi (10.000+ inquilinos).

Marcel Jackwerth
fonte
1
"O esquema múltiplo parece ter sido projetado para ter tabelas ligeiramente diferentes para cada inquilino" Então? O que há de errado com o esquema múltiplo e as mesmas tabelas? Você está dizendo que não deseja recriar estruturas de tabela idênticas em todos os esquemas? Ou você está dizendo que não pode criar estruturas idênticas em todos os esquemas?
S.Lott 6/02
+1 para uma pergunta boa / interessante
AdaTheDev
2
@ S.Lott Espero mais de 10.000 inquilinos com mais de 100 inscrições por dia. Ter milhões de entradas em uma única definição de tabela (definition = shared, data = isolated) me faz sentir melhor do que ter milhares de entradas em milhares de definições de tabela. Como poucas pessoas estão fazendo dessa maneira, não tenho tanta confiança no esquema múltiplo.
Marcel Jackwerth
1
Eu concordo com Daniel, o banco de dados múltiplo é excluído com base nesses números. Atualizei minha resposta para refletir isso, mas mantendo-a mais para a história. A abordagem compartilhada parece definitivamente a abordagem mais razoável.
AdaTheDev
2
de dynjo em uma resposta: " Ótimo artigo de Ryan Bigg sobre o assunto exato"
Félix Gagnon-Grenier

Respostas:

95

Entretanto, é claro que algumas empresas temem que seus dados sejam comprometidos, por isso estamos avaliando outras soluções.

Isso é lamentável, pois os clientes às vezes sofrem de um equívoco de que apenas o isolamento físico pode oferecer segurança suficiente.

Há um artigo interessante do MSDN, intitulado Arquitetura de dados com vários locatários , que você pode verificar. Foi assim que os autores abordaram o equívoco em relação à abordagem compartilhada:

Um equívoco comum sustenta que apenas o isolamento físico pode fornecer um nível apropriado de segurança. De fato, os dados armazenados usando uma abordagem compartilhada também podem fornecer segurança de dados forte, mas requerem o uso de padrões de design mais sofisticados.

Quanto às considerações técnicas e comerciais, o artigo faz uma breve análise sobre onde uma determinada abordagem pode ser mais apropriada que outra:

O número, a natureza e as necessidades dos inquilinos que você espera atender afetam sua decisão de arquitetura de dados de maneiras diferentes. Algumas das perguntas a seguir podem direcioná-lo para uma abordagem mais isolada, enquanto outras podem direcioná-lo para uma abordagem mais compartilhada.

  • Quantos inquilinos em potencial você espera atingir? Você pode estar longe de ser capaz de estimar o uso potencial com autoridade, mas pense em termos de ordem de grandeza: você está criando um aplicativo para centenas de inquilinos? Milhares? Dezenas de milhares? Mais? Quanto maior você espera que sua base de locatários, maior a probabilidade de você considerar uma abordagem mais compartilhada.

  • Quanto espaço de armazenamento você espera que os dados do inquilino médio ocupem? Se você espera que alguns ou todos os inquilinos armazenem quantidades muito grandes de dados, a abordagem de banco de dados separado é provavelmente a melhor. (De fato, os requisitos de armazenamento de dados podem forçar você a adotar um modelo de banco de dados separado de qualquer maneira. Nesse caso, será muito mais fácil projetar o aplicativo dessa maneira desde o início do que passar para uma abordagem de banco de dados separado posteriormente.)

  • Quantos usuários finais simultâneos você espera que o inquilino médio ofereça suporte? Quanto maior o número, mais apropriada será uma abordagem mais isolada para atender aos requisitos do usuário final.

  • Você espera oferecer serviços de valor agregado por inquilino, como capacidade de backup e restauração por inquilino? Esses serviços são mais fáceis de oferecer por meio de uma abordagem mais isolada.


UPDATE: Mais para atualizar sobre o número esperado de inquilinos.

Esse número esperado de inquilinos (10k) deve excluir a abordagem de vários bancos de dados, para a maioria, se não todos os cenários. Não acho que você goste da idéia de manter 10.000 instâncias de banco de dados e ter que criar centenas de novas diariamente.

Somente a partir desse parâmetro, parece que a abordagem de esquema único de banco de dados compartilhado é a mais adequada. O fato de você estar armazenando apenas cerca de 50 Mb por inquilino e de que não haverá complementos por inquilino torna essa abordagem ainda mais apropriada.

O artigo MSDN citado acima menciona três padrões de segurança que abordam considerações de segurança para a abordagem de banco de dados compartilhado:

Quando você estiver confiante com as medidas de segurança de dados do seu aplicativo, poderá oferecer a seus clientes um Agregado de Nível de Serviço que fornece fortes garantias de segurança de dados. No seu SLA, além das garantias, você também pode descrever as medidas que você adotaria para garantir que os dados não sejam comprometidos.

ATUALIZAÇÃO 2: Aparentemente, os caras da Microsoft mudaram / criaram um novo artigo sobre esse assunto, o link original desapareceu e este é o novo: Padrões de locação de banco de dados SaaS com vários locatários (parabéns a Shai Kerer)

Daniel Vassallo
fonte
1
Oh, eu digitalizei o artigo ontem e pulei essa parte do equívoco. Precisa ler novamente.
Marcel Jackwerth
1
@Marcel: No entanto, além da percepção de segurança dos clientes, acredito que sua decisão sobre qual abordagem de vários inquilinos deve ser baseada em fatores como os quatro pontos citados no artigo do MSDN: 1. Número esperado de inquilinos . - 2. Requisito de armazenamento esperado para cada inquilino. - 3. Número esperado de usuários finais simultâneos. - 4. Addons esperados por inquilino.
Daniel Vassallo
1
Obrigado por apontar essa seção. Número = 10k, Armazenamento = 50mb, Usuários finais simultâneos = 2 por inquilino, Complementos = 0. Portanto, a situação atual com uma abordagem compartilhada parece ser a mais razoável. Acho que farei algumas ligações na próxima semana para descobrir o que os clientes realmente precisam / esperam. A Alemanha e a segurança de dados / TI são uma história muito difícil.
Marcel Jackwerth
1
Só para os usuários que estão lendo isso a partir de agora, o artigo mencionado não existe mais, alguém fez uma cópia, talvez?
gmslzr
1
@guillesalazar Não sei se é o mesmo, mas acho que é - docs.microsoft.com/en-us/azure/sql-database/… (@DanielVassallo, se é o mesmo, talvez considere atualizar o link no seu resposta :-))
Shai Kerer
20

Minha experiência (embora SQL Server) é que o banco de dados múltiplo é o caminho a percorrer, onde cada cliente tem seu próprio banco de dados. Portanto, embora eu não tenha experiência com mySQL ou Ruby On Rails, espero que minha entrada possa agregar algum valor.

As razões pelas quais incluem:

  1. segurança de dados / recuperação de desastres. Os dados de cada empresa são armazenados inteiramente separadamente dos outros, o que reduz o risco de comprometimento dos dados (pensando em coisas como se você introduzir um bug de código que significa que algo olha erroneamente para outros dados do cliente quando não deveria), minimiza a perda potencial para um cliente, se houver. um banco de dados específico é corrompido etc. Os benefícios de segurança percebidos para o cliente são ainda maiores (efeito colateral adicional adicionado!)
  2. escalabilidade. Basicamente, você particionaria seus dados para permitir maior escalabilidade - por exemplo, os bancos de dados podem ser colocados em diferentes discos, você pode colocar vários servidores de banco de dados on-line e mover os bancos de dados com facilidade para espalhar a carga.
  3. ajuste de desempenho. Suponha que você tenha um cliente muito grande e um muito pequeno. Os padrões de uso, volumes de dados etc. podem variar bastante. Você pode ajustar / otimizar mais fácil para cada cliente, se necessário.

Espero que isso ofereça alguma contribuição útil! Há mais razões, mas minha mente ficou em branco. Se ele voltar, atualizarei :)

EDIT:
Desde que publiquei esta resposta, agora está claro que estamos falando de mais de 10.000 inquilinos. Minha experiência está em centenas de bancos de dados de grande escala - não acho que 10.000 bancos de dados separados sejam muito gerenciáveis ​​para o seu cenário; portanto, agora não estou favorecendo a abordagem multi-db para o seu cenário. Especialmente agora que está claro que você está falando de pequenos volumes de dados para cada inquilino!

Mantendo minha resposta aqui da maneira que for, pois pode ser útil para outras pessoas em um barco semelhante (com menos inquilinos)

AdaTheDev
fonte
Sim, desculpe por não ter esclarecido isso antes. Ainda +1. ;)
Marcel Jackwerth
falando sobre segurança de dados, você diria que cada banco de dados deve ser colocado em servidores / VMs separados? ou ter todos os bancos de dados em um servidor único / clusterizado com diferentes usuários sql é seguro o suficiente?
Shay
@ Shay - Não, não deve ser necessário colocá-los em servidores separados - imagine que você tenha 100 anos, ou seja, muitas instâncias / licenças de servidor que você precisa para começar. Veja a resposta de Daniel mais adiante, há alguns bons links lá.
AdaTheDev 8/06
Eu argumentaria que, mesmo que multi-DB signifique 10.000 bancos de dados separados e aumente significativamente o custo de manutenção, você ainda pode domesticar essa fera usando scripts de automação em sua infraestrutura de nuvem, de modo que tudo se torne gerenciado programaticamente, exigindo pouco ou nenhum esforço humano.
Korayem
17

Abaixo está um link para um white paper no Salesforce.com sobre como eles implementam a multilocação:

http://www.developerforce.com/media/ForcedotcomBookLibrary/Force.com_Multitenancy_WP_101508.pdf

Eles têm uma tabela enorme com 500 colunas de cadeia (Valor0, Valor1, ... Valor500). Datas e números são armazenados como seqüências de caracteres em um formato para que possam ser convertidos em seus tipos nativos no nível do banco de dados. Existem tabelas de metadados que definem a forma do modelo de dados que pode ser exclusivo por inquilino. Existem tabelas adicionais para indexação, relacionamentos, valores exclusivos etc.

Por que o aborrecimento?

Cada inquilino pode personalizar seu próprio esquema de dados em tempo de execução sem precisar fazer alterações no nível do banco de dados (alterar tabela, etc.). Esta é definitivamente a maneira mais difícil de fazer algo assim, mas é muito flexível.

dana
fonte
10

Como você mencionou, o único banco de dados por inquilino é uma opção e possui algumas vantagens maiores. Pode funcionar bem em menor escala, como um único dígito ou poucos 10 inquilinos, mas além disso fica mais difícil de gerenciar. Tanto as migrações, mas também a manutenção dos bancos de dados.

O modelo por esquema não é útil apenas para esquemas exclusivos para cada um, embora ainda seja difícil executar migrações em todos os inquilinos e, a milhares de esquemas, o Postgres pode começar a ter problemas.

Uma abordagem mais escalável é absolutamente ter inquilinos distribuídos aleatoriamente, armazenados no mesmo banco de dados, mas em diferentes shards lógicos (ou tabelas ). Dependendo do seu idioma, existem várias bibliotecas que podem ajudar com isso. Se você estiver usando o Rails, há uma biblioteca para garantir a locação acts_as_tenant, isso ajuda a garantir que as consultas do inquilino apenas retirem esses dados. Há também uma jóia apartment- embora ele use o modelo de esquema, ele ajuda nas migrações em todos os esquemas. Se você estiver usando o Django, há um número, mas um dos mais populares parece estar entre os esquemas . Tudo isso ajuda mais no nível do aplicativo. Se você estiver procurando algo mais diretamente no nível do banco de dados, a Citus se concentra em fazer esse tipo de sharding paraa multilocação trabalhe mais fora da caixa com o Postgres.

CraigKerstiens
fonte