Redis
 sql >> Base de Dados >  >> NoSQL >> Redis

Procurando uma solução entre definir muitos temporizadores ou usar uma fila de tarefas agendadas


Os temporizadores Node.js são implementados de forma muito eficiente. Sua implementação (descrita em um artigo detalhado sobre como eles funcionam) pode lidar facilmente com um grande número de temporizadores.

Eles são mantidos em uma lista duplamente vinculada que é classificada e apenas o próximo temporizador a ser acionado tem um temporizador real do sistema libuv associado a ele. Quando esse timer é acionado ou cancelado, o próximo na lista se torna aquele anexado a um timer real do sistema libuv. Quando um novo temporizador é definido, ele é apenas inserido na lista ordenada e, a menos que seja o próximo a ser disparado, ele fica na lista esperando sua vez de ser o próximo. Você pode ter milhares deles com muita eficiência.

Aqui estão alguns recursos sobre como esses temporizadores funcionam:

Quantos setTimeouts simultâneos antes de problemas de desempenho?

Como o nodejs gerencia os temporizadores internamente

A primeira referência contém vários comentários do código nodejs real que descreve como o sistema de lista vinculada do temporizador funciona e para que é otimizado.

O segundo artigo fornece uma descrição de nível um pouco mais alto de como está organizado.

Existem outras eficiências para que, quando um cronômetro chegar ao início da lista e disparar, depois de chamar esse retorno de chamada, o node.js verifique a frente da lista em busca de outros cronômetros que agora também estejam prontos para disparar. Isso varrerá quaisquer outros temporizadores com o mesmo "tempo de destino" que o primeiro e também quaisquer outros que tenham vencido enquanto esses vários outros retornos de chamada estavam em execução.

Quando você tem milhares, levará um pouco mais de tempo para inserir um novo cronômetro na lista vinculada ordenada se houver muitos cronômetros lá, mas uma vez inserido, pouco importa quantos existem porque ele está apenas olhando para o próximo a atirar. Portanto, o processo de ficar sentado com dezenas de milhares de cronômetros pendentes é apenas um cronômetro do sistema (representando o próximo evento do cronômetro a ser acionado) e um monte de dados. Todos esses dados para os outros cronômetros futuros não estão custando nada a você apenas sentado lá.

Para Javascript, semelhante à primeira solução do python, eu poderia gerar quantos setTimeouts forem necessários, mas o problema é que todos os tempos limite funcionam no thread principal, mas como eu disse, as tarefas não são intensivas em recursos e eu só preciso de precisão para o segundo.

Parece-me que o nodejs poderia lidar com sua quantidade de setTimeout() chama muito bem. Se você tivesse um problema no node.js, não seria por causa do número de temporizadores, mas você teria que ter certeza de aplicar CPU suficiente ao problema se tiver mais trabalho para processar do que um núcleo pode suportar. Você pode expandir o uso principal com clustering nodejs ou com uma fila de trabalho que usa Worker Threads ou outros processos nodejs para ajudar no processamento. node.js é, por si só, muito eficiente com qualquer coisa relacionada a E/S, desde que você não esteja fazendo grande computação intensiva da CPU, um único thread node.js pode lidar com muito processamento de eventos.

Tenha em mente que os temporizadores Javascript não oferecem garantias de precisão. Se você atolar a CPU, alguns temporizadores serão acionados mais tarde do que o programado porque não são preventivos. Mas, se suas tarefas não exigem muita CPU, você pode ficar bem.