sql >> Database >  >> NoSQL >> Redis

Op zoek naar een oplossing tussen het instellen van veel timers of het gebruik van een geplande taakwachtrij

Node.js-timers zijn zeer efficiënt geïmplementeerd. Hun implementatie (beschreven in een gedetailleerd artikel over hoe ze werken) kan gemakkelijk zeer grote aantallen timers aan.

Ze worden bewaard in een dubbel gelinkte lijst die is gesorteerd en alleen de volgende timer die wordt geactiveerd, heeft een echte libuv-systeemtimer. Wanneer die timer afgaat of wordt geannuleerd, wordt de volgende in de lijst degene die is gekoppeld aan een echte libuv-systeemtimer. Wanneer een nieuwe timer is ingesteld, wordt deze gewoon in de gesorteerde lijst ingevoegd en, tenzij het de volgende wordt die wordt geactiveerd, blijft hij in de lijst wachten op zijn beurt om de volgende te zijn. Je kunt er heel efficiënt duizenden van hebben.

Hier zijn een paar bronnen over hoe deze timers werken:

Hoeveel gelijktijdige setTimeouts vóór prestatieproblemen?

Hoe beheert nodejs timers intern

De eerste referentie bevat een heleboel opmerkingen van de eigenlijke nodejs-code die beschrijft hoe het timer-gekoppelde lijstsysteem werkt en waarvoor het is geoptimaliseerd.

Het tweede artikel geeft je een beschrijving op een hoger niveau van hoe het is georganiseerd.

Er zijn andere efficiëntieverbeteringen, zodat wanneer een timer aan het begin van de lijst komt en deze wordt geactiveerd, node.js na het aanroepen van die callback de voorkant van de lijst controleert op andere timers die nu ook klaar zijn om te vuren. Dit zal alle andere timers met dezelfde "doeltijd" als de eerste wissen en ook andere timers die zijn vervallen terwijl deze verschillende andere callbacks liepen.

Als je er duizenden hebt, duurt het iets langer om een ​​nieuwe timer in de gesorteerde gekoppelde lijst in te voegen als er veel timers zijn, maar als deze eenmaal is ingevoegd, maakt het nauwelijks uit hoeveel er zijn, omdat het alleen maar kijkt naar de volgende om te vuren. Dus het proces om daar te zitten met zelfs tienduizenden timers in behandeling, is slechts één systeemtimer (die de volgende timergebeurtenis vertegenwoordigt die moet worden geactiveerd) en een heleboel gegevens. Al die gegevens voor de andere toekomstige timers kost je niets als je daar blijft zitten.

Voor Javascript, vergelijkbaar met de eerste oplossing van de python, zou ik zoveel setTimeouts kunnen spawnen als nodig is, maar het probleem is dat alle time-outs op de hoofdthread werken, maar zoals ik al zei, de taken zijn niet arbeidsintensief en ik heb alleen nauwkeurigheid nodig voor de tweede.

Het lijkt mij dat nodejs uw hoeveelheid setTimeout() aankan belt gewoon goed. Als je een probleem had in node.js, zou dat niet komen door het aantal timers, maar je zou er zeker van moeten zijn dat je voldoende CPU op het probleem toepast als je meer werk te verwerken hebt dan één kern aankan. U kunt het kerngebruik uitbreiden met nodejs-clustering of met een werkwachtrij die Worker Threads of andere nodejs-processen gebruikt om te helpen bij de verwerking. node.js is op zichzelf zeer efficiënt met alles wat met I/O te maken heeft, dus zolang u geen grote CPU-intensieve berekeningen uitvoert, kan een enkele node.js-thread veel gebeurtenisverwerking aan.

Houd er rekening mee dat Javascript-timers geen nauwkeurigheidsgaranties bieden. Als je de CPU vastloopt, worden sommige timers later geactiveerd dan gepland omdat ze niet preventief zijn. Maar als je taken niet CPU-intensief zijn, zit je misschien wel goed.




  1. Bereikquery voor MongoDB-paginering

  2. mongodb controleer of punt in polygoon is

  3. Bulk mongodb invoegen in Meteor of Node

  4. Spring Data RedisTemplate:serialisatie van de waarde en hashwaarde