Ir al contenido principal

Paralelismo en el Marco de Trabajo

La razón por la que escogí el nombre Lanzador en el articulo anterior, es porque idealmente este componente es ejecutable, y sirve para lanzar instancias del servidor.

Idealmente podemos tener varias instancias, y hacer balance de carga sobre ellas, y mediante el lanzamiento de nuevas instancias podemos escalar el servidor. Idealmente estas instancias no están en la misma maquina.

Tradicionalmente lo que haríamos es crear copias de todo el espacio de trabajo, una en cada instancia. Sin embargo, es posible encontrar particiones (como se entiende en base de datos), y dividir el espacio de trabajo. No es necesario hacer esto. De hecho, incluso si no lo hacemos, podemos dividir el resto del marco de trabajo para conseguir paralelismo.


Otra cosa que debemos considerar, es la posibilidad de utilizar una base de datos distribuida, de forma que podamos agregar nodos instancias a la base de datos. La selección de base de datos no debe tomarse a la ligera, puesto que sabemos que tendremos múltiples instancias que usan la base de datos, y hay que resolver el problema de qué hacer cuando un nodo de la base de datos falla. Y no debemos olvidar que una cosa son las instancias de la base de datos, y otra es el almacenamiento, por ejemplo hay sistemas de discos de red que facilitan agregar almacenamiento o reemplazarlo cuando uno falla, y todo con almacenamiento redundante y verificaciones de integridad.

Idealmente los recursos de computo de una instancia son limitados, facilitando su administración. Cualquier sistema de maquinas virtuales nos puede ayudar con esto (desde la maquina virtual de Java, hasta maquinas virtuales de sistema como VirtualBox, o contenedores como Docker).

Otra ventaja de los sistemas distribuidos es que si un nodo se cae, el sistema puede seguir funcionado.


Ahora, un componente de balance de carga es un cuello de botella. Si todo tiene que pasar por el balance de carga, el sistema solo es tan eficiente como el servidor de balance de carga...

Para diseñar un sistema de balance de carga que no tenga este problema, vamos a darle la vuelta. Hay dualidad entre recibir notificaciones (asíncrono) y leer datos (sincrónico). Con una solución clásica, el balance de carga llama a las instancias, y todos los clientes llaman el balance de carga. No podemos tener dos sistemas de balance de carga en paralelo porque el uno no sabría de la carga que está haciendo el otro... pero si las instancias leen las peticiones, solo tienen disponibilidad, eliminamos ese problema. Sin embargo hemos introducido otros dos: La interacción de las instancias ya no es asíncrona y depende del balance de carga.

En este caso, igual que antes, introducimos un nuevo componente, este recibe las peticiones, y las almacena, luego se inyecta como una dependencia en el Enrutador, el cual puede leerlas. Y, por supuesto, el Enrutador llamará a la instancia adecuada.


Esta dualidad entre notificaciones y almacenamiento nos permite pensar en el problema en términos de arroyos que viajan por canales de datos. Esto tiene otras dos ventajas:

  • Es fácil hacer composición y descomposición de arroyos. Por ejemplo para balance de carga como digo arriba, o para otras preocupaciones (por ejemplo escribir logs).
  • Es posible reconstruir el estado del almacenamiento a partir un registro de operaciones, y es posible crear un registro de operaciones que resulte en un estado de almacenamiento.

Si la entrada del usuario es uno de estos arroyos, y el acceso a datos es uno de estos arroyos, y tenemos logs de ellos, es posible reconstruir el estado en que ocurre un fallo reportado por el usuario, incluso simularlo.

Siguiendo esta lógica, vamos a terminar con un marco de trabajo de eventos distribuido (e.g. Apache Kafka), que maneja toda la comunicación entre instancias.

Nota: En la arquitectura que estoy proponiendo, este es un sistema externo, nos conectamos con el mediante servicios, y el trabajo del Lanzador crear los diferentes tipos de instancias con sus conexiones a este sistema externo.


Este articulo toma inspiración de la presentación "Four Distributed Systems Architectural Patterns" por "Tim Berglund"

Comentarios