Qual é a abordagem recomendada para bancos de dados multilocatários no MongoDB?


98

Estou pensando em criar um aplicativo multilocatário usando MongoDB. Não tenho nenhuma estimativa em termos de quantos inquilinos eu ainda teria, mas gostaria de poder chegar aos milhares.

Posso pensar em três estratégias:

  1. Todos os inquilinos na mesma coleção, usando campos específicos do inquilino para segurança
  2. 1 coleção por inquilino em um único banco de dados compartilhado
  3. 1 banco de dados por locatário

A voz na minha cabeça está sugerindo que eu escolha a opção 2.

Pensamentos e implicações, alguém?


Caro @Braintapper, estamos na mesma situação agora com nosso aplicativo que precisa ser multilocatário. Você tem alguma experiência para compartilhar? Seria ótimo, obrigado.
Joshua Muheim

3
Para meu aplicativo, acabei optando pelo Postgresql (obtemos o benefício de um banco de dados relacional com algumas funcionalidades semelhantes a NoSQL por meio da extensão hstore) em vez do MongoDB e gerenciando multilocação em Rails com escopo. Usamos uma abordagem similar àquela usada neste Railscast: railscasts.com/episodes/388-multitenancy-with-scopes
Braintapper

2
Eu sei que uma resposta já foi escolhida para esta questão, mas qualquer pessoa deve consultar este documento oficial no site mongohq: support.mongohq.com/use-cases/multi-tenant.html . Ele defende claramente a solução @Braintapper abaixo
lafama

1
Resposta atualizada. As informações em seu link não estavam prontamente disponíveis em maio de 2010.
Braintapper

@Braintapper você está usando a solução postgresql (baseada em railscasts.com) agora? Quero usá-lo, mas não tenho certeza se adiciona segurança e quantos inquilinos ele pode suportar! por favor, preciso de seus comentários sobre esta experiência. obrigado
medBouzid

Respostas:


71

Tenho o mesmo problema para resolver e também considerando variantes. Como tenho anos de experiência na criação de aplicativos SaaS multi-tenant, também selecionaria a segunda opção com base em minha experiência anterior com bancos de dados relacionais.

Enquanto fazia minha pesquisa, encontrei este artigo no site de suporte do mongodb (adicionado há muito tempo): https://web.archive.org/web/20140812091703/http://support.mongohq.com/use-cases/multi -tenant.html

Os caras declararam evitar as segundas opções a qualquer custo, o que, pelo que entendi, não é particularmente específico para mongodb. Minha impressão é que isso é aplicável para a maioria dos bancos de dados NoSQL que pesquisei (CoachDB, Cassandra, CouchBase Server, etc.) devido às especificações do design do banco de dados.

Coleções (ou depósitos ou como eles chamam em bancos de dados diferentes) não são a mesma coisa que esquemas de segurança em RDBMS, apesar de se comportarem como contêineres para documentos, eles são inúteis para aplicar uma boa separação de inquilino. Não consegui encontrar o banco de dados NoSQL que pode aplicar restrições de segurança com base em coleções.

Claro que você pode usar a segurança baseada em função mongodb para restringir o acesso no nível do banco de dados / servidor. ( http://docs.mongodb.org/manual/core/authorization/ )

Eu recomendaria a 1ª opção quando:

  • Você tem tempo e recursos suficientes para lidar com a complexidade do design, implementação e teste deste cenário.
  • Se você não vai ter muitas diferenças na estrutura e funcionalidade do banco de dados para diferentes inquilinos.
  • O design do seu aplicativo permitirá que os locatários façam apenas personalizações mínimas no tempo de execução.
  • Se você deseja otimizar espaço e minimizar o uso de recursos de hardware.
  • Se você vai ter milhares de inquilinos.
  • Se você deseja expandir rapidamente e com bom custo.
  • Se você NÃO vai fazer backup de dados com base em locatários (mantenha backups separados para cada locatário). É possível fazer isso mesmo nesse cenário, mas o esforço será enorme.

Eu escolheria a variante 3 se:

  • Você terá uma pequena lista de inquilinos (várias centenas).
  • As especificidades do negócio exigem que você seja capaz de suportar grandes diferenças na estrutura do banco de dados para diferentes locatários (por exemplo, integração com sistemas de terceiros, importação-exportação de dados).
  • O design do seu aplicativo permitirá que os clientes (locatários) façam mudanças significativas no tempo de execução do aplicativo (adicionando módulos, personalizando os campos, etc.).
  • Se você tiver recursos suficientes para escalar horizontalmente com novos nós de hardware rapidamente.
  • Se você for obrigado a manter versões / backups de dados por locatário. Além disso, a restauração será fácil.
  • Existem restrições legais / regulatórias que o obrigam a manter diferentes locatários em diferentes bancos de dados (até mesmo centros de dados).
  • Se você deseja utilizar totalmente os recursos de segurança prontos para uso do mongodb, como funções.
  • Existem grandes diferenças quanto ao tamanho entre os locatários (você tem muitos locatários pequenos e poucos locatários muito grandes).

Se você postar detalhes adicionais sobre sua inscrição, talvez eu possa lhe dar conselhos mais detalhados.


9
Acho que o link original está morto, fui para o arquivado: web.archive.org/web/20140812091703/http://support.mongohq.com/…
Peter

Olá, Como podemos criar um novo banco de dados com o banco de dados atual usando mongodb?
HEMAL

@Russian Como lidaremos com a indexação se optarmos por 1
Robins Gupta

10

Encontrei uma boa resposta nos comentários deste link:

http://blog.boxedice.com/2010/02/28/notes-from-a-production-mongodb-deployment/

Basicamente, a opção nº 2 parece ser a melhor opção.

Citação do comentário de David Mytton:

Decidimos não ter um banco de dados por cliente devido à maneira como o MongoDB aloca seus arquivos de dados. Cada banco de dados usa seu próprio conjunto de arquivos:

O primeiro arquivo para um banco de dados é dbname.0, depois dbname.1, etc. dbname.0 terá 64 MB, dbname.1 128 MB, etc., até 2 GB. Quando os arquivos atingem 2 GB de tamanho, cada arquivo sucessivo também tem 2 GB.

Portanto, se o último arquivo de dados presente for, digamos, 1 GB, esse arquivo pode estar 90% vazio se tiver sido acessado recentemente.

do manual.

À medida que os usuários se inscrevem no teste e experimentam, obteríamos mais e mais bancos de dados com pelo menos 2 GB de tamanho, mesmo que todo o arquivo de dados não fosse usado. Descobrimos que isso usava uma grande quantidade de espaço em disco em comparação com ter vários bancos de dados para todos os clientes, onde o espaço em disco pode ser usado com eficiência máxima.

A fragmentação ocorrerá por coleção como padrão, o que apresenta um problema em que a coleção nunca atinge o tamanho mínimo para iniciar a fragmentação, como é o caso de alguns dos nossos (por exemplo, coleções apenas armazenando detalhes de login do usuário). No entanto, solicitamos que isso também possa ser feito no nível do banco de dados. Veja http://jira.mongodb.org/browse/SHARDING-41

Não há compensações de desempenho usando muitas coleções. Consulte http://www.mongodb.org/display/DOCS/Using+a+Large+Number+of+Collections


2
Conforme sugerido em outras respostas, o nº 2 não é uma boa abordagem. Considere alterar a resposta aceita, porque isso pode deixar de levar outros desenvolvedores.
clopez

1
Resposta aceita alterada, pois as coisas mudaram significativamente desde 2010, quando a pergunta foi feita pela primeira vez.
Braintapper

3

um artigo razoável no MSDN sobre arquitetura de dados multilocatário que você pode querer consultar. Alguns tópicos principais tocados por este artigo:

  • Considerações econômicas
  • Segurança
  • Considerações do inquilino
  • Regulatório (legal)
  • Preocupações com o conjunto de habilidades

Também abordamos alguns padrões de configuração de Software como Serviço (SaaS).

Além disso, vale a pena dar uma olhada em um artigo interessante do pessoal do SQL Anywhere .

Minha opinião pessoal - a menos que você tenha certeza da segurança / confiança aplicada, eu escolheria a opção 3, ou se as questões de escalabilidade proibirem o fallback para a opção 2, no mínimo. Dito isso ... Não sou profissional com MongoDB. Eu fico muito nervoso usando um "esquema" compartilhado - mas ficarei feliz em adiar para praticantes mais experientes.


Estou familiarizado com esse artigo do MSDN, pois meu plano original era usar um banco de dados relacional. No entanto, meus dados são bastante desestruturados, o que agora me leva a investigar bancos de dados NoSQL como o MongoDB. Não parece que o MongoDB tenha suporte para ACL da mesma forma que o Lotus Domino, e eu realmente não quero reinventar a roda, o que me faz pensar também que 2 ou 3 são o caminho a percorrer. Eu também não sei se há limites que posso encontrar em termos de número de coleções ou dbs permitidos no MongoDB.
Braintapper

3

Eu escolheria a opção 2.

No entanto, você pode definir a opção de linha de comando mongod.exe --smallfiles. Isso significa que o maior tamanho de arquivo de uma extensão será de 0,5 gigabyte e não 2 gigabyte. Eu testei isso com o mongo 1.42. Portanto, a opção 3 não é impossível.



0

De acordo com minha pesquisa no MongoDB. Trucos y consejos. Aplicaciones multitenant. essa opção não é recomendada se você não sabe quantos inquilinos você pode ter, podem ser milhares e seria complicado quando se trata de sharding, imagine também ter milhares de coleções em um único banco de dados ... Então no seu caso. é recomendado usar a opção um. Agora, se você vai ter um número limitado de usuários, já é diferente e sim, você pode usar a opção dois como você pensou.


-2

Embora a discussão aqui seja sobre NoSQL e principalmente sobre MongoDB, nós da Citus estamos usando PostgreSQL e construindo um banco de dados multi-tenant distribuído / fragmentado.

Nosso guia de caso de uso mostra um aplicativo de exemplo, cobrindo o esquema e vários recursos específicos de multilocação.

Para dados mais não estruturados, usamos a coluna JSONB do PostgreSQL para armazenar esses dados específicos do locatário.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.