braziljs / forum

Fórum da BrazilJS
MIT License
126 stars 6 forks source link

NodeJS Performance #14

Closed renanbastos93 closed 6 years ago

renanbastos93 commented 6 years ago

Olá,

Gostaria de entender se tem alguma forma de reduzir o consumo de CPU de uma aplicação NodeJS. Bom vou explicar pouco do cenário para ficar mais claro.

Tenho um request numa API que trás mais de 3000 items, com N campos, e faço diversos tratamento nesses campos e depois salvo no MongoDB. E nesse request ele sempre passa dos 90% de consumo da CPU. A máquina da AWS é uma máquina com 2GB de memoria e 1 core.

Então fica a dúvida, qual máquina ideal para uma aplicação em NodeJS e quais formas ou soluções já existentes, se existem.

Agradeço desde já.

Att, @renanbastos93

geovanisouza92 commented 6 years ago

@renanbastos93

No caso, essa request precisa trazer todos os 3000 itens ou é tipo um processo em Batch?

Se for algo que pode ser processado e armazenado (como estou assumindo já que vc comenta que salva no MongoDB), você já considerou separar esse processo em workers? Nada muito rebuscado, apenas aproveitar o módulo cluster do próprio Node, que vai lançar mais processos e, considerando que cada processo Node é "single-thread" (pelo menos na execução do JS), ter mais processos pode acelerar o processamento e melhorar o aproveitamento da máquina.

Outra coisa que vc precisa considerar é que, se essa requisição não for solicitada com tanta frequência, talvez você não precise se preocupar em melhorar a performance dela. Não é nenhum crime deixar um "elefante na sala" se tirá-lo não vai trazer resultado prático (só uma opinião, claro).

renanbastos93 commented 6 years ago

@geovanisouza92

Opa, entendi. E que depende a quantidade de usuários que pedirem dados do cache, ele poderá ter mais ou menos.

Mas aí pensei se fizer por worker imagina se for 1000 clientes, vai dar no mesmo não?

geovanisouza92 commented 6 years ago

@renanbastos93

Se for 1000 clientes você vai ter que aumentar a infraestrutura eventualmente de qualquer forma.


Se os dados forem comuns entre os usuários (pouco ou nada parametrizado) o cache (mesmo no MongoDB) amortiza bastante isso.


Voltando à sua questão inicial - sobre o dimensionamento das máquinas -, se usando esse perfil de máquina (1 CPU e 2 Gb RAM, imagino que seja t2.small, certo?) ele chega com frequência à 90% de uso, vc deveria considerar escalar vertical ou horizontalmente.

Vertical = aumentar a máquina (recomendaria uma c5.large, já que há um processamento desses itens); Horizontal = aumentar a quantidade de máquinas para evitar que outros usuários sofram lentidão.


"Dividir e conquistar" costuma ser uma opção interessante. No caso de usar uma t2.small você têm apenas uma CPU disponível, então subir subprocessos talvez só segmente o problema, mas não dê um ganho enorme em performance. No caso de ter mais CPU, os processos se tornam concorrentes, e usar subprocessos dá um resultado perceptível. Então você poderia pegar esses 3000+ registros e dividir em lotes menores e repassar esses lotes para os subprocessos realizarem as manipulações (e talvez já salvar no MongoDB). Você precisa testar pra descobrir qual o tamanho ideal, já que, se o lote for muito pequeno, o tempo de comunicação entre os processos pode custar muito; se ele for muito grande, o resultado percebido vai ser menor.

renanbastos93 commented 6 years ago

@geovanisouza92,

Sim, tava usando o --inspec e identifiquei que o problema é nos forEach pra inserir no mongo, pois são 3 mil items e mais outras dependências dele assim gera bem mais de 3 mil insert ou update, então to começando a trabalhar em cima, bom é se tivesse um esquema de inseri um array inteiro pelo mongoose.

geovanisouza92 commented 6 years ago

Você já experimentou isso?

renanbastos93 commented 6 years ago

@geovanisouza92,

você questiona se já experimentei o --inspec ?

geovanisouza92 commented 6 years ago

Se você já tentou a API de insert do mongoose, que suporta bulk insert.

renanbastos93 commented 6 years ago

Não, tentei ainda. e tem também o bulk update?

geovanisouza92 commented 6 years ago

Sim, insert e update

renanbastos93 commented 6 years ago

@geovanisouza92,

Valeu, vou dar uma olhada!

agostinhovitorio commented 4 years ago

Olá, carxs, bom dia! Estou com o mesmo problema. Minha api está levando quase um giga em pouco tempo para trazer as requisições de nosso Call center. O código fora passado pra mim e tenho de mudar algumas configurações. Como utilizar um código que reduza o consumo de memória. Se alguém puder me ajudar, ser-lhe-ei muito grato!