sql >> Base de Datos >  >> NoSQL >> Redis

Buscando una solución entre configurar muchos temporizadores o usar una cola de tareas programada

Los temporizadores de Node.js se implementan de manera muy eficiente. Su implementación (descrita en un artículo detallado sobre cómo funcionan) puede manejar fácilmente una gran cantidad de temporizadores.

Se mantienen en una lista doblemente enlazada que está ordenada y solo el próximo temporizador para disparar tiene un temporizador de sistema libuv real asociado. Cuando ese temporizador se dispara o se cancela, el siguiente en la lista se convierte en el que se adjunta a un temporizador del sistema libuv real. Cuando se establece un nuevo temporizador, simplemente se inserta en la lista ordenada y, a menos que se convierta en el próximo en disparar, simplemente se sienta en la lista esperando su turno para ser el siguiente. Puede tener miles de estos de manera muy eficiente.

Aquí hay un par de recursos sobre cómo funcionan estos temporizadores:

¿Cuántos setTimeouts simultáneos antes de problemas de rendimiento?

¿Cómo gestiona nodejs los temporizadores internamente?

La primera referencia contiene un montón de comentarios del código real de nodejs que describe cómo funciona el sistema de lista enlazada del temporizador y para qué está optimizado.

El segundo artículo le brinda una descripción de nivel un poco más alto de cómo está organizado.

Hay otras eficiencias para que cuando un temporizador llegue al comienzo de la lista y se active, luego de llamar a esa devolución de llamada, node.js verifica el frente de la lista en busca de otros temporizadores que ahora también estén listos para activarse. Esto barrerá cualquier otro temporizador con el mismo "tiempo objetivo" que el primero y también cualquier otro que haya vencido mientras se ejecutaban estas otras devoluciones de llamada.

Cuando tenga miles, tomará un poco más de tiempo insertar un nuevo temporizador en la lista enlazada ordenada si hay muchos temporizadores allí, pero una vez que se inserta, apenas importa cuántos hay porque solo está mirando el siguiente en disparar. Por lo tanto, el proceso de sentarse allí incluso con decenas de miles de temporizadores pendientes es solo un temporizador del sistema (que representa el próximo evento del temporizador que se activará) y un montón de datos. Todos esos datos para los otros cronómetros futuros no le cuestan nada, solo está sentado allí.

Para Javascript, similar a la primera solución de python, podría generar tantos setTimeouts como sea necesario, pero el problema es que todos los tiempos de espera funcionan en el hilo principal, pero como dije, las tareas no consumen muchos recursos y solo necesito precisión para el segundo.

Me parece que nodejs podría manejar su cantidad de setTimeout() llama muy bien. Si tuviera un problema en node.js, no sería por la cantidad de temporizadores, pero tendría que asegurarse de aplicar suficiente CPU al problema si tiene más trabajo para procesar del que puede manejar un núcleo. Puede expandir el uso principal con la agrupación en clústeres de nodejs o con una cola de trabajo que use subprocesos de trabajo u otros procesos de nodejs para ayudar con el procesamiento. node.js es, por sí mismo, muy eficiente con todo lo relacionado con E/S, por lo que siempre que no esté realizando un cálculo intensivo de la CPU, un solo subproceso de node.js puede manejar una gran cantidad de procesamiento de eventos.

Tenga en cuenta que los temporizadores de Javascript no ofrecen garantías de precisión. Si atasca la CPU, algunos temporizadores se activarán más tarde de lo programado porque no son preventivos. Pero, si sus tareas no requieren un uso intensivo de la CPU, entonces puede estar bien.