admin管理员组文章数量:1332403
I have an app running on Nest.Js / Node.Js which does text processing and because of that it has an .map
(or .forEach
) iteration that takes a lot of resources (tokenizing a sentence, then removing the stopwords, etc — for each sentence of which there may be tens of thousands).
For reproducibility, I provide the code I use below, without the text processing details — just a long heavy loop to emulate my problem:
const before = Date.now()
const statements = [...Array(100)]
let l = 0
let p = 0
const processed =
statements.map((value, index) => {
// a set of consecutive functions that take a long time to execute
for (let i = 0; i < 100000; i++) {
l = l + i * Math.random()
}
// console.log(index + ' ' + l + ' ' + (Date.now() - before))
p = index
return l
})
console.log(processed)
const after = Date.now()
console.log(p + ' results in ' + (after - before) + ' ms')
For very big files the process takes up to 100% of the CPU, so the app bees unresponsive.
I was wondering if you know of any solution to prevent the app from taking all the CPU made available to it. Like is there a way to set any single process to take 80% and always leave 20% for the other users?
PS I run it from Amazon's ECS so of course I can create clusters and also use PM2 for clusterization, but I wonder how I can avoid the 100% load from a single process within a Javascript / Node.Js app itself. I mention the Nest.Js framework because maybe there's a solution there as well.
I have an app running on Nest.Js / Node.Js which does text processing and because of that it has an .map
(or .forEach
) iteration that takes a lot of resources (tokenizing a sentence, then removing the stopwords, etc — for each sentence of which there may be tens of thousands).
For reproducibility, I provide the code I use below, without the text processing details — just a long heavy loop to emulate my problem:
const before = Date.now()
const statements = [...Array(100)]
let l = 0
let p = 0
const processed =
statements.map((value, index) => {
// a set of consecutive functions that take a long time to execute
for (let i = 0; i < 100000; i++) {
l = l + i * Math.random()
}
// console.log(index + ' ' + l + ' ' + (Date.now() - before))
p = index
return l
})
console.log(processed)
const after = Date.now()
console.log(p + ' results in ' + (after - before) + ' ms')
For very big files the process takes up to 100% of the CPU, so the app bees unresponsive.
I was wondering if you know of any solution to prevent the app from taking all the CPU made available to it. Like is there a way to set any single process to take 80% and always leave 20% for the other users?
PS I run it from Amazon's ECS so of course I can create clusters and also use PM2 for clusterization, but I wonder how I can avoid the 100% load from a single process within a Javascript / Node.Js app itself. I mention the Nest.Js framework because maybe there's a solution there as well.
Share Improve this question asked Mar 15, 2022 at 12:18 AerodynamikaAerodynamika 8,45318 gold badges91 silver badges150 bronze badges 5- Do you want your text processing to take 80% of CPU so the rest 20% is free for other tasks in your nodejs application? If yes, that is impossible because what you are doing is synchronous, basically javascript is not going to do anything until the current synchronous task is done. – typicallearner Commented Mar 15, 2022 at 15:00
- @typicallearner yes, this is exactly what i was thinking... and no, that would work, because if it's a server app, the person who's doing a request might have 80% taken, but some other person accessing the service, would still be able to use it. that's the idea. – Aerodynamika Commented Mar 17, 2022 at 15:21
- Does not matter whether it's a server or not, Javascript is single-threaded, what you are asking is blocking, if your text processing is running, that single nodejs instance won't respond to anything else, what I would do is split it into two instances, one worker (which processed text), one web server, this way you can split the CPU usage and you won't block your webserver. – typicallearner Commented Mar 17, 2022 at 18:30
-
If a portion of work is done in your putation, continue the rest in setImmediate callback. If you are inside an async callback, you can try
await new Promise((resolve) => setImmediate(resolve));
– Mihályi Zoltán Commented Mar 24, 2022 at 11:41 - Did you try parallel processing with nodejs? It will reduce the putational time, so the cpu usage in a period of time. – Francesco Clementi Commented Mar 24, 2022 at 13:49
2 Answers
Reset to default 7 +25In terms of limiting a single thread from using 100% CPU, there are architectural ways of doing so at a server level, however I don't think that's really the oute you would want. A CPU using 100% isn't an issue (CPUs will often spike to 100% CPU for very short periods of time to process things as quickly as possible), it's more of it using 100% CPU for an extended period of time and preventing other applications from getting CPU cycles.
From what I am seeing in the example code, it might be a better solution to use Queues within NestJS. Documentation can be seen here using Bull. This way you can utilize the rate limits of jobs being processed and tweak it there, and other applications will not be waiting for the pletion of the entire process.
For instance if you have 100,000 files to process, you may want to create a job that will process 1,000 of them at a time and create 100 jobs to be thrown into the queue. This is a fairly typical process for processes that require a large amount of pute time.
I know this isn't the exactly the answer I am sure you were looking for, but hopefully it will help and provide a solution that is not specific to your architecture.
JS is a syncronous language. Now when using this on your node application, you can end up blocking your main thread if not done correctly.
https://nodejs/en/docs/guides/dont-block-the-event-loop/
Node.js has two types of threads: one Event Loop and k Workers. The Event Loop is responsible for JavaScript callbacks and non-blocking I/O, and a Worker executes tasks corresponding to C++ code that pletes an asynchronous request, including blocking I/O and CPU-intensive work. Both types of threads work on no more than one activity at a time. If any callback or task takes a long time, the thread running it bees blocked. If your application makes blocking callbacks or tasks, this can lead to degraded throughput (clients/second) at best, and plete denial of service at worst.
To write a high-throughput, more DoS-proof web server, you must ensure that on benign and on malicious input, neither your Event Loop nor your Workers will block.
One request is to offload the operation to another area.
- for example can you do part of the operation on Database
- like if you are working on mongodb, can mongodb manage the replaceAll in aggregation, or do some other manipulation
- this way you dont have to do this at your node application level
本文标签: javascriptHow to avoid a NestJsNodeJs process taking up 100 of the CPUStack Overflow
版权声明:本文标题:javascript - How to avoid a Nest.JsNode.Js process taking up 100% of the CPU? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742278920a2445728.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论