Redis
 sql >> Database >  >> NoSQL >> Redis

Alla ricerca di una soluzione tra l'impostazione di molti timer o l'utilizzo di una coda di attività pianificata

I timer Node.js sono implementati in modo molto efficiente. La loro implementazione (descritta in un articolo dettagliato su come funzionano) può facilmente gestire un numero molto elevato di timer.

Sono mantenuti in un elenco doppiamente collegato che viene ordinato e solo il prossimo timer che si attiva ha un timer di sistema libuv effettivo associato ad esso. Quando quel timer si attiva o viene annullato, quello successivo nell'elenco diventa quello collegato a un timer di sistema libuv effettivo. Quando viene impostato un nuovo timer, viene semplicemente inserito nell'elenco ordinato e, a meno che non diventi il ​​prossimo a sparare, si trova semplicemente nell'elenco in attesa del suo turno per essere il prossimo. Puoi averne migliaia in modo molto efficiente.

Ecco un paio di risorse su come funzionano questi timer:

Quanti setTimeout simultanei prima dei problemi di prestazioni?

In che modo nodejs gestisce i timer internamente

Il primo riferimento contiene una serie di commenti dal codice nodejs effettivo che descrive come funziona il sistema di elenchi collegati del timer e per cosa è ottimizzato.

Il secondo articolo fornisce una descrizione di livello leggermente superiore di come è organizzato.

Ci sono altre efficienze in modo che quando un timer arriva all'inizio dell'elenco e si attiva, dopo aver chiamato quella richiamata, node.js controlla la parte anteriore dell'elenco per eventuali altri timer che ora sono pronti per essere attivati. Questo eliminerà tutti gli altri timer con lo stesso "tempo target" del primo e anche tutti gli altri che sono scaduti mentre erano in esecuzione questi vari altri callback.

Quando ne hai migliaia, ci vorrà un po' più di tempo per inserire un nuovo timer nell'elenco collegato ordinato se ci sono molti timer, ma una volta inserito, non importa affatto quanti ce ne siano perché sta solo guardando il prossimo a sparare. Quindi, il processo per rimanere lì con anche decine di migliaia di timer in sospeso è solo un timer di sistema (che rappresenta il prossimo evento timer da attivare) e una serie di dati. Tutti quei dati per gli altri futuri timer non ti costano nulla, semplicemente stando lì seduti.

Per Javascript, simile alla prima soluzione di Python, potrei generare tutti i setTimeout necessari, ma il problema è che tutti i timeout funzionano sul thread principale, ma come ho detto, le attività non richiedono molte risorse e ho solo bisogno di precisione per il secondo.

Mi sembra che nodejs possa gestire la tua quantità di setTimeout() chiama bene. Se avessi un problema in node.js, non sarebbe a causa del numero di timer, ma dovresti essere certo di applicare abbastanza CPU al problema se hai più lavoro da elaborare di quanto un core possa gestire. È possibile espandere l'utilizzo del core con il clustering nodejs o con una coda di lavoro che utilizza i thread di lavoro o altri processi nodejs per facilitare l'elaborazione. node.js è, di per sé, molto efficiente con qualsiasi cosa relativa all'I/O, quindi fintanto che non stai eseguendo calcoli ad alta intensità di CPU, un singolo thread node.js può gestire molte elaborazioni di eventi.

Tieni presente che i timer Javascript non offrono garanzie di accuratezza. Se si impantana la CPU, alcuni timer si attiveranno più tardi del previsto perché non sono preventivi. Ma se le tue attività non richiedono molta CPU, allora potresti andare bene.