How to better utilize the performance limits of node. js

Source: Internet
Author: User
Tags cassandra elasticsearch aggregation

By using non-blocking, event-driven I/O operations, node. JS provides a great platform for building and running large-scale network applications and services, and is also widely welcomed. Its main features are the ability to handle large, high-throughput concurrent connections to build high-performance, highly scalable Internet applications. However, node. JS single-threaded operation and limited manageable memory make it very limited in computing performance, limiting the application in some scenarios. Recently, Dave Galbraith, an engineer at the Jut development team, shared the limitations of node. js that they encountered and how to go beyond those limits. Next, this article analyzes the problem and the solution of the thought in detail.

First, the product developed by the Jut team is called the Operational Data Center (operations). The product is a Stream analytics platform designed specifically for research and development teams that collects operational data such as logs and events, and then analyzes and correlates them as a whole. Its core function is to be able to simultaneously process real-time data, historical data, structural and unstructured data. The specific product architecture is shown.

As can be seen, the core of the product is the data engine, including the underlying big data back end and JPC (Juttle processing Core) two parts. The whole system needs to rely on these big data backend systems, such as Elasticsearch and Cassandra, for the processing and storage of historical data and the recovery and management of general data. JPC uses node. js to achieve equal treatment of historical and real-time data, leveraging log data/ Measure data/Event data ask questions and send real-time data to the browser to visualize with D3. Furthermore, JPC is responsible for running the Juttle program. When the user clicks the Juttle program, the browser sends the program to JPC and converts it to JavaScript for execution. Galbraith proposed that The jut team chose to use node. js in JPC, including high-level programming languages such as JavaScript, to quickly complete the modeling and iterative process, with JavaScript implemented at the front of the program, and the backend using JavaScript to facilitate front-to-back coordination and communication; node. JS has a powerful open Community, so that the development team can effectively use the power of the community and other three aspects. JPC took advantage of the 103 NPM packages in the community and shared the 7 packages it developed.

Despite the very good features of node. JS, the JPC development team encountered some problems that node. JS could not directly solve:

    1. The node. JS application is single-threaded. This means that even if the computer is multi-core or multi-processor, node. JS applications can only take advantage of one, greatly limiting system performance.
    2. As the stack gets larger, node. JS's garbage collector becomes very inefficient. As the stack uses more than 1GB of space, the process of garbage collection starts to become very slow and can severely affect program performance.
    3. Because of the above problem, node. JS limits the amount of space that the stack can use to 1.5GB. Once this range is exceeded, the system will go wrong.
      To ensure the efficiency of the jut system, the Jut team came up with some solutions.

First, the Jut team adopted a way to avoid using node. js as much as possible to minimize the performance problems caused by node. JS Single Threading. JPC will cut the juttle flow graph into a few sub-graphs and then perform efficiently in the deeper layers of the jut platform. Take Elasticsearch as an example, before optimization, the process of the data request is: Elasticsearch the relevant data from the disk, and encode to json-> through the HTTP protocol sent to the JPC->JPC decoding JSON file, Perform the expected calculations. However, Elasticsearch has an aggregation (Aggregation) capability to perform calculations across datasets. In this way, a large request can be optimized for a elasticsearch aggregation, avoiding intermediate JSON conversions and the process of node. js for large-scale data calculations. Moreover, both Elasticsearch and Cassandra are written in Java and can effectively utilize multicore or multiprocessor resources for high-efficiency parallel computing. In summary, the JUT team effectively improves the performance of the system by minimizing the way in which it is calculated in node. js.

Second, about the stack space problem. Whenever a user asks a node. JS server to send a request to another server, the user provides some functions to process the data that is returned in the future. node. JS puts these functions into the event loop, waits for the data to be returned, and then calls the appropriate function for processing. This kind of interrupt-like approach can greatly improve the efficiency of single-threaded node. js. However, once one of the functions in the event loop has been calculated for too long, there is a problem with the system. Take the data that the user sends to node. JS to request several rows from another server, and then take a mathematical calculation of the data as an example. If the requested data exceeds the 1.5GB stack size limit, the calculation process can take up node. js for a long time, and not even complete. Because node. js is single-threaded, during this time, new requests or newly returned data can only be placed in the to-do list of the event loop. In this way, the response time of the node. JS server will increase significantly, affecting the normal processing of other requests.

To solve this problem, Jut has implemented paging (paging) wherever possible. This means that the system will not read large amounts of data at a time, but instead divide it into small requests. In the middle of these requests, the system can also processor new requests. Of course, multiple requests require a certain amount of communication costs. After the jut team's groping, 20,000 points are more appropriate size-the system can still be executed in a few milliseconds, and the general request does not require a large number of splits.

To address these issues, Galbraith shared a specific use case. As a loyal customer of Jut, NPM has been accompanied by jut from the Alpha version to the current beta version. A specific task for NPM is to find the top 10 downloads for the last two weeks of all packages, and then display them in tabular form on the site. The Juttle program can accomplish this task with very simple code:

Read-last:2 weeks: | Reduce count () by package | Sort Count-desc | Head 10 | @table

However, Jut ran into a problem the first time the program was run. After debugging, the problem is that JPC optimizes the read and reduce operations and merges them into a single elasticsearch aggregation operation. Since the aggregation operation itself does not support paging, and NPM has more than millions of packages, Elasticsearch returns a huge response of more than million arrays, with a total size of hundreds of MB. When the response is received, JPC attempts to process it one time, causing the memory space usage to exceed the 1.5GB limit. The garbage collector starts trying to reclaim space. As a result, the processing time exceeds the threshold value--60s that the JPC built-in monitoring service considers to be abnormal. The monitoring service restarted the JPC directly, causing the NPM task to remain incomplete.

To solve this problem, the Jut team used a method that mimics the elasticsearch of the aggregation for pagination. For the return of the results containing a lot of information, jpc it into small pieces that can be easily processed, processed by each. With the help of some public libraries, the modified JavaScript code is as follows:

var points = perform_elasticsearch_aggregtion (); ' Promise.each (_.range (points.length/20000), function Processchunk (n {        return Promise.try (function () {        process (points.splice (0, 20000));               }). Delay (1);    });

Promise.each(param1,param2)it is responsible for invoking the param1 function in the second argument for each element in the first parameter param2 ; the _.range(num) function receives a number num that returns an array of that number size. To include 1 million points for example, the above program needs to call the processChunk() function ( points.length/20000=1000000/20000=50 ). Each call is responsible for pulling 20,000 points out of the array and then calling the process() function to process it. Once processing is complete, the garbage collector can reclaim the space occupied by these 20,000 points. Promise.try()returns an object that can control the execution of a function in its arguments, using a function as a parameter. The method of the object .delay(1) represents a pause in the middle of multiple calls to allow processor 1ms to process other requests. After this modification, the program only took about 20s of time to complete the previous NPM task. Also, during this time, the server responds to other requests.

All-in-one programmer Exchange QQ Group 290551701, gather a lot of Internet elite, technical director, architect, Project Manager! Open source technology research, Welcome to the industry, Daniel and beginners are interested in engaging in IT industry personnel to enter!

How to better utilize the performance limits of node. js

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.