Multi-Tenancy | Principio de arquitectura de software

La llegada de la nube ha cambiado para siempre la forma en que consumimos software, pasando de tener que instalar una aplicación en nuestro equipo, ha simplemente acceder a un sitio web para tener acceso a toda nuestra información, pero la pregunta clave aquí es, ¿cómo es que una aplicación que vive en la nube, puede albergar múltiples clientes y al mismo tiempo mantener separada la información? Bueno, para resolver esta pregunta tenemos el termino Multi-Tenancy.

Multi-Tenancy es un principio de arquitectura de software donde una aplicación puede albergar a múltiples clientes, de esta forma, todos trabajan sobre la misma instancia de software que se ejecuta en el mismo servidor, con la única diferencia de que los datos que pueden ver cada cliente son diferentes, logrando un efecto en el que la aplicación se pueden ver como si fuera construida exclusivamente para uno de ellos.

Para poner un ejemplo claro de Multi-Tenancy que todos podremos comprender, hablemos de Gmail. Seguramente todos aquí tenemos una cuenta de correo en esta aplicación, sin embargo, cuando entramos solo podemos ver nuestros correos, a pesar de que seguramente existen millones de correos electrónicos en toda la plataforma. De esta misma forma, podemos personalizar la forma en que se visualiza la página, ya que podemos cambiar la forma en que organizamos los correos, las carpetas, colores, logotipo (si es una cuenta empresarial), etc. Sin embargo, cada una de estar personalizaciones solo podrán ser observadas por el dueño de ese cliente y nada más.

Multi-Tenancy hace posible que existan muchas de las aplicaciones que hoy conocemos como SaaS ( Software as a Service), en la cual pagamos (o no) una renta mensual para utilizar, como puede ser el mismo Gmail, Trello, Netflix, YouTube, Salesforce, Twitter, Facebook, etc.

La pregunta ahora es, como es que estas aplicaciones logran separar la información de sus clientes. Para empezar, sería buen aterrizar el termino Multi-Tenancy, que si lo traducimos al español sería algo así como “Multi inquilino” o “Multi usuario”.  Una aplicación Multi-Tenancy la podemos comparar con un edificio de apartamentos, donde todos los inquilinos viven en el mismo edificio, utilizan la infraestructura general de este, como lo es, personal de seguridad, áreas comunes,  elevadores, etc., sin embargo, y a pesar de que viven en el mismo edificio, no viven en el mismo lugar, pues cada uno tiene su propio apartamento, donde pueden guardar sus pertenencias de forma seguras, y la única personas que puede acceder, sería su dueño(s).

Siguiendo esta misma analogía en una aplicación Multi-Tenancy, el edificio completo sería la aplicación, y cada apartamento sería su información. En este sentido, podrás observar que todos los usuarios hacen uso de la misma aplicación,  pero la información permanece asilada entre los diferentes usuarios.

Creo que a nivel conceptual esto puede resultar fácil de entender, sin embargo, implementarlo en una aplicación real no es tan simple, ya que hay que tener mucho cuidado de aislar correctamente la información de los diferentes usuarios, ya que de lo contrarios, estaríamos exponiendo información privada a otros usuarios.

Formas de implementar una aplicación Multi-Tenancy

Básicamente existen tres formas de lograr que una aplicación sean Multi-Tenancy, las cuales son las siguientes:

DB y esquema compartidos (Shared DB, Shared Schema)

Este es la forma más simple de crear una aplicación Multi-Tenancy, la cual consiste en compartir una misma base de datos y esquema para todos los usuarios registrados:

Para lograr la separación de la información, se suele segmentar la información por columnas en la DB, de esta forma, cada registro indica a que Empresa o usuario pertenece y cada uno de los Query que lancemos a la base de datos deberá de contemplar este campo dentro del WHERE, para evitar que la información se mescle:

SELECT * FROM ORDERS WHERE TENANT = ?

En este caso, el WHERE es la única forma de segmentar la información, ya que en caso de omitir ese filtro, se podría mostrar información de todos los demás clientes, o incluso, borrar datos que no son de ese cliente en particular.

Solo por poner un ejemplo, mi plataforma de cursos Codmind yo la he construido desde cero utilizando esta estrategia, ya que en una sola base de datos tengo la información de todos mis clientes, separando la información por el ID del usuario.

Ventajas:

  • Fácil de implementar: como lo mencioné al inicio, este método es el más simple, pues con solo agregar filtrar los registros mediante una columna, es posible segmentar la información.
  • Cero configuraciones: Cada que un nuevo cliente se registra, solo hace falta registrarlo en la DB y comenzar a segmentar su información según su TenantID.
  • Fácil de mantener: Dado que solo tenemos una DB, es muy simple darle mantenimiento y respaldar la información.

Desventajas:

  • Aislamiento: Dado que toda la información está en la misma base de datos, es mas propenso a que mesclemos información de los clientes.
  • Seguridad: Si el acceso a los datos se ve comprometida, el atacante tiene acceso a la información de todos los clientes. Por otra parte, cuando le damos acceso a un programador a la DB, automáticamente tiene acceso a la información de todos los clientes, aun cuando solo quiera analizar un problema con un cliente determinado.
  • Escalamiento: Dado que toda la información vive en una sola DB, es escalamiento se ve limitado hasta el número de transacciones que un solo manejador de base de datos pueda soportar.
  • Disponibilidad: La disponibilidad entera de la aplicación depende de una sola base de datos, por lo que si se cea, todo el sistema se muere.

DB compartida, diferente Schema

Este método es muy similar al anterior, ya que los clientes comparten la base de datos, con la única diferencia de que la información se almacena en schemas diferentes:

Esta técnica permite un mejor aislamiento de la información, pues cada schema tiene un usuario diferente y cada uno de estos tiene una replica de las tablas, por lo que ya no es necesario segmentar la información mediante el WHERE del query, en su lugar, el reto consiste en conectarnos al Schema correcto según el cliente que está realizando la solicitud.

Ventajas:

  • Mejor Aislamiento: Esta técnica tiene un mejor aislamiento que la estrategia anterior, pues cada cliente tendrá su propio schema, sin embargo, aun tenemos el problema de que con un usuario administrado de la DB es posible acceder a todos los Schemas.
  • Optimización de la infraestructura: Dado que varios clientes pueden utilizar la misma base de datos, es posible compartir los recursos del servidor, de esta forma, si un cliente tiene poca demanda, deja los recursos para los clientes que consumen mas recursos, de esta forma evitamos tener recursos no utilizados y que estemos pagando.
  • Escalamiento: Dado que las conexiones son por schema, esto permite tener múltiples bases de datos con múltiples schemas, por lo que podemos crear más servidores de base de datos a medida que el número de clientes aumenta.

Desventajas:

  • Mantenimiento: Al tener múltiples schemas, es necesario crear mecanismos que creen los schemas de forma automática cuando un nuevo cliente se registre, además de que hay que darles soporte de forma separada.
  • Respaldo: El respaldo de vuele una tarea un poco más complicada, porque ahora hay que gestionar un respaldo por cada schema.
  • Configuración: Debemos preparar al sistema para conectarse dinámicamente a diferentes fuentes de datos, lo que puede representar un reto de ingeniería del lado del servidor.

Una base de datos por Inquilino (Database per Tenant)

Esta técnica consiste en que cada cliente utiliza una base de datos totalmente separada, lo que implica que tengamos una base de datos por cliente

Esta es la estrategia que permite el mayor nivel de aislamiento y seguridad, pues separar por completo la información de cada usuario en su propia base de datos, pero también implica el mayor esfuerzo en configuración, pues se tendrá que crear una nueva base de datos por cada cliente que se registre. Además, cada servidor de base de datos consume recurso del lado del servidor, los cuales estarán reservados, los utilice o no.

 Ventajas:

  • Seguridad: Dado que cada base de datos es independiente, proporciona el mejor nivel de seguridad, pues de comprometerse una base de datos, solo afectará a un cliente y no a todos.
  • Aislamiento: relacionado con el anterior, cada base de datos contiene la información de un solo cliente, lo que hacer muy difícil mesclar información entre clientes.
  • Escalamiento: Dado que cada cliente utiliza su propia base de datos, es posible escalar los recursos de cada cliente a medida que estos crecen. Además, la carga de la base de datos no se comparte entre clientes, pues cada uno tiene su propia base de datos.
  • Disponibilidad: Dado que cada cliente tiene su propia base de datos, si alguna se cae, no afecta al resto de clientes.

Desventajas:

  • Mantenimiento: Las múltiples instancias de las bases de datos hace más complicado el mantenimiento, pues se tendrá que cuidar N servidor de base de datos.
  • Respaldo: Hacer respaldos se hace una tarea complicada, pues habrá que configurar proceso que se conecten a múltiples servidores para hacer los respaldos.
  • Configuración: En esta arquitectura no basta con clonar los schemas, si no que es necesario levantar dinámicamente más servidores que alberguen las nuevas bases de datos.
  • Costo: Dado que es necesario tener bases de datos separadas, también será necesario contar con servidores de base datos separados, lo que puede incrementar los costos operativos.
¿Quieres aprender más principios de diseño y patrones arquitectónicos como este que acabas de ver y convertirte en arquitecto de software? Te invito a que veas mi libro de Arquitectura de software, el mejor libro en español.

Conclusiones

Las aplicaciones Multi-Tenancy llegaron para quedarse, incluso, creo que en un futuro, todas las aplicaciones que utilizaremos serán bajo este principio, ya que nos permite accederlas desde cualquier lugar y cualquier equipo, algo muy diferente a las aplicaciones a las aplicaciones convencionales, donde tenemos que estar en la computadora donde instalamos el software o de lo contrario no tenemos acceso ni al software, ni a la información. Otra de las ventajas que ofrece es que no requiere configuración e incluso, muchas de las veces son gratuitas, o al menos hasta cierto tiempo o uso.

Creo que hoy en día, todos los productos de software que creemos, deberán estar enfocados al Multi-Tenancy, ya que nos permite llegar a más clientes, además que el modelo por suscripción ha demostrado ser más rentable que el pagar una cuota fina por licencia (sin contar que evitamos la piratería).

NOTA: Estoy pensando en escribir un artículo de como implementar un sistema Multi-Tenancy usando Spring Boot, así que si te interesaría que lo escribiera, me gustaría que me lo comentaras, así puede que me anime a crearlo.

16 thoughts to “Multi-Tenancy | Principio de arquitectura de software”

  1. Excelente articulo, en cierta ocasión crea un sistema SaaS de los que mencionas, lo que hacía era que tenía el backup del esquema principal (sin data, solo la estructura) y lo tomaba desde backend y lo ejecutaba y este creaba el esquema propio para cada cliente.
    Puedes hacer el vídeo de la implementación si deseas, me encantaría verlo.

  2. Muy bueno el artículo, justo estoy en un proyecto donde se utiliza la misma app para un grupo de empresas. Lo que hacemos es replicar tanto la app como la base para cada empresa y no me convence la metodología dado que se complica el mantenimiento de la app y la infra. Me gustaría mucho ver un ejemplo en sprint boot.
    Muchas gracias por compartir tu conocimiento

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *