Is NodeJS really as fast as you think?

Tram Ho

NodeJS under the eyes of the world

There are many of you questioning me around NodeJS Performance issues, such as:

  • How can you avoid the situation where a heavy request affects all other requests on a Web application using NodeJS? (#first)
  • Why is NodeJS fast, but sometimes slow at different APIs? (#2)
  • Are there APIs, NodeJS needs tens of seconds in order to respond? (# 3)

So how a beautiful flower like NodeJS here, not placed in the right place becomes so dry, let’s clarify each issue together!

Hello, I’m Khanh Ney , born a speed enthusiast, but Mom and Dad started to work as a Developer, that’s why when I was a child I really liked Speed ​​and even in the football field, I loved the moves. long ball and past the defenders with his quick bursts (1-2 phase is a substitution).

It is also because in the past, when I first started to learn about website building platforms, but I do not understand which man has written headlines that make me default NodeJS is running FAST, but it is like a dream. , with that in mind, I have been working with NodeJS projects with the thought ‘NodeJS is unmatched, I said it fast and it will be fast’, …

What are the academic concepts such as: EventLoop, CallStack, Non-Blocking I / O, Asynchornous Code , .. These concepts are already full on the Internet, but really do not fully understand and do not know when do I apply in the application. I think there are a lot of AEs who have / are / will have these problems until now.

And I keep thinking that NodeJS is a leader, going through many different projects, and what will come will come, I have had a chance to work  when faced with problems, if you stop and know, it is not sure to solve. OK.

In order for a player to have high speed, you must know the combination of breathing and stride to help your body in the best condition when running.

Breath coordination greatly affects your running steps (source: wikiHow)

And under different conditions and situations will also greatly affect the result of a Marathon

  • Newspaper is king in the short-sprint blocking, but not the strength for the long block race
  • And in the environment with HIGH temperature, humans will be the winners in the race block against ROTS, WOLF, and LIST.

(reference: https://qr.ae/pNWVOm )

Come back now, let’s explain together and understand why the Flower is beautiful but in the right place, or else it will be like this.

Non-Blocking I / O in Node

As many other articles mentioned, NodeJS works with MainThread (Event Loop), In addition to MainThread, LibUV also provides another type of Thread to help handle I / O tasks better, ThreadPool , to help NodeJS can efficiently handle I / O tasks. Nowadays, operating systems provide Asynchronous Interfaces that help NodeJS interact with the OS (Operating System) and try to push to the operating system, for example: AIO of Linux, epool (linux), kqueue (OSX) ) ,… In short, In addition to Async I / O tasks that are likely to be handled by the OS, ThreadPool does.

→ It’s also one of the strong points of NodeJS that makes handling I / O tasks nicer with the term ‘ Non-Blocking I / O ‘.

How about computational tasks via CPU?

For example:

  • Browse through 1 million items in the array to compute an expression.
  • Related problems computed on array traversing

In fact, if you run into one of the above problems, you could also handle it by splitting into sub arrays, which would look like this:

But with this approach, the complexity is still 0 (n), it doesn’t improve much, and importantly our # 1 problem is still not solved. If the system has an API containing the above function, then as we go, remember:

The performance of a system is the performance of the worst performing function.

or it can also be implied, ‘A worm makes the pot of soup’. Therefore, the system can be completely shut down by having at least one API of this type.

The above code describes how when a user accesses the API: ‘ / huge-arr ‘, we need to go through 10,000,000,000 items , and each run must compute a complex and time-consuming expression ( function sums through each iteration), and in the meantime, API entry requests: ‘ / check-health ‘ will pending until API ‘ / huge-arr ‘ returns the result via res.json (‘done, … ‘).

/ huge-arr blocks all other APIs

So how can we solve the above problem (avoid the API clogging the rest of the API until it is released), we have 2 solutions to solve:

  • Off-loading Technology
  • Partitioning Technique

If you have noticed, the Task Pushing Process that the Operating System already supports to handle I / O tasks over Interfaces that communicate directly with NodeJS is also considered an Off-Loading technique. But that is at another level in the NodeJS architecture. Since NodeJS v10.5 introduced WorkerThreads and LTS at v12.x. With WorkerThreads, We can proactively configure and handle CPU-related heavy-duty tasks with the Off-Loading Technology.

Image source: https://nodesource.com/blog/worker-threads-nodejs/

Off-Loading :

We haven’t reduced the algorithmic complexity (O (n)) yet, but it makes it possible to use Workers handling highly complex / heavy tasks instead of Main-Thread . This can also be seen simply, With high-speed creators, instead of slipping the ball from home, they can pass to the Wingers, and score after a cross from Defenders 😜.

Source: giphy.com ⚽

But the number of Workers is Limited, and there will inevitably be times when the number of requests is greater than the number of Workers ready to receive jobs (refer to the Off-Loading code in NodeJS: https://nodesource.com/blog/worker-threads) -nodejs / ). And then we have to talk more about Technique 2: Partitioning.

Partitioning

is a technique based on the principle of operation of the Phases in EventLoop (I will talk about it later) that we can reduce O (n) → O (1) for large-volume array traversing problems, for easy visualization. More capacities we have the following example 📉:

As you can also see, separating and processing 1 item / 1 tick 🔁 (1 iteration, related concept EventLoop) helps the App We can continue to receive other requests without worrying about the current Request processing done yet (end of array). When the user accesses’ / huge-arr-with-ronaldo ‘, it is no longer pending but can still receive other requests such as entering the’ / check-health ‘API without having to wait for the API response’ / huge-arr-with-ronaldo ‘;

Usually, I usually apply the following rule:

  • Offloading : for heavy duty + heavy computing
  • Partitioning : The array browsing task 🔁

Troubleshooting

So if we combine the two techniques above, we can solve the questions from the beginning of the article in the following order:

Question 3 : There are APIs, NodeJS needs tens of seconds in order to respond? (# 3) → In this point, it is necessary to clarify, if the bottleneck is in Database (Query with a large volume of data), we can improve it through Cache or Index optimization in Database. But if the problem is with the Javascript Code, we need to determine if this is an I / O or CPU task.

  • -IO-intensive: See if we are able to handle the I / O tasks well, have we blocked them?
  • CPU-intensive: Applying one or both of the techniques (Offloading-Partitioning) minimizes the need for EventLoop (Main-Thread) to take over and handle those heavy tasks. (Bonous: In addition, we need to pay attention to the parameters on Metric EventLoop, GC, Memory / CPU Profiler, Database Profiler , … to improve performance at the best stage)

Question 1 : How can I avoid the situation where a heavy request affects all other requests on a Web application using NodeJS? (#first)
Question 2 : Why do people say that NodeJS is fast, but sometimes slow at different APIs? (#2)
→ As Question 3 I mentioned, with heavy requests to analyze that are related to CPU or I / O to have appropriate handling plans (the combination of tools PerformanceTest + Monitoring will help us have something visual / visualization and identifying the bottleneck is the most important thing)

Hopefully here you also have some understanding of the Advantages / Disadvantages of NodeJS in each type of task, and of course, when we have the above disadvantages, we appreciate the advantages of NodeJS and the pros. as I was when I just learned.

Study, learn more, learn forever …

Actually, the above 2 techniques are a part that helps us to handle, of course, there will be many other factors, such as:

  • How can I detect which API is Bottleneck API ⏳?
  • At what level does the API come from: Network, Infrastructure, Application, Database , … or others?
  • Are you using Worker (the component that handles the job from WorkerThreads) is over?
  • Is your Javascript code really good, in the parts involved in handling: Synchronous / Asynchronous Code, REDOS, Garbage Collection ,…?

In the next articles, I will go into depth on each topic and answer each question through the topics I target.  Bingo, now bye and see you in the next posts!

Share the news now

Source : Viblo