Colas Redis & Redis Queue Dashboards para el desarrollo de API de Python

En este artículo, explorará el módulo RQ para configurar colas de trabajo y trabajadores, así como el módulo RQ-Dashboard para visualizarlos.

Introducción

El almacén de datos en memoria: Redis es ampliamente utilizado por los desarrolladores como base de datos, capa de caché, para administrar colas de trabajo y más.

Resulta útil cuando crea API con un mecanismo de cola de trabajos para manejar tareas como ejecutar trabajos que requieren mucha memoria en segundo plano, contar las visitas a la página o enviar campañas masivas de correo electrónico.

Si está creando una API en Python, el módulo Redis Queue (RQ) le brinda funciones para poner en cola, programar y procesar estos trabajos mediante la implementación de trabajadores.

En este artículo, explorará el módulo RQ para configurar colas de trabajos y trabajadores, así como el módulo RQ-Dashboard para visualizarlos.

Configuración de Redis

Si aún no tiene una API o ningún código al que pueda aplicar Redis RQ, puede clonar nuestro [repositorio GitHub] (https://github.com/wikihtp/redis-queues-redis-queue-dashboards) con código de ejemplo.

Clonemos nuestro repositorio e instalemos sus dependencias:

1
2
3
4
5
$ git clone [correo electrónico protegido]:wikihtp/redis-queues-redis-queue-dashboards.git
$ cd redis-queues-redis-queue-dashboards
$ python -m venv env
$ . env/bin/activate
$ pip install -r requirements.txt

También tenemos que instalar Redis, que en realidad puede ser un poco complicado si no está utilizando un sistema operativo basado en Linux. La forma más sencilla de instalarlo en sistemas operativos que no sean Linux es a través de Componer ventana acoplable:

1
$ docker-compose up -d

Nuestro archivo docker-compose está configurado para descargar una imagen de Redis, y ese comando lo ejecutará en segundo plano. Alternativamente, puede instalar Redis localmente.

Para Ubuntu, esa instalación se ve así:

1
2
3
4
5
$ sudo apt-get install redis
$ sudo service redis-server start
Starting redis-server: redis-server.
$ redis-cli -v       
redis-cli 4.0.9

Ahora que nuestro entorno está creado, echemos un vistazo a Redis Queues.

Cola de retorno (RQ)

Redis Queue (RQ) es un módulo de cola que se ejecuta sobre Redis. Actúa como productor para enviar los trabajos a la cola. El módulo también viene con trabajadores que actúan como consumidores para procesar los trabajos enviados desde la cola de forma asíncrona. Pero, ¿qué es un trabajo de todos modos?

Los trabajos son referencias a las funciones de Python que se envían a la cola.

Pueden existir múltiples colas para procesar trabajos, y estas colas pueden tener el nombre que desee. Los trabajos enviados a las colas se pueden monitorear utilizando sus ID de trabajo.

Escribamos un script simple para poner en cola un trabajo en Redis Queue, por ejemplo, test.py:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# Imported to assign redis as the backend to rq
from redis import Redis
# Imported to initialize the queue object
from rq import Queue
# Functions from the __main__ module can't be processed by workers
# Hence, we have a separate Python file containing the function
from test_job import i_am_a_job

# Create the queue object by passing in the redis object
q = Queue(connection=Redis())
 
# Run the job asynchronously
job = q.enqueue(i_am_a_job, 1)
# Return the function output

La función que desea poner en cola debe importarse desde un archivo Python separado. Lo hemos importado desde test_job.py:

1
2
3
4
# A Function (or) a job
def i_am_a_job(arg1):
    # Perform some function
    return arg1

Ahora que Redis Queue y la función están configuradas, ejecutemos el script de Python:

1
$ python test.py

Ejecutar este comando debería crear un trabajo pero no devolver ningún resultado. Si obtiene un error, revise los pasos de configuración nuevamente antes de continuar.

Si todo funcionó, usemos RQ-Dashboard para administrar nuestro trabajo.

Administración de trabajos en cola de Redis con RQ-Dashboard

Puede inspeccionar el estado de sus trabajos en Redis Queue usando RQ-Dashboard, una aplicación Flask liviana que se usa para monitorear Redis Queues. Ejecutemos RQ-Dashboard para monitorear el trabajo que acabamos de crear.

En una Terminal separada, navegue a la carpeta donde clonó el repositorio. Allí, activaremos RQ-Dashboard:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
$ . env/bin/activate
$ rq-dashboard
RQ Dashboard version 0.5.2
 * Serving Flask app 'rq_dashboard.cli' (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on all addresses.
   WARNING: This is a development server. Do not use it in a production deployment.
 * Running on http://192.168.1.10:9181/ (Press CTRL+C to quit)
192.168.1.10 - - [11/Jun/2021 15:30:12] "GET / HTTP/1.1" 200 -

Puede acceder a RQ-Dashboard en http://localhost:9181. Cuando abra el enlace, notará que su trabajo todavía está en la cola y que aún no hay trabajadores asignados:

Captura de pantalla de RQ-Dashboard ejecutándose por primera vez, no tiene trabajadores y un trabajo

Redis Queue Workers

Los trabajadores eligen un trabajo de la cola para ejecutarlo. En otra Terminal (también puedes usar la primera), creemos un trabajador:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
$ . env/bin/activate # For new Terminals when you don't install the dependencies locally
$ rq worker --with-scheduler
15:42:38 Worker rq:worker:a33eb6277eda4969921cc8e3f1e857c0: started, version 1.8.1
15:42:38 Subscribing to channel rq:pubsub:a33eb6277eda4969921cc8e3f1e857c0
15:42:38 *** Listening on default...
15:42:38 Trying to acquire locks for default
15:42:38 Cleaning registries for queue: default
15:42:38 Scheduler for default started with PID 1093
15:42:38 default: test_job.i_am_a_job(1) (b92bf928-48dd-4fb9-a551-427866c46a38)
15:42:38 default: Job OK (b92bf928-48dd-4fb9-a551-427866c46a38)
15:42:38 Result is kept for 500 seconds

El trabajo que envió se ejecutó y el resultado se mantiene en Redis durante 500 segundos. Además de las ejecuciones inmediatas de trabajos, también se pueden programar trabajos para que se ejecuten en un momento futuro, similar a un trabajo CRON. La instrucción en cola se puede escribir como programada mediante:

1
job = queue.enqueue_at(datetime(2021, 7, 7, 13, 15), i_am_a_job, 1)

Estas operaciones son la base para usar Redis Queues, monitorearlas y asignar trabajadores. Ahora, escribamos una pequeña aplicación práctica, que cuenta el número de visitas a la página.

Aplicación de demostración Redis Queue: recuento de visitas al sitio

El código del repositorio que descargó anteriormente incluye una aplicación Flask:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
from flask import Flask
from redis import Redis
from rq import Queue
from counter import visit

app = Flask(__name__)
q = Queue(connection=Redis())


@app.route('/visit')
def count_visit():
    count = q.enqueue(visit)
    return "Visit has been registered"


@app.route('/')
def return_visit_count():
    count = Redis().get('count').decode('utf-8') if Redis().get('count') else '0'
    return (f'<h1> Congrats! Your are the visitor no.: {count} </h1>')

En tu Terminal, ejecutemos esta aplicación Flask:

1
2
$ . env/bin/activate # Unless it's already running
$ flask run

Esto inicia la aplicación Flask en app.py. Esta aplicación contiene dos rutas: / y /visit.

Cada vez que se alcanza el punto final http://localhost:5000/visita, la clave count en Redis se incrementa en 1 y se devuelve la siguiente página web.

Captura de pantalla de la página inicial de reconocimiento del visitante del sitio web

La función de incremento se pone en cola como un trabajo. El número de visitas es visible en el punto final: http://localhost:5000 como:

Captura de pantalla del sitio web que muestra el conteo de visitantes

Intentemos visitar el punto final http://localhost:5000/visita tres veces. Esto enviará nuestro trabajo tres veces. Entonces, verifiquemos el estado de nuestros trabajos en RQ-Dashboard. Visite http://localhost:9181 y podrá observar la siguiente página web donde nuestros trabajos se envían con éxito pero ningún trabajador los está procesando:

Captura de pantalla de RQ-Dashboard mostrando nuevos trabajos en ejecución

Para iniciar el trabajador y el programador de Redis Queue, abra otra Terminal e ingrese el comando para iniciar un trabajador. Observe que los trabajos enviados se ejecutan uno tras otro:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
$ . env/bin/activate # For new Terminals when you don't install the dependencies locally
$ rq worker --with-scheduler
23:40:06 Worker rq:worker:f5a178b0931b42859699ce57696ed402: started, version 1.8.1
23:40:06 Subscribing to channel rq:pubsub:f5a178b0931b42859699ce57696ed402
23:40:06 *** Listening on default...
23:40:06 Trying to acquire locks for default
23:40:06 Cleaning registries for queue: default
23:40:06 Scheduler for default started with PID 2889
23:40:06 default: counter.visit() (d23c4df8-d638-476b-b70a-dbb4b6f091f2)
23:40:06 default: Job OK (d23c4df8-d638-476b-b70a-dbb4b6f091f2)
23:40:06 Result is kept for 500 seconds
23:40:06 default: counter.visit() (f4ca10c4-16f2-4578-b1b7-67dfce3cee5a)
23:40:06 default: Job OK (f4ca10c4-16f2-4578-b1b7-67dfce3cee5a)
23:40:06 Result is kept for 500 seconds
23:40:06 default: counter.visit() (956b7b39-0b82-4ac6-b29e-fe3f0706431e)
23:40:06 default: Job OK (956b7b39-0b82-4ac6-b29e-fe3f0706431e)
23:40:06 Result is kept for 500 seconds

Puede volver a consultar el panel de control y es posible que descubra que los trabajos se han ejecutado. Esto se puede verificar apuntando a la URL en su navegador a http://localhost:9181. Observe que el trabajador ahora está en funcionamiento y que los trabajos se han procesado correctamente.

Captura de pantalla de RQ-Dashboard que muestra el nuevo trabajo registrado

Verifiquemos el número de visitas abriendo o actualizando la aplicación en http://localhost:5000. ¡Voila! El contador de visitas a la página se ha incrementado en 3.

Captura de pantalla del sitio web de conteo de visitantes, el conteo se incrementó en 3 desde la última captura de pantalla

Piense en un sitio web con mucho tráfico y uno desea monitorear las visitas al sitio y las visitas a la página. En este caso, varias instancias de esta API se sirven bajo un balanceador de carga y el recuento se realiza en función de los trabajos enviados en la cola de forma asíncrona.

Conclusión

En este artículo, hemos explorado la importancia de las colas de trabajos y cómo RQ y RQ-Dashboards pueden servir como una pila de colas de trabajos minimalista para sus aplicaciones web. El ejemplo práctico se puede expandir a otras aplicaciones del mundo real donde las posibilidades son infinitas.