SlideShare a Scribd company logo
NODE, CAN YOU EVEN IN CPU
INTENSIVE OPERATIONS?
RAFAŁ OSTROWSKI
RAFAL.OSTROWSKI@TSH.IO
NODE.JS DEVELOPER
WHAT'S THE PLAN?
▸ SINGLE THREADED?
▸ NON BLOCKING I/O OPERATIONS
▸ PERFORMANCE TRAPS
▸ CPU-INTENSIVE OPERATIONS WITHOUT KILLING
OUR APPS
▸ HTTP REQUESTS
▸ DISK READS/WRITES
▸ DB
I/O OPERATIONS
NODE, CAN YOU EVEN IN CPU INTENSIVE OPERATIONS?
BLOCKING VS NON-
BLOCKING I/O
▸ NEXT OPERATIONS HAVE TO WAIT
▸ APPLICATION DOES NOTHING WHILE WAITING
FOR THE RESULT
▸ TOP-DOWN - SYNCHRONOUS
▸ TIME = FUNCTION'S CALL + OPERATION’S TIME
▸ EXAMPLE: readFileSync
BLOCKING I/O
NODE, CAN YOU EVEN IN CPU INTENSIVE OPERATIONS?
BLOCKING I/O EXAMPLE
▸ NEXT OPERATIONS DON'T HAVE TO WAIT
▸ ASYNC
▸ CALLBACKS!
▸ TIME = FUNCTION'S CALL + CALLBACK'S
HANDLING
▸ EXAMPLE: readFile
NON-BLOCKING I/O
NODE, CAN YOU EVEN IN CPU INTENSIVE OPERATIONS?
NON-BLOCKING I/O EXAMPLE
EVENT LOOP
“THE EVENT LOOP IS WHAT ALLOWS NODE.JS TO PERFORM NON-BLOCKING
I/O OPERATIONS,
DESPITE THE FACT THAT JAVASCRIPT IS SINGLE-THREADED,
BY OFFLOADING OPERATIONS TO THE SYSTEM KERNEL WHENEVER POSSIBLE.”
▸ SIMPLIFIED EXPLANATION!
▸ IMPLEMENTED IN LIBUV
▸ EVENT LOOP IS, WELL, AN EVENT LOOP
▸ STARTED WHEN NODE PROCESS STARTS
▸ ENDS WHEN THERE'S NOTHING MORE TO
PROCESS
EVENT LOOP
NODE, CAN YOU EVEN IN CPU INTENSIVE OPERATIONS?
Node, can you even in CPU intensive operations?
▸ SYNCHRONOUS CODE IS EASY
▸ ASYNC NOT SO MUCH - ESPECIALLY IN A SINGLE
THREADED ENVIRONMENT
▸ CALLBACKS MUST BE HANDLED SOMEHOW
▸ CAN'T HAPPEN ANYTIME
▸ WE NEED A MECHANISM THAT WILL QUEUE THESE
CALLBACKS
EVENT LOOP, WHAT FOR?
NODE, CAN YOU EVEN IN CPU INTENSIVE OPERATIONS?
LET'S RUN SOME
BENCHMARKS
BENCHMARKS
NODE, CAN YOU EVEN IN CPU INTENSIVE OPERATIONS?
▸ API
▸ /userBlocking
▸ /userNonBlocking
▸ USER READ TIME = 75ms
▸ APACHE BENCHMARK: -c 10 -t 5
Node, can you even in CPU intensive operations?
Node, can you even in CPU intensive operations?
LIFE'S GOOD
NODE, CAN YOU EVEN IN CPU INTENSIVE OPERATIONS?
▸ API RUNNING HAPPILY ON PROD
▸ NON-BLOCKING I/O ONLY
▸ AWESOME PERFORMANCE OUT OF THE BOX
▸ $$$$
NEW REQUIREMENTS
Node, can you even in CPU intensive operations?
NEW REQUIREMENTS
NODE, CAN YOU EVEN IN CPU INTENSIVE OPERATIONS?
▸ NEW ENDPOINT FOR SOME HYPER COMPLICATED
CALCULATIONS
▸ CONSUMED BY OTHER TEAM
▸ BATCH JOB
▸ OUR ALGORITHM WILL PROCESS SOME DATA
▸ WE'LL EXPOSE THE ENDPOINT IN OUR EXISTING
API
DEPLOY
Node, can you even in CPU intensive operations?
Node, can you even in CPU intensive operations?
Node, can you even in CPU intensive operations?
LET’S FIND (AND HOPEFULLY
FIX) THE PROBLEM
LET’S FIND THE PROBLEM
NODE, CAN YOU EVEN IN CPU INTENSIVE OPERATIONS?
▸ HIT CPU-CONSUMING ENDPOINT IN A LOOP
▸ RUN THE SAME BENCHMARK AS BEFORE (ab -c 10
-t 5)
Node, can you even in CPU intensive operations?
Node, can you even in CPU intensive operations?
CLUSTER MODE
"A SINGLE INSTANCE OF NODE.JS RUNS IN A SINGLE THREAD.
TO TAKE ADVANTAGE OF MULTI-CORE SYSTEMS, THE USER
WILL SOMETIMES WANT TO LAUNCH A CLUSTER OF NODE.JS
PROCESSES TO HANDLE THE LOAD."
▸ WE'LL HARNESS OUR CPU'S FULL POWER
▸ LOAD BALANCER OUT OF THE BOX
▸ LET'S IMPLEMENT IT!
CLUSTER MODE
NODE, CAN YOU EVEN IN CPU INTENSIVE OPERATIONS?
const cluster = require('cluster');
const numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
console.log(`Master ${process.pid} is running`);
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', (worker, code, signal) => {
console.log(`worker ${worker.process.pid} died`);
});
} else {
// run http server
console.log(`Process ${process.pid} started`);
}
const cluster = require('cluster');
const numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
console.log(`Master ${process.pid} is running`);
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', (worker, code, signal) => {
console.log(`worker ${worker.process.pid} died`);
});
} else {
// run http server
console.log(`Process ${process.pid} started`);
}
const cluster = require('cluster');
const numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
console.log(`Master ${process.pid} is running`);
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', (worker, code, signal) => {
console.log(`worker ${worker.process.pid} died`);
});
} else {
// run http server
console.log(`Process ${process.pid} started`);
}
const cluster = require('cluster');
const numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
console.log(`Master ${process.pid} is running`);
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', (worker, code, signal) => {
console.log(`worker ${worker.process.pid} died`);
});
} else {
// run http server
console.log(`Process ${process.pid} started`);
}
LET'S RUN SOME
BENCHMARKS
Node, can you even in CPU intensive operations?
Node, can you even in CPU intensive operations?
DEPLOY
Node, can you even in CPU intensive operations?
Node, can you even in CPU intensive operations?
Node, can you even in CPU intensive operations?
LET’S FIND (AND FIX) THE
PROBLEM
LET’S FIND THE PROBLEM (AGAIN)
NODE, CAN YOU EVEN IN CPU INTENSIVE OPERATIONS?
▸ HIT CPU-CONSUMING ENDPOINT IN A LOOP, BUT
IN PARALLEL THIS TIME (5 SCRIPTS
SIMULTANEOUSLY)
▸ RUN THE SAME BENCHMARK AS BEFORE (ab -c 10
-t 5) on /userNonBlocking
Node, can you even in CPU intensive operations?
Node, can you even in CPU intensive operations?
WORKER THREADS
"WORKERS (THREADS) ARE USEFUL FOR PERFORMING CPU-INTENSIVE JAVASCRIPT
OPERATIONS.
THEY WILL NOT HELP MUCH WITH I/O-INTENSIVE WORK.
NODE.JS’S BUILT-IN ASYNCHRONOUS I/O OPERATIONS ARE MORE EFFICIENT THAN
WORKERS CAN BE."
WORKER THREADS
NODE, CAN YOU EVEN IN CPU INTENSIVE OPERATIONS?
▸ ADDED IN NODE 10.5
▸ ALLOWS TO EXECUTE JAVASCRIPT IN PARALLEL
▸ STABILITY: EXPERIMENTAL
▸ FLAG --experimental-worker NEEDED FOR NODE <
11.7
▸ 'worker_threads' MODULE
LET'S IMPLEMENT IT!
const {Worker, isMainThread, parentPort} = require('worker_threads')
if (isMainThread) {
module.exports = async function timeConsumingOperationOnThreads(raw) {
return new Promise((resolve, reject) => {
const worker = new Worker(__filename, {
workerData: raw
});
worker.on('message', resolve)
worker.on('error', reject)
worker.on('exit', (code) => {
if (code !== 0) {
reject(new Error(`Worker stopped with exit code ${code}`))
}
});
});
};
} else {
const result = runSuperComplicatedAlgorithm()
parentPort.postMessage({ result })
}
const {Worker, isMainThread, parentPort} = require('worker_threads')
if (isMainThread) {
module.exports = async function timeConsumingOperationOnThreads(raw) {
return new Promise((resolve, reject) => {
const worker = new Worker(__filename, {
workerData: raw
});
worker.on('message', resolve)
worker.on('error', reject)
worker.on('exit', (code) => {
if (code !== 0) {
reject(new Error(`Worker stopped with exit code ${code}`))
}
});
});
};
} else {
const result = runSuperComplicatedAlgorithm()
parentPort.postMessage({ result })
}
const {Worker, isMainThread, parentPort} = require('worker_threads')
if (isMainThread) {
module.exports = async function timeConsumingOperationOnThreads(raw) {
return new Promise((resolve, reject) => {
const worker = new Worker(__filename, {
workerData: raw
});
worker.on('message', resolve)
worker.on('error', reject)
worker.on('exit', (code) => {
if (code !== 0) {
reject(new Error(`Worker stopped with exit code ${code}`))
}
});
});
};
} else {
const result = runSuperComplicatedAlgorithm()
parentPort.postMessage({ result })
}
const {Worker, isMainThread, parentPort} = require('worker_threads')
if (isMainThread) {
module.exports = async function timeConsumingOperationOnThreads(raw) {
return new Promise((resolve, reject) => {
const worker = new Worker(__filename, {
workerData: raw
});
worker.on('message', resolve)
worker.on('error', reject)
worker.on('exit', (code) => {
if (code !== 0) {
reject(new Error(`Worker stopped with exit code ${code}`))
}
});
});
};
} else {
const result = runSuperComplicatedAlgorithm()
parentPort.postMessage({ result })
}
LET'S RUN SOME
BENCHMARKS
Node, can you even in CPU intensive operations?
Node, can you even in CPU intensive operations?
DEPLOY
Node, can you even in CPU intensive operations?
Node, can you even in CPU intensive operations?
ALTERNATIVES
PARTITIONING
NODE, CAN YOU EVEN IN CPU INTENSIVE OPERATIONS?
▸ COMPLETE PART OF THE WORK => PUSH BACK TO
EVENT LOOP
▸ NOT APPLICABLE TO ALL ALGORITHMS
▸ WILL TAKE LONGER TIME
▸ MIGHT NOT BE POSSIBLE WHEN USING EXTERNAL
LIBRARIES
▸ HARDER TO REASON ABOUT
WITHOUT PARTITIONING:
WITH PARTITIONING:
PROCESS.FORK
NODE, CAN YOU EVEN IN CPU INTENSIVE OPERATIONS?
▸ IMPOSSIBLE TO SHARE MEMORY BETWEEN
PROCESSES
▸ EXPENSIVE IN TERMS OF RESOURCES
▸ NOT AS LIGHTWEIGHT AS THREADS
▸ WHY?
Node, can you even in CPU intensive operations?
PROCESS.FORK CONT.
NODE, CAN YOU EVEN IN CPU INTENSIVE OPERATIONS?
▸ NEW WORKER THREAD * 500 = ~2000 ms
▸ NEW PROCESS * 500 = ~12300 ms
CHANGE YOUR ARCHITECTURE
NODE, CAN YOU EVEN IN CPU INTENSIVE OPERATIONS?
▸ SEPARATE API
▸ MOVE TIME CONSUMING OPERATION TO A
SEPARATE SERVICE WITH A QUEUE IN FRONT OF IT
▸ THEY WILL STILL SUFFER FROM LOW
PERFORMANCE, JUST WON’T AFFECT OTHER
ENDPOINTS
“(...) HOWEVER, IF YOUR SERVER RELIES HEAVILY ON COMPLEX
CALCULATIONS, YOU SHOULD THINK ABOUT WHETHER NODE IS REALLY A GOOD
FIT.
NODE EXCELS FOR I/O-BOUND WORK, BUT FOR EXPENSIVE COMPUTATION IT
MIGHT NOT BE THE BEST OPTION.”
▸ FAVOR NON-BLOCKING (ASYNC) I/O OVER
BLOCKING OPERATION
▸ VERTICAL SCALING (CLUSTER MODE) MIGHT NOT
SOLVE YOUR PROBLEMS WITH CPU-INTENSIVE
OPERATIONS...
▸ ...BUT WORKER THREADS CAN (JUST REMEMBER -
THEY'RE STILL AN EXPERIMENTAL FEATURE!)
▸ NODE.JS EXCELS IN I/O BOUND AND MIGHT NOT
BE THE BEST CHOICE FOR CPU-HEAVY
OPERATIONS
SUMMARY
NODE, CAN YOU EVEN IN CPU INTENSIVE OPERATIONS?
THANKS

More Related Content

What's hot (20)

PDF
Node.js Event Loop & EventEmitter
Simen Li
 
PPT
JavaScript Event Loop
Thomas Hunter II
 
PDF
Everything as a code
Aleksandr Tarasov
 
KEY
Don’t block the event loop!
hujinpu
 
PDF
Network Automation: Ansible 102
APNIC
 
PPTX
How NOT to write in Node.js
Piotr Pelczar
 
PDF
Test driven infrastructure
Skills Matter Talks
 
PPT
Node js presentation
martincabrera
 
PDF
Node.js API 서버 성능 개선기
JeongHun Byeon
 
PDF
DevOps(2) : Vagrant - (MOSG)
Soshi Nemoto
 
PDF
Ceph Day Shanghai - Ceph Performance Tools
Ceph Community
 
PDF
Using Node.js to Build Great Streaming Services - HTML5 Dev Conf
Tom Croucher
 
PDF
DevOps(4) : Ansible(2) - (MOSG)
Soshi Nemoto
 
PDF
Preparation study of_docker - (MOSG)
Soshi Nemoto
 
PPTX
Introduction to Ansible
CoreStack
 
PPT
JS everywhere 2011
Oleg Podsechin
 
PPTX
ES6, 잘 쓰고 계시죠?
장현 한
 
PDF
DevOps(3) : Ansible - (MOSG)
Soshi Nemoto
 
PDF
Ansible 2.0
Dennis Rowe
 
PDF
Instruction: dev environment
Soshi Nemoto
 
Node.js Event Loop & EventEmitter
Simen Li
 
JavaScript Event Loop
Thomas Hunter II
 
Everything as a code
Aleksandr Tarasov
 
Don’t block the event loop!
hujinpu
 
Network Automation: Ansible 102
APNIC
 
How NOT to write in Node.js
Piotr Pelczar
 
Test driven infrastructure
Skills Matter Talks
 
Node js presentation
martincabrera
 
Node.js API 서버 성능 개선기
JeongHun Byeon
 
DevOps(2) : Vagrant - (MOSG)
Soshi Nemoto
 
Ceph Day Shanghai - Ceph Performance Tools
Ceph Community
 
Using Node.js to Build Great Streaming Services - HTML5 Dev Conf
Tom Croucher
 
DevOps(4) : Ansible(2) - (MOSG)
Soshi Nemoto
 
Preparation study of_docker - (MOSG)
Soshi Nemoto
 
Introduction to Ansible
CoreStack
 
JS everywhere 2011
Oleg Podsechin
 
ES6, 잘 쓰고 계시죠?
장현 한
 
DevOps(3) : Ansible - (MOSG)
Soshi Nemoto
 
Ansible 2.0
Dennis Rowe
 
Instruction: dev environment
Soshi Nemoto
 

Similar to Node, can you even in CPU intensive operations? (20)

PDF
Faster PHP apps using Queues and Workers
Richard Baker
 
PDF
To AWS with Ansible
☁️ Gerben Geijteman
 
PDF
Developer-friendly taskqueues: What you should ask yourself before choosing one
Sylvain Zimmer
 
PDF
Developer-friendly task queues: what we learned building MRQ, Sylvain Zimmer
Pôle Systematic Paris-Region
 
PDF
Stress Test & Chaos Engineering
Diego Pacheco
 
PPT
Threaded Programming
Sri Prasanna
 
PDF
Introducing Ansible
Francesco Pantano
 
PDF
Tips on how to improve the performance of your custom modules for high volume...
Odoo
 
PDF
Confitura 2018 — Apache Beam — Promyk Nadziei Data Engineera
Piotr Wikiel
 
PDF
Multiprocessing with python
Patrick Vergain
 
PDF
maXbox Starter 42 Multiprocessing Programming
Max Kleiner
 
PDF
AI&BigData Lab. Александр Конопко "Celos: оркестрирование и тестирование зада...
GeeksLab Odessa
 
KEY
Capistrano, Puppet, and Chef
David Benjamin
 
ODP
Plproxy
Joshua Drake
 
PPT
Node.js: CAMTA Presentation
Rob Tweed
 
PDF
Continuous Delivery: The Dirty Details
Mike Brittain
 
PDF
How to deploy node to production
Sean Hess
 
PDF
HC-4021, Efficient scheduling of OpenMP and OpenCL™ workloads on Accelerated ...
AMD Developer Central
 
PDF
Jenkins 101: Getting Started
R Geoffrey Avery
 
PPTX
Coroutines talk ppt
Shahroz Khan
 
Faster PHP apps using Queues and Workers
Richard Baker
 
To AWS with Ansible
☁️ Gerben Geijteman
 
Developer-friendly taskqueues: What you should ask yourself before choosing one
Sylvain Zimmer
 
Developer-friendly task queues: what we learned building MRQ, Sylvain Zimmer
Pôle Systematic Paris-Region
 
Stress Test & Chaos Engineering
Diego Pacheco
 
Threaded Programming
Sri Prasanna
 
Introducing Ansible
Francesco Pantano
 
Tips on how to improve the performance of your custom modules for high volume...
Odoo
 
Confitura 2018 — Apache Beam — Promyk Nadziei Data Engineera
Piotr Wikiel
 
Multiprocessing with python
Patrick Vergain
 
maXbox Starter 42 Multiprocessing Programming
Max Kleiner
 
AI&BigData Lab. Александр Конопко "Celos: оркестрирование и тестирование зада...
GeeksLab Odessa
 
Capistrano, Puppet, and Chef
David Benjamin
 
Plproxy
Joshua Drake
 
Node.js: CAMTA Presentation
Rob Tweed
 
Continuous Delivery: The Dirty Details
Mike Brittain
 
How to deploy node to production
Sean Hess
 
HC-4021, Efficient scheduling of OpenMP and OpenCL™ workloads on Accelerated ...
AMD Developer Central
 
Jenkins 101: Getting Started
R Geoffrey Avery
 
Coroutines talk ppt
Shahroz Khan
 
Ad

More from The Software House (20)

PDF
Jak kraść miliony, czyli o błędach bezpieczeństwa, które mogą spotkać również...
The Software House
 
PDF
Uszanowanko Podsumowanko
The Software House
 
PDF
Jak efektywnie podejść do certyfikacji w AWS?
The Software House
 
PDF
O co chodzi z tą dostępnością cyfrową?
The Software House
 
PDF
Chat tekstowy z użyciem Amazon Chime
The Software House
 
PDF
Migracje danych serverless
The Software House
 
PDF
Jak nie zwariować z architekturą Serverless?
The Software House
 
PDF
Analiza semantyczna artykułów prasowych w 5 sprintów z użyciem AWS
The Software House
 
PDF
Feature flags na ratunek projektu w JavaScript
The Software House
 
PDF
Typowanie nominalne w TypeScript
The Software House
 
PDF
Automatyzacja tworzenia frontendu z wykorzystaniem GraphQL
The Software House
 
PDF
Serverless Compose vs hurtownia danych
The Software House
 
PDF
Testy API: połączenie z bazą danych czy implementacja w pamięci
The Software House
 
PDF
Jak skutecznie read model. Case study
The Software House
 
PDF
Firestore czyli ognista baza od giganta z Doliny Krzemowej
The Software House
 
PDF
Jak utrzymać stado Lambd w ryzach
The Software House
 
PDF
Jak poskromić AWS?
The Software House
 
PDF
O łączeniu Storyblok i Next.js
The Software House
 
PDF
Amazon Step Functions. Sposób na implementację procesów w chmurze
The Software House
 
PDF
Od Figmy do gotowej aplikacji bez linijki kodu
The Software House
 
Jak kraść miliony, czyli o błędach bezpieczeństwa, które mogą spotkać również...
The Software House
 
Uszanowanko Podsumowanko
The Software House
 
Jak efektywnie podejść do certyfikacji w AWS?
The Software House
 
O co chodzi z tą dostępnością cyfrową?
The Software House
 
Chat tekstowy z użyciem Amazon Chime
The Software House
 
Migracje danych serverless
The Software House
 
Jak nie zwariować z architekturą Serverless?
The Software House
 
Analiza semantyczna artykułów prasowych w 5 sprintów z użyciem AWS
The Software House
 
Feature flags na ratunek projektu w JavaScript
The Software House
 
Typowanie nominalne w TypeScript
The Software House
 
Automatyzacja tworzenia frontendu z wykorzystaniem GraphQL
The Software House
 
Serverless Compose vs hurtownia danych
The Software House
 
Testy API: połączenie z bazą danych czy implementacja w pamięci
The Software House
 
Jak skutecznie read model. Case study
The Software House
 
Firestore czyli ognista baza od giganta z Doliny Krzemowej
The Software House
 
Jak utrzymać stado Lambd w ryzach
The Software House
 
Jak poskromić AWS?
The Software House
 
O łączeniu Storyblok i Next.js
The Software House
 
Amazon Step Functions. Sposób na implementację procesów w chmurze
The Software House
 
Od Figmy do gotowej aplikacji bez linijki kodu
The Software House
 
Ad

Recently uploaded (20)

PPT
Computer Securityyyyyyyy - Chapter 2.ppt
SolomonSB
 
PPTX
一比一原版(SUNY-Albany毕业证)纽约州立大学奥尔巴尼分校毕业证如何办理
Taqyea
 
PPTX
西班牙武康大学毕业证书{UCAMOfferUCAM成绩单水印}原版制作
Taqyea
 
PPTX
L1A Season 1 Guide made by A hegy Eng Grammar fixed
toszolder91
 
PPTX
ONLINE BIRTH CERTIFICATE APPLICATION SYSYTEM PPT.pptx
ShyamasreeDutta
 
PDF
DevOps Design for different deployment options
henrymails
 
PDF
Web Hosting for Shopify WooCommerce etc.
Harry_Phoneix Harry_Phoneix
 
PPTX
Cost_of_Quality_Presentation_Software_Engineering.pptx
farispalayi
 
PDF
Build Fast, Scale Faster: Milvus vs. Zilliz Cloud for Production-Ready AI
Zilliz
 
PPTX
法国巴黎第二大学本科毕业证{Paris 2学费发票Paris 2成绩单}办理方法
Taqyea
 
PDF
Apple_Environmental_Progress_Report_2025.pdf
yiukwong
 
PPT
Agilent Optoelectronic Solutions for Mobile Application
andreashenniger2
 
PDF
The-Hidden-Dangers-of-Skipping-Penetration-Testing.pdf.pdf
naksh4thra
 
PPTX
英国假毕业证诺森比亚大学成绩单GPA修改UNN学生卡网上可查学历成绩单
Taqyea
 
PPTX
本科硕士学历佛罗里达大学毕业证(UF毕业证书)24小时在线办理
Taqyea
 
PPTX
sajflsajfljsdfljslfjslfsdfas;fdsfksadfjlsdflkjslgfs;lfjlsajfl;sajfasfd.pptx
theknightme
 
PPTX
INTEGRATION OF ICT IN LEARNING AND INCORPORATIING TECHNOLOGY
kvshardwork1235
 
PDF
𝐁𝐔𝐊𝐓𝐈 𝐊𝐄𝐌𝐄𝐍𝐀𝐍𝐆𝐀𝐍 𝐊𝐈𝐏𝐄𝐑𝟒𝐃 𝐇𝐀𝐑𝐈 𝐈𝐍𝐈 𝟐𝟎𝟐𝟓
hokimamad0
 
PPTX
一比一原版(LaTech毕业证)路易斯安那理工大学毕业证如何办理
Taqyea
 
PPTX
internet básico presentacion es una red global
70965857
 
Computer Securityyyyyyyy - Chapter 2.ppt
SolomonSB
 
一比一原版(SUNY-Albany毕业证)纽约州立大学奥尔巴尼分校毕业证如何办理
Taqyea
 
西班牙武康大学毕业证书{UCAMOfferUCAM成绩单水印}原版制作
Taqyea
 
L1A Season 1 Guide made by A hegy Eng Grammar fixed
toszolder91
 
ONLINE BIRTH CERTIFICATE APPLICATION SYSYTEM PPT.pptx
ShyamasreeDutta
 
DevOps Design for different deployment options
henrymails
 
Web Hosting for Shopify WooCommerce etc.
Harry_Phoneix Harry_Phoneix
 
Cost_of_Quality_Presentation_Software_Engineering.pptx
farispalayi
 
Build Fast, Scale Faster: Milvus vs. Zilliz Cloud for Production-Ready AI
Zilliz
 
法国巴黎第二大学本科毕业证{Paris 2学费发票Paris 2成绩单}办理方法
Taqyea
 
Apple_Environmental_Progress_Report_2025.pdf
yiukwong
 
Agilent Optoelectronic Solutions for Mobile Application
andreashenniger2
 
The-Hidden-Dangers-of-Skipping-Penetration-Testing.pdf.pdf
naksh4thra
 
英国假毕业证诺森比亚大学成绩单GPA修改UNN学生卡网上可查学历成绩单
Taqyea
 
本科硕士学历佛罗里达大学毕业证(UF毕业证书)24小时在线办理
Taqyea
 
sajflsajfljsdfljslfjslfsdfas;fdsfksadfjlsdflkjslgfs;lfjlsajfl;sajfasfd.pptx
theknightme
 
INTEGRATION OF ICT IN LEARNING AND INCORPORATIING TECHNOLOGY
kvshardwork1235
 
𝐁𝐔𝐊𝐓𝐈 𝐊𝐄𝐌𝐄𝐍𝐀𝐍𝐆𝐀𝐍 𝐊𝐈𝐏𝐄𝐑𝟒𝐃 𝐇𝐀𝐑𝐈 𝐈𝐍𝐈 𝟐𝟎𝟐𝟓
hokimamad0
 
一比一原版(LaTech毕业证)路易斯安那理工大学毕业证如何办理
Taqyea
 
internet básico presentacion es una red global
70965857
 

Node, can you even in CPU intensive operations?

  • 1. NODE, CAN YOU EVEN IN CPU INTENSIVE OPERATIONS?
  • 3. WHAT'S THE PLAN? ▸ SINGLE THREADED? ▸ NON BLOCKING I/O OPERATIONS ▸ PERFORMANCE TRAPS ▸ CPU-INTENSIVE OPERATIONS WITHOUT KILLING OUR APPS
  • 4. ▸ HTTP REQUESTS ▸ DISK READS/WRITES ▸ DB I/O OPERATIONS NODE, CAN YOU EVEN IN CPU INTENSIVE OPERATIONS?
  • 6. ▸ NEXT OPERATIONS HAVE TO WAIT ▸ APPLICATION DOES NOTHING WHILE WAITING FOR THE RESULT ▸ TOP-DOWN - SYNCHRONOUS ▸ TIME = FUNCTION'S CALL + OPERATION’S TIME ▸ EXAMPLE: readFileSync BLOCKING I/O NODE, CAN YOU EVEN IN CPU INTENSIVE OPERATIONS?
  • 8. ▸ NEXT OPERATIONS DON'T HAVE TO WAIT ▸ ASYNC ▸ CALLBACKS! ▸ TIME = FUNCTION'S CALL + CALLBACK'S HANDLING ▸ EXAMPLE: readFile NON-BLOCKING I/O NODE, CAN YOU EVEN IN CPU INTENSIVE OPERATIONS?
  • 11. “THE EVENT LOOP IS WHAT ALLOWS NODE.JS TO PERFORM NON-BLOCKING I/O OPERATIONS, DESPITE THE FACT THAT JAVASCRIPT IS SINGLE-THREADED, BY OFFLOADING OPERATIONS TO THE SYSTEM KERNEL WHENEVER POSSIBLE.”
  • 12. ▸ SIMPLIFIED EXPLANATION! ▸ IMPLEMENTED IN LIBUV ▸ EVENT LOOP IS, WELL, AN EVENT LOOP ▸ STARTED WHEN NODE PROCESS STARTS ▸ ENDS WHEN THERE'S NOTHING MORE TO PROCESS EVENT LOOP NODE, CAN YOU EVEN IN CPU INTENSIVE OPERATIONS?
  • 14. ▸ SYNCHRONOUS CODE IS EASY ▸ ASYNC NOT SO MUCH - ESPECIALLY IN A SINGLE THREADED ENVIRONMENT ▸ CALLBACKS MUST BE HANDLED SOMEHOW ▸ CAN'T HAPPEN ANYTIME ▸ WE NEED A MECHANISM THAT WILL QUEUE THESE CALLBACKS EVENT LOOP, WHAT FOR? NODE, CAN YOU EVEN IN CPU INTENSIVE OPERATIONS?
  • 16. BENCHMARKS NODE, CAN YOU EVEN IN CPU INTENSIVE OPERATIONS? ▸ API ▸ /userBlocking ▸ /userNonBlocking ▸ USER READ TIME = 75ms ▸ APACHE BENCHMARK: -c 10 -t 5
  • 19. LIFE'S GOOD NODE, CAN YOU EVEN IN CPU INTENSIVE OPERATIONS? ▸ API RUNNING HAPPILY ON PROD ▸ NON-BLOCKING I/O ONLY ▸ AWESOME PERFORMANCE OUT OF THE BOX ▸ $$$$
  • 22. NEW REQUIREMENTS NODE, CAN YOU EVEN IN CPU INTENSIVE OPERATIONS? ▸ NEW ENDPOINT FOR SOME HYPER COMPLICATED CALCULATIONS ▸ CONSUMED BY OTHER TEAM ▸ BATCH JOB ▸ OUR ALGORITHM WILL PROCESS SOME DATA ▸ WE'LL EXPOSE THE ENDPOINT IN OUR EXISTING API
  • 27. LET’S FIND (AND HOPEFULLY FIX) THE PROBLEM
  • 28. LET’S FIND THE PROBLEM NODE, CAN YOU EVEN IN CPU INTENSIVE OPERATIONS? ▸ HIT CPU-CONSUMING ENDPOINT IN A LOOP ▸ RUN THE SAME BENCHMARK AS BEFORE (ab -c 10 -t 5)
  • 32. "A SINGLE INSTANCE OF NODE.JS RUNS IN A SINGLE THREAD. TO TAKE ADVANTAGE OF MULTI-CORE SYSTEMS, THE USER WILL SOMETIMES WANT TO LAUNCH A CLUSTER OF NODE.JS PROCESSES TO HANDLE THE LOAD."
  • 33. ▸ WE'LL HARNESS OUR CPU'S FULL POWER ▸ LOAD BALANCER OUT OF THE BOX ▸ LET'S IMPLEMENT IT! CLUSTER MODE NODE, CAN YOU EVEN IN CPU INTENSIVE OPERATIONS?
  • 34. const cluster = require('cluster'); const numCPUs = require('os').cpus().length; if (cluster.isMaster) { console.log(`Master ${process.pid} is running`); for (let i = 0; i < numCPUs; i++) { cluster.fork(); } cluster.on('exit', (worker, code, signal) => { console.log(`worker ${worker.process.pid} died`); }); } else { // run http server console.log(`Process ${process.pid} started`); }
  • 35. const cluster = require('cluster'); const numCPUs = require('os').cpus().length; if (cluster.isMaster) { console.log(`Master ${process.pid} is running`); for (let i = 0; i < numCPUs; i++) { cluster.fork(); } cluster.on('exit', (worker, code, signal) => { console.log(`worker ${worker.process.pid} died`); }); } else { // run http server console.log(`Process ${process.pid} started`); }
  • 36. const cluster = require('cluster'); const numCPUs = require('os').cpus().length; if (cluster.isMaster) { console.log(`Master ${process.pid} is running`); for (let i = 0; i < numCPUs; i++) { cluster.fork(); } cluster.on('exit', (worker, code, signal) => { console.log(`worker ${worker.process.pid} died`); }); } else { // run http server console.log(`Process ${process.pid} started`); }
  • 37. const cluster = require('cluster'); const numCPUs = require('os').cpus().length; if (cluster.isMaster) { console.log(`Master ${process.pid} is running`); for (let i = 0; i < numCPUs; i++) { cluster.fork(); } cluster.on('exit', (worker, code, signal) => { console.log(`worker ${worker.process.pid} died`); }); } else { // run http server console.log(`Process ${process.pid} started`); }
  • 45. LET’S FIND (AND FIX) THE PROBLEM
  • 46. LET’S FIND THE PROBLEM (AGAIN) NODE, CAN YOU EVEN IN CPU INTENSIVE OPERATIONS? ▸ HIT CPU-CONSUMING ENDPOINT IN A LOOP, BUT IN PARALLEL THIS TIME (5 SCRIPTS SIMULTANEOUSLY) ▸ RUN THE SAME BENCHMARK AS BEFORE (ab -c 10 -t 5) on /userNonBlocking
  • 50. "WORKERS (THREADS) ARE USEFUL FOR PERFORMING CPU-INTENSIVE JAVASCRIPT OPERATIONS. THEY WILL NOT HELP MUCH WITH I/O-INTENSIVE WORK. NODE.JS’S BUILT-IN ASYNCHRONOUS I/O OPERATIONS ARE MORE EFFICIENT THAN WORKERS CAN BE."
  • 51. WORKER THREADS NODE, CAN YOU EVEN IN CPU INTENSIVE OPERATIONS? ▸ ADDED IN NODE 10.5 ▸ ALLOWS TO EXECUTE JAVASCRIPT IN PARALLEL ▸ STABILITY: EXPERIMENTAL ▸ FLAG --experimental-worker NEEDED FOR NODE < 11.7 ▸ 'worker_threads' MODULE
  • 53. const {Worker, isMainThread, parentPort} = require('worker_threads') if (isMainThread) { module.exports = async function timeConsumingOperationOnThreads(raw) { return new Promise((resolve, reject) => { const worker = new Worker(__filename, { workerData: raw }); worker.on('message', resolve) worker.on('error', reject) worker.on('exit', (code) => { if (code !== 0) { reject(new Error(`Worker stopped with exit code ${code}`)) } }); }); }; } else { const result = runSuperComplicatedAlgorithm() parentPort.postMessage({ result }) }
  • 54. const {Worker, isMainThread, parentPort} = require('worker_threads') if (isMainThread) { module.exports = async function timeConsumingOperationOnThreads(raw) { return new Promise((resolve, reject) => { const worker = new Worker(__filename, { workerData: raw }); worker.on('message', resolve) worker.on('error', reject) worker.on('exit', (code) => { if (code !== 0) { reject(new Error(`Worker stopped with exit code ${code}`)) } }); }); }; } else { const result = runSuperComplicatedAlgorithm() parentPort.postMessage({ result }) }
  • 55. const {Worker, isMainThread, parentPort} = require('worker_threads') if (isMainThread) { module.exports = async function timeConsumingOperationOnThreads(raw) { return new Promise((resolve, reject) => { const worker = new Worker(__filename, { workerData: raw }); worker.on('message', resolve) worker.on('error', reject) worker.on('exit', (code) => { if (code !== 0) { reject(new Error(`Worker stopped with exit code ${code}`)) } }); }); }; } else { const result = runSuperComplicatedAlgorithm() parentPort.postMessage({ result }) }
  • 56. const {Worker, isMainThread, parentPort} = require('worker_threads') if (isMainThread) { module.exports = async function timeConsumingOperationOnThreads(raw) { return new Promise((resolve, reject) => { const worker = new Worker(__filename, { workerData: raw }); worker.on('message', resolve) worker.on('error', reject) worker.on('exit', (code) => { if (code !== 0) { reject(new Error(`Worker stopped with exit code ${code}`)) } }); }); }; } else { const result = runSuperComplicatedAlgorithm() parentPort.postMessage({ result }) }
  • 64. PARTITIONING NODE, CAN YOU EVEN IN CPU INTENSIVE OPERATIONS? ▸ COMPLETE PART OF THE WORK => PUSH BACK TO EVENT LOOP ▸ NOT APPLICABLE TO ALL ALGORITHMS ▸ WILL TAKE LONGER TIME ▸ MIGHT NOT BE POSSIBLE WHEN USING EXTERNAL LIBRARIES ▸ HARDER TO REASON ABOUT
  • 67. PROCESS.FORK NODE, CAN YOU EVEN IN CPU INTENSIVE OPERATIONS? ▸ IMPOSSIBLE TO SHARE MEMORY BETWEEN PROCESSES ▸ EXPENSIVE IN TERMS OF RESOURCES ▸ NOT AS LIGHTWEIGHT AS THREADS ▸ WHY?
  • 69. PROCESS.FORK CONT. NODE, CAN YOU EVEN IN CPU INTENSIVE OPERATIONS? ▸ NEW WORKER THREAD * 500 = ~2000 ms ▸ NEW PROCESS * 500 = ~12300 ms
  • 70. CHANGE YOUR ARCHITECTURE NODE, CAN YOU EVEN IN CPU INTENSIVE OPERATIONS? ▸ SEPARATE API ▸ MOVE TIME CONSUMING OPERATION TO A SEPARATE SERVICE WITH A QUEUE IN FRONT OF IT ▸ THEY WILL STILL SUFFER FROM LOW PERFORMANCE, JUST WON’T AFFECT OTHER ENDPOINTS
  • 71. “(...) HOWEVER, IF YOUR SERVER RELIES HEAVILY ON COMPLEX CALCULATIONS, YOU SHOULD THINK ABOUT WHETHER NODE IS REALLY A GOOD FIT. NODE EXCELS FOR I/O-BOUND WORK, BUT FOR EXPENSIVE COMPUTATION IT MIGHT NOT BE THE BEST OPTION.”
  • 72. ▸ FAVOR NON-BLOCKING (ASYNC) I/O OVER BLOCKING OPERATION ▸ VERTICAL SCALING (CLUSTER MODE) MIGHT NOT SOLVE YOUR PROBLEMS WITH CPU-INTENSIVE OPERATIONS... ▸ ...BUT WORKER THREADS CAN (JUST REMEMBER - THEY'RE STILL AN EXPERIMENTAL FEATURE!) ▸ NODE.JS EXCELS IN I/O BOUND AND MIGHT NOT BE THE BEST CHOICE FOR CPU-HEAVY OPERATIONS SUMMARY NODE, CAN YOU EVEN IN CPU INTENSIVE OPERATIONS?