¿Cuál es el enfoque recomendado para las bases de datos de múltiples inquilinos en MongoDB?

98

Estoy pensando en crear una aplicación multiinquilino usando MongoDB. No tengo ninguna suposición en términos de cuántos inquilinos tendría todavía, pero me gustaría poder escalar a miles.

Puedo pensar en tres estrategias:

  1. Todos los inquilinos de la misma colección, utilizando campos específicos de inquilinos para la seguridad
  2. 1 colección por inquilino en una única base de datos compartida
  3. 1 base de datos por inquilino

La voz en mi cabeza sugiere que opte por la opción 2.

Pensamientos e implicaciones, ¿alguien?

Braintapper
fuente
Estimado @Braintapper, estamos en la misma situación en este momento con nuestra aplicación, que necesita ser habilitada para múltiples inquilinos. ¿Tienes alguna experiencia que compartir? Sería genial, gracias.
Joshua Muheim
3
Para mi aplicación, terminé usando Postgresql (obtenemos el beneficio de una base de datos relacional con alguna funcionalidad similar a NoSQL a través de la extensión hstore) en lugar de MongoDB y manejando la tenencia múltiple en Rails con alcance. Usamos un enfoque similar al utilizado en este Railscast: railscasts.com/episodios/388-multitenancy-with-scopes
Braintapper
2
Sé que ya se ha elegido una respuesta para esta pregunta, pero cualquier otra persona debería consultar este documento oficial en el sitio de mongohq: support.mongohq.com/use-cases/multi-tenant.html . Defiende claramente contra la solución de @Braintapper a continuación
lafama
1
Respuesta actualizada. La información en su enlace no estaba disponible en mayo de 2010.
Braintapper
@Braintapper, ¿está utilizando la solución postgresql (basada en railscasts.com) en este momento? ¡Quiero usarlo, pero no estoy seguro de si agrega seguridad y cuántos inquilinos puede admitir! por favor, necesito sus comentarios sobre esta experiencia. gracias
medBouzid

Respuestas:

71

Tengo el mismo problema por resolver y también considerando variantes. Como tengo años de experiencia en la creación de aplicaciones SaaS multiinquilino, también iba a seleccionar la segunda opción en base a mi experiencia previa con las bases de datos relacionales.

Mientras investigaba, encontré este artículo en el sitio de soporte de mongodb (se agregó mucho desde que desapareció): https://web.archive.org/web/20140812091703/http://support.mongohq.com/use-cases/multi -tenant.html

Los chicos declararon evitar las segundas opciones a toda costa, lo que, según tengo entendido, no es particularmente específico de mongodb. Mi impresión es que esto es aplicable a la mayoría de las bases de datos NoSQL que investigué (CoachDB, Cassandra, CouchBase Server, etc.) debido a las características específicas del diseño de la base de datos.

Las colecciones (o cubos o como lo llamen en diferentes bases de datos) no son lo mismo que los esquemas de seguridad en RDBMS a pesar de que se comportan como contenedores de documentos, son inútiles para aplicar una buena separación de inquilinos. No pude encontrar una base de datos NoSQL que pueda aplicar restricciones de seguridad basadas en colecciones.

Por supuesto, puede usar la seguridad basada en roles de mongodb para restringir el acceso a nivel de base de datos / servidor. ( http://docs.mongodb.org/manual/core/authorization/ )

Recomendaría la primera opción cuando:

  • Tiene suficiente tiempo y recursos para lidiar con la complejidad del diseño, implementación y prueba de este escenario.
  • Si no va a tener muchas diferencias en la estructura y funcionalidad en la base de datos para diferentes inquilinos.
  • El diseño de su aplicación permitirá a los inquilinos realizar solo personalizaciones mínimas en tiempo de ejecución.
  • Si desea optimizar el espacio y minimizar el uso de recursos de hardware.
  • Si vas a tener miles de inquilinos.
  • Si desea escalar rápidamente y a buen costo.
  • Si NO va a realizar una copia de seguridad de los datos según los inquilinos (mantenga copias de seguridad separadas para cada inquilino). Es posible hacerlo incluso en este escenario, pero el esfuerzo será enorme.

Elegiría la variante 3 si:

  • Vas a tener una pequeña lista de inquilinos (varios cientos).
  • Las características específicas del negocio requieren que pueda soportar grandes diferencias en la estructura de la base de datos para diferentes inquilinos (por ejemplo, integración con sistemas de terceros, importación-exportación de datos).
  • El diseño de su aplicación permitirá a los clientes (inquilinos) realizar cambios significativos en el tiempo de ejecución de la aplicación (agregar módulos, personalizar los campos, etc.).
  • Si tiene suficientes recursos para escalar horizontalmente con nuevos nodos de hardware rápidamente.
  • Si es necesario que conserve versiones / copias de seguridad de los datos por inquilino. Además, la restauración será fácil.
  • Existen restricciones legales / regulatorias que le obligan a mantener diferentes inquilinos en diferentes bases de datos (incluso centros de datos).
  • Si desea utilizar completamente las funciones de seguridad listas para usar de mongodb, como roles.
  • Existen grandes diferencias en cuanto al tamaño entre los inquilinos (tiene muchos inquilinos pequeños y pocos inquilinos muy grandes).

Si publica detalles adicionales sobre su solicitud, tal vez pueda darle un consejo más detallado.

Ruslan Kiskinov
fuente
9
Supongo que el enlace original está muerto,
busqué
Hola, ¿Cómo podemos crear una nueva base de datos con la base de datos actual usando mongodb?
HEMAL
@Russian Cómo vamos a manejar la indexación si optamos por 1
Robins Gupta
10

Encontré una buena respuesta en los comentarios de este enlace:

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

Básicamente, la opción 2 parece ser la mejor manera de hacerlo.

Cita del comentario de David Mytton:

Decidimos no tener una base de datos por cliente debido a la forma en que MongoDB asigna sus archivos de datos. Cada base de datos usa su propio conjunto de archivos:

El primer archivo de una base de datos es dbname.0, luego dbname.1, etc. dbname.0 será de 64 MB, dbname.1 128 MB, etc., hasta 2 GB. Una vez que los archivos alcanzan un tamaño de 2 GB, cada archivo sucesivo también tiene 2 GB.

Por lo tanto, si el último archivo de datos presente es, digamos, 1 GB, ese archivo podría estar vacío en un 90% si se alcanzó recientemente.

del manual.

A medida que los usuarios se registran en la versión de prueba y prueban las cosas, obtendríamos más y más bases de datos de al menos 2 GB de tamaño, incluso si no se usaba todo el archivo de datos. Descubrimos que esto usaba una gran cantidad de espacio en disco en comparación con tener varias bases de datos para todos los clientes donde el espacio en disco se puede usar con la máxima eficiencia.

La fragmentación será por colección como estándar, lo que presenta un problema en el que la colección nunca alcanza el tamaño mínimo para comenzar a fragmentar, como es el caso de algunas de las nuestras (por ejemplo, colecciones que solo almacenan los datos de inicio de sesión del usuario). Sin embargo, hemos solicitado que esto también se pueda hacer a nivel de base de datos. Ver http://jira.mongodb.org/browse/SHARDING-41

No hay compensaciones de rendimiento al utilizar muchas colecciones. Ver http://www.mongodb.org/display/DOCS/Using+a+Large+Number+of+Collections

Braintapper
fuente
2
Como se sugiere en otras respuestas, el n. ° 2 no es un buen enfoque. Considere cambiar la respuesta aceptada, ya que esto podría perder el liderazgo de otros desarrolladores.
clopez
1
Se cambió la respuesta aceptada, ya que las cosas han cambiado significativamente desde 2010, cuando se hizo la pregunta por primera vez.
Braintapper
3

Hay un artículo razonable en MSDN sobre la arquitectura de datos de múltiples inquilinos al que quizás desee consultar. Algunos temas clave tratados en este artículo:

  • Consideraciones económicas
  • Seguridad
  • Consideraciones de inquilinos
  • Regulatorio (legal)
  • Preocupaciones sobre el conjunto de habilidades

También se mencionan algunos patrones para la configuración de software como servicio (SaaS).

Además, vale la pena echar un vistazo a un interesante artículo de los chicos de SQL Anywhere .

Mi propia opinión personal: a menos que esté seguro de la seguridad / confianza impuesta, optaría por la opción 3, o si las preocupaciones de escalabilidad prohíben el retorno a la opción 2 como mínimo. Dicho esto ... no soy un profesional con MongoDB. Me pongo bastante nervioso al usar un "esquema" compartido, pero felizmente lo cediré a practicantes más experimentados.

AJ.
fuente
Estoy familiarizado con ese artículo de MSDN, ya que mi plan original era usar una base de datos relacional. Sin embargo, mis datos están bastante desestructurados, lo que ahora me tiene investigando bases de datos NoSQL como MongoDB. No parece que MongoDB tenga soporte ACL como lo hace Lotus Domino, y realmente no quiero reinventar la rueda, lo que me hace pensar que 2 o 3 son el camino a seguir. Sin embargo, tampoco sé si hay límites que pueda encontrar en términos de # de colecciones o dbs permitidos en MongoDB.
Braintapper
3

Yo optaría por la opción 2.

Sin embargo, puede configurar la opción de línea de comando mongod.exe --smallfiles. Esto significa que el tamaño de archivo más grande de una extensión será de 0,5 gigabytes y no de 2 gigabytes. Probé esto con mongo 1.42. Entonces, la opción 3 no es imposible.

TTT
fuente
Solo para que ayude, en retrospectiva: http://yazezo.com/2013/10/how-to-setup-saas-cloud-multi-tenant.html
KMån
0

Según mi investigación en MongoDB. Trucos y consejos. Aplicaciones multiusuario. esa opción no es recomendable si no sabes cuántos inquilinos puedes tener, podrían ser miles y sería complicado a la hora de fragmentar, también imagina tener miles de colecciones en una sola base de datos ... Así que en tu caso se recomienda utilizar la opción uno. Ahora bien, si vas a tener un número limitado de usuarios, ya es diferente y sí, podrías usar la opción dos como pensabas.

Osleynin Mambell Ramos
fuente
-2

Si bien la discusión aquí es sobre NoSQL y principalmente MongoDB, en Citus estamos usando PostgreSQL y construyendo una base de datos de múltiples inquilinos distribuida / fragmentada.

Nuestra guía de casos de uso recorre una aplicación de ejemplo, que cubre el esquema y varias características específicas de múltiples inquilinos.

Para datos más no estructurados, usamos la columna JSONB de PostgreSQL para almacenar dichos datos y los específicos del inquilino.

Sumedh
fuente