¿Cómo crear una base de datos multiinquilino con estructuras de tabla compartidas?

129

Nuestro software actualmente se ejecuta en MySQL. Los datos de todos los inquilinos se almacenan en el mismo esquema. Como estamos utilizando Ruby on Rails, podemos determinar fácilmente qué datos pertenecen a qué inquilino. Sin embargo, hay algunas compañías, por supuesto, que temen que sus datos puedan verse comprometidos, por lo que estamos evaluando otras soluciones.

Hasta ahora he visto tres opciones:

  • Base de datos múltiple (cada inquilino obtiene el suyo, casi lo mismo que 1 servidor por cliente)
  • Multi-Schema (no disponible en MySQL, cada inquilino obtiene su propio esquema en una base de datos compartida)
  • Esquema compartido (nuestro enfoque actual, tal vez con un registro de identificación adicional en cada columna)

Multi-Schema es mi favorito (considerando los costos). Sin embargo, crear una nueva cuenta y realizar migraciones parece ser bastante doloroso, porque tendría que repetir todos los esquemas y cambiar sus tablas / columnas / definiciones.

P: Multi-Schema parece estar diseñado para tener tablas ligeramente diferentes para cada inquilino; no quiero esto. ¿Hay algún RDBMS que me permita usar una solución de múltiples esquemas y múltiples inquilinos, donde la estructura de la tabla se comparte entre todos los inquilinos?

PD Por multi me refiero a algo como ultra-multi (más de 10.000 inquilinos).

Marcel Jackwerth
fuente
1
"Multi-Schema parece estar diseñado para tener tablas ligeramente diferentes para cada inquilino" ¿Entonces? ¿Qué tiene de malo el esquema múltiple y las mismas tablas? ¿Estás diciendo que no quieres recrear estructuras de tabla idénticas en todos los esquemas? ¿O estás diciendo que no puedes crear estructuras idénticas en todos los esquemas?
S.Lott
+1 para una pregunta buena / interesante
AdaTheDev
2
@ S.Lott Espero más de 10.000 inquilinos con más de 100 suscripciones por día. Tener millones de entradas en una sola definición de tabla (definición = compartida, datos = aislado) me hace sentir mejor que tener miles de entradas en miles de definiciones de tabla. Como no muchas personas lo están haciendo de esa manera, no estoy tan seguro con el esquema múltiple.
Marcel Jackwerth
1
Estoy de acuerdo con Daniel, la exclusión de múltiples bases de datos se basa en esas cifras. He actualizado mi respuesta para reflejar eso, pero manteniéndolo más para la historia. El enfoque compartido definitivamente parece el enfoque más razonable.
AdaTheDev
2
de dynjo en una respuesta: " Gran artículo de Ryan Bigg sobre el tema exacto"
Félix Gagnon-Grenier

Respuestas:

95

Sin embargo, hay algunas compañías, por supuesto, que temen que sus datos puedan verse comprometidos, por lo que estamos evaluando otras soluciones.

Esto es lamentable, ya que los clientes a veces sufren de una idea errónea de que solo el aislamiento físico puede ofrecer suficiente seguridad.

Hay un interesante artículo de MSDN titulado Arquitectura de datos de múltiples inquilinos , que quizás desee consultar. Así es como los autores abordaron la idea errónea hacia el enfoque compartido:

Una idea errónea común sostiene que solo el aislamiento físico puede proporcionar un nivel adecuado de seguridad. De hecho, los datos almacenados utilizando un enfoque compartido también pueden proporcionar una seguridad sólida de los datos, pero requieren el uso de patrones de diseño más sofisticados.

En cuanto a las consideraciones técnicas y comerciales, el artículo hace un breve análisis sobre dónde un determinado enfoque podría ser más apropiado que otro:

El número, la naturaleza y las necesidades de los inquilinos a los que espera atender afectan su decisión de arquitectura de datos de diferentes maneras. Algunas de las siguientes preguntas pueden sesgarlo hacia un enfoque más aislado, mientras que otras pueden sesgarlo hacia un enfoque más compartido.

  • ¿A cuántos posibles inquilinos espera apuntar? Es posible que no esté cerca de poder estimar el uso potencial con autoridad, pero piense en términos de órdenes de magnitud: ¿está creando una aplicación para cientos de inquilinos? Miles? ¿Decenas de miles? ¿Más? Cuanto más grande espere que sea su base de inquilinos, más probabilidades tendrá de considerar un enfoque más compartido.

  • ¿Cuánto espacio de almacenamiento espera que ocupen los datos del inquilino promedio? Si espera que algunos o todos los inquilinos almacenen grandes cantidades de datos, el enfoque de base de datos separada es probablemente el mejor. (De hecho, los requisitos de almacenamiento de datos pueden obligarlo a adoptar un modelo de base de datos separada de todos modos. Si es así, será mucho más fácil diseñar la aplicación de esa manera desde el principio que pasar a un enfoque de base de datos separada más adelante).

  • ¿Cuántos usuarios finales concurrentes espera que el inquilino promedio admita? Cuanto mayor sea el número, más apropiado será un enfoque más aislado para cumplir con los requisitos del usuario final.

  • ¿Espera ofrecer algún servicio de valor agregado por inquilino, como la capacidad de respaldo y restauración por inquilino? Dichos servicios son más fáciles de ofrecer a través de un enfoque más aislado.


ACTUALIZAR: más para actualizar sobre el número esperado de inquilinos.

Ese número esperado de inquilinos (10k) debería excluir el enfoque de múltiples bases de datos, para la mayoría, si no todos los escenarios. No creo que le guste la idea de mantener 10,000 instancias de bases de datos y tener que crear cientos de nuevas cada día.

Solo con ese parámetro, parece que el enfoque de esquema único de base de datos compartida es el más adecuado. El hecho de que almacenará aproximadamente 50Mb por inquilino, y que no habrá complementos por inquilino, hace que este enfoque sea aún más apropiado.

El artículo de MSDN citado anteriormente menciona tres patrones de seguridad que abordan las consideraciones de seguridad para el enfoque de base de datos compartida:

Cuando esté seguro de las medidas de seguridad de datos de su aplicación, podrá ofrecer a sus clientes un Acuerdo de nivel de servicio que brinde sólidas garantías de seguridad de datos. En su SLA, además de las garantías, también puede describir las medidas que tomaría para garantizar que los datos no se vean comprometidos.

ACTUALIZACIÓN 2: Al parecer, los chicos de Microsoft se mudaron / hicieron un nuevo artículo sobre este tema, el enlace original desapareció y este es el nuevo: patrones de tenencia de la base de datos SaaS para múltiples inquilinos (felicitaciones a Shai Kerer)

Daniel Vassallo
fuente
1
Oh, escaneé ese artículo ayer y salté esa parte errónea. Necesito leerlo de nuevo.
Marcel Jackwerth
1
@Marcel: Sin embargo, aparte de cuál es la percepción de seguridad de los clientes, creo que su decisión sobre qué enfoque de múltiples inquilinos debe basarse en factores como esos 4 puntos que cité en el artículo de MSDN: 1. Número esperado de inquilinos . - 2. Requisito de almacenamiento esperado para cada inquilino. - 3. Número esperado de usuarios finales concurrentes. - 4. Complementos esperados por inquilino.
Daniel Vassallo
1
Gracias por señalar esa sección. Número = 10k, Almacenamiento = 50mb, Usuarios finales concurrentes = 2 por inquilino, Complementos = 0. Por lo tanto, la situación actual con un enfoque compartido parece ser la más razonable. Creo que haré algunas llamadas la próxima semana para averiguar lo que los clientes realmente necesitan / esperan. Alemania y la seguridad de datos / TI es una historia realmente difícil.
Marcel Jackwerth
1
Solo para los usuarios que lean esto de ahora en adelante, el artículo mencionado ya no existe, ¿alguien hizo una copia, tal vez?
gmslzr
1
@guillesalazar No estoy seguro de que sea el mismo, pero supongo que lo es: docs.microsoft.com/en-us/azure/sql-database/… (@DanielVassallo si es el mismo, quizás considere actualizar el enlace en su respuesta :-))
Shai Kerer
20

Mi experiencia (aunque SQL Server) es que la base de datos múltiple es el camino a seguir, donde cada cliente tiene su propia base de datos. Entonces, aunque no tengo experiencia en mySQL o Ruby On Rails, espero que mi entrada pueda agregar algún valor.

Las razones por las cuales incluyen:

  1. seguridad de datos / recuperación ante desastres. Los datos de cada compañía se almacenan completamente por separado de los demás, lo que reduce el riesgo de que los datos se vean comprometidos (pensar cosas como si introduce un error de código que significa que algo mira erróneamente los datos de otros clientes cuando no debería), minimiza la pérdida potencial para un cliente si uno la base de datos particular se corrompe, etc. Los beneficios de seguridad percibidos para el cliente son aún mayores (¡efecto secundario adicional!)
  2. escalabilidad Esencialmente, estaría particionando sus datos para permitir una mayor escalabilidad; por ejemplo, las bases de datos se pueden colocar en diferentes discos, podría poner en línea múltiples servidores de bases de datos y mover las bases de datos más fácilmente para distribuir la carga.
  3. la optimización del rendimiento. Supongamos que tiene un cliente muy grande y uno muy pequeño. Los patrones de uso, los volúmenes de datos, etc. pueden variar enormemente. Puede ajustar / optimizar más fácilmente para cada cliente si lo necesita.

¡Espero que esto ofrezca información útil! Hay más razones, pero mi mente se quedó en blanco. Si vuelve a funcionar, actualizaré :)

EDITAR:
desde que publiqué esta respuesta, ahora está claro que estamos hablando de más de 10,000 inquilinos. Mi experiencia está en cientos de bases de datos a gran escala: no creo que 10,000 bases de datos separadas sean demasiado manejables para su escenario, por lo que ahora no estoy a favor del enfoque de múltiples bases de datos para su escenario. ¡Especialmente porque ahora está claro que estás hablando de pequeños volúmenes de datos para cada inquilino!

Mantener mi respuesta aquí de todos modos, ya que puede ser útil para otras personas en un bote similar (con menos inquilinos)

AdaTheDev
fuente
Sí, lamento no haberlo aclarado antes. Todavía +1. ;)
Marcel Jackwerth
hablando de seguridad de datos, ¿diría que cada base de datos debe colocarse en servidores / VM separados? ¿o tener todas las bases de datos en un servidor único / agrupado con diferentes usuarios sql es lo suficientemente seguro?
Shay
@Shay: No, no debería tener que colocarlos en servidores separados. Imagine que tiene 100, eso es una gran cantidad de instancias / licencias de servidor que necesitaría para comenzar. Vea la respuesta de Daniel más arriba, hay algunos buenos enlaces allí.
AdaTheDev
Argumentaría que incluso si multi-DB significa 10,000 bases de datos separadas y aumenta significativamente el costo de mantenimiento, aún puede domesticar a esta bestia usando scripts de automatización sobre su infraestructura en la nube de modo que todo se gestione mediante programación, lo que requiere poco o ningún esfuerzo humano
Korayem
17

A continuación se muestra un enlace a un documento técnico en Salesforce.com sobre cómo implementan la tenencia múltiple:

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

Tienen 1 tabla enorme con 500 columnas de cadena (Value0, Value1, ... Value500). Las fechas y los números se almacenan como cadenas en un formato tal que se pueden convertir a sus tipos nativos en el nivel de la base de datos. Hay tablas de metadatos que definen la forma del modelo de datos que pueden ser únicas por inquilino. Hay tablas adicionales para indexación, relaciones, valores únicos, etc.

¿Por qué la molestia?

Cada inquilino puede personalizar su propio esquema de datos en tiempo de ejecución sin tener que hacer cambios a nivel de la base de datos (alterar tabla, etc.). Esta es definitivamente la forma difícil de hacer algo como esto, pero es muy flexible.

dana
fuente
10

Como mencionas, una base de datos por inquilino es una opción y tiene algunas compensaciones más grandes. Puede funcionar bien a menor escala, como un solo dígito o 10 de inquilinos bajos, pero más allá de eso se vuelve más difícil de administrar. Tanto solo las migraciones como también para mantener las bases de datos en funcionamiento.

El modelo por esquema no solo es útil para esquemas únicos para cada uno, aunque seguir ejecutando migraciones en todos los inquilinos se vuelve difícil y en miles de esquemas Postgres puede comenzar a tener problemas.

Un enfoque más escalable es absolutamente tener inquilinos distribuidos aleatoriamente, almacenados en la misma base de datos, pero a través de diferentes fragmentos lógicos (o tablas ). Dependiendo de su idioma, hay varias bibliotecas que pueden ayudarlo. Si está utilizando Rails, hay una biblioteca para prevenir el arrendamiento acts_as_tenant, lo que ayuda a garantizar que sus consultas de inquilinos solo retiren esos datos. También hay una gema apartment, aunque utiliza el modelo de esquema, ayuda con las migraciones en todos los esquemas. Si está utilizando Django, hay un número, pero uno de los más populares parece estar en todos los esquemas . Todo esto ayuda más a nivel de aplicación. Si está buscando algo más en el nivel de la base de datos directamente, Citus se enfoca en hacer este tipo de fragmentación paramulti-tenancy trabaja más fuera de la caja con Postgres.

CraigKerstiens
fuente