Saltar al contenido

Deshazte de ese cuello de botella usando las técnicas modernas de colas

El último caso de uso que discutiré en este artículo es el caso de los cuellos de botella causados por los «grandes» cálculos.

En el caso de un cómputo «grande» que no puede ser dividido en partes más pequeñas y separadas, probablemente tendremos que escalar nuestro sistema trayendo servicios en línea adicionales que puedan computar a una escala «grande».

Deshazte de ese cuello de botella usando las técnicas modernas de colas
Deshazte de ese cuello de botella usando las técnicas modernas de colas

Sin embargo, a menudo también puede haber cálculos que pueden desglosarse en cálculos separados, «más pequeños», que pueden realizarse por separado.

Con tales cálculos, como acabo de mencionar, nuestro sistema podría ser optimizado procesando varios cálculos «más pequeños» por separado, en paralelo, y luego combinando los resultados de estos cálculos en un resultado final para todo el cálculo «grande».

Por favor, tenga en cuenta que el paralelismo suele ser limitado. No puedes «romper» un problema en tantos problemas «más pequeños» como desees y simplemente lanzarlos a tu CPU.

Cada CPU tiene un recuento de hilos físicos que debe tenerse en cuenta al realizar un cálculo en paralelo. En caso de no utilizar todos los hilos físicos disponibles en la CPU, es probable que esté infrautilizando sus recursos.

Pero ten cuidado. En caso de que el software que maneja la computación a gran escala requiera más hilos de los que físicamente están disponibles en su máquina, pagará los gastos generales creados por el cambio de contexto.

¿Pero cómo nos ayudará una cola aquí?

De nuevo, como se mencionó antes, al discutir la separación de preocupaciones entre el software y los equipos de DevOps, las colas pueden ayudarnos a escribir código que sea agnóstico del entorno en el que está alojado.

Considere el siguiente ejemplo:

Nuestro sistema está manejando cálculos «grandes». El Servicio A recibe mensajes de entrada que sabe «descomponer» en tres cómputos discretos «más pequeños», que son realizados por el Servicio B, el Servicio C y el Servicio D.

Nuestro sistema funciona en una máquina con ocho hilos físicos disponibles. Eso significa que óptimamente nos gustaría tener ocho cálculos hechos en paralelo.

Nuestros desarrolladores de software sólo tienen que preocuparse de escribir la aplicación de manera que permita realizar los tres cálculos discretos en paralelo. Eso significa que cada cálculo diferente debe tener una cola de mensajes dedicada y un servicio que lea los mensajes de esta cola y los procese.

Eso es todo desde el punto de vista del desarrollador.

Ahora, en el lado de DevOps, nos gustaría asegurarnos de que dos cosas sucedan:

  1. Se crean todas las colas de mensajes.
  2. El sistema se despliega con el grado correcto de paralelismo.

En el ejemplo anterior, como cada mensaje puede desglosarse en tres mensajes «más pequeños», nos gustaría que se plantearan tres instancias de servicio (una para el Servicio A, una para el Servicio B y una para el Servicio C) y que estuvieran listas para recibir mensajes por cada mensaje «grande». Así que tenemos tres hilos físicos más un hilo físico = cuatro hilos físicos por cada mensaje «grande».

Teniendo ocho hilos físicos a nuestra disposición, podemos sacar con seguridad una instancia adicional del servicio A, una instancia adicional para el servicio B, una más para el servicio C y finalmente una instancia del servicio D.

Nuestro sistema se verá entonces así:

Ahora bien, ¿qué pasa si es necesario reducir la escala y ser alojado en una máquina con menos recursos? Esto no es un problema de software; no se modificará ni una sola línea de código. Las instancias pueden ser bajadas (en el diagrama de abajo estamos bajando cuatro instancias – volviendo al despliegue anterior).

¿Y qué hay de la ampliación en máquinas adicionales? No es un problema de software de nuevo, ya que no se escribirá ningún código. Traiga servicios adicionales y apúntelos a su cola de mensajes. Eso es todo lo que hay que hacer, en realidad.

Eso significa que nuestros desarrolladores deben preocuparse por «descomponer» los problemas en unidades de cálculo discretas y asegurarse de que cada tipo de cálculo tenga una cola de mensajes única.

Si sigue estas directrices, su aplicación podrá realizar cálculos en paralelo, dentro de los límites de los recursos de hardware (es decir, los hilos físicos).