Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
10倍速いNode.js並列プログラミング
Search
shigeru. nakajima
June 29, 2018
Technology
12
4.3k
10倍速いNode.js並列プログラミング
Node.jsのプログラミングを並列化して10倍速く動かした話です。
Node学園 31時限目 のLT
https://nodejs.connpass.com/event/90936/
shigeru. nakajima
June 29, 2018
Tweet
Share
More Decks by shigeru. nakajima
See All by shigeru. nakajima
Introduce dRuby
ledsun
0
390
Watching Ruby in browsers
ledsun
0
110
Using Ruby in the browser is wonderful
ledsun
1
3.2k
Rubyで書いたテトリスをブラウザで動かしてみた
ledsun
0
2.4k
ruby.wasm に関する進捗報告
ledsun
0
1.1k
Hacking Guide of the ruby.wasm
ledsun
0
1.6k
私の作ったruby.wasm アプリケーション
ledsun
0
670
Load gem from browser
ledsun
2
1.8k
パラメタライズドテスト
ledsun
0
590
Other Decks in Technology
See All in Technology
ウォンテッドリーのデータパイプラインを支える ETL のための analytics, rds-exporter / analytics, rds-exporter for ETL to support Wantedly's data pipeline
unblee
0
140
JavaにおけるNull非許容性
skrb
2
2.7k
Apache Iceberg Case Study in LY Corporation
lycorptech_jp
PRO
0
360
Global Databaseで実現するマルチリージョン自動切替とBlue/Greenデプロイ
j2yano
0
160
いまからでも遅くない!コンテナでWebアプリを動かしてみよう!コンテナハンズオン編
nomu
0
170
事業モメンタムを生み出すプロダクト開発
macchiitaka
0
100
Oracle Database Technology Night #87-1 : Exadata Database Service on Exascale Infrastructure(ExaDB-XS)サービス詳細
oracle4engineer
PRO
1
210
事業を差別化する技術を生み出す技術
pyama86
2
490
JAWS DAYS 2025 アーキテクチャ道場 事前説明会 / JAWS DAYS 2025 briefing document
naospon
0
2.8k
遷移の高速化 ヤフートップの試行錯誤
narirou
6
1.9k
E2Eテスト自動化入門
devops_vtj
1
110
20250304_赤煉瓦倉庫_DeepSeek_Deep_Dive
hiouchiy
2
120
Featured
See All Featured
Unsuck your backbone
ammeep
669
57k
Adopting Sorbet at Scale
ufuk
75
9.2k
What’s in a name? Adding method to the madness
productmarketing
PRO
22
3.3k
A Philosophy of Restraint
colly
203
16k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
49
2.3k
Build The Right Thing And Hit Your Dates
maggiecrowley
34
2.5k
Rails Girls Zürich Keynote
gr2m
94
13k
GraphQLとの向き合い方2022年版
quramy
44
14k
Code Reviewing Like a Champion
maltzj
521
39k
KATA
mclloyd
29
14k
Building Flexible Design Systems
yeseniaperezcruz
328
38k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
13
1k
Transcript
10ഒ͍Node.jsฒྻϓϩάϥϛϯά Shigeru Nakajima a.k.a. @ledsun Luxiar co., ltd NodeֶԂ LT
2018/06/29
Node εΫϨΠϐϯά͓͡͞Μ ʮnode εΫϨΠϐϯάʯͰάάͬͯ
PANQ panq http://www.panq.jp/ ͱ͍͏αʔϏεΛ࡞ͬ ͍ͯΔ QiitaͷهࣄΛࢀরͰධՁ Qiita APIͰࢀরऔΕͳ͍ εΫϨΠϐϯάͰऔಘ 8000هࣄΛूΊͨ
NodeͱεΫϨΠϐϯά εΫϨΠϐϯά = HTMLμϯϩʔυɹ + ɹHTMLύʔε = Network IOɹɹɹɹɹ+ɹ CPU
work
εΫϨΠϐϯάඇಉظϓϩ άϥϛϯάϞσϧͱΑ͘߹͏ request('http://example.com/', (e, res, body) => { const doc
= libxmljs.parseHtmlString(body) const data = doc.get('(//dl[@class="newsList"])[1]/dt[1]/text()') }) ;ͭ͏ʹॻ͘ͱޮతʹಈ͘
࠶ύʔε • ධՁ߲Λมߋ͍ͨ͠ • 8000htmlϑΝΠϧΛ࠶ύʔε
20min
ͬͱ͍ͨ͘͠
C++ Addon: libxmljs • ύʔεॲཧΛ͘͢Δ • parse5Λlibxmljsʹม͑Δ • 1200s(20min) =>
160s • 7.5ഒ͘ͳͬͨ • parse5: pure js • libxmljs: libxml2 (c) ͷϥούʔ
ͬͱ͍ͨ͘͠
ॲཧ༰ͷੳ • SSDڥͰFileಡΈࠐΈշ • IOͪຆͲແ͍ • CPUॲཧ͕େΛΊΔ • ୯ମͷCPUॲཧΛ͘͢Δͷ͍͠
ฒྻϓϩάϥϛϯά ݱͷύιίϯෳίΞ͕ࡌ͍ͬͯΔ ෳͷίΞͰCPUॲཧΛฒྻʹΒͤΔ => ฒྻϓϩάϥϛϯά
ຊͷ͓ Node.jsϓϩάϥϜΛฒྻԽͯ͠ੑೳΛ্͛Δ
ฒྻԽ • 1ͷϚγϯͷෳͷίΞΛͬͯɺಉ࣌ʹෳ ͷܭࢉΛ࣮ߦ • ෳϚγϯͷѻΘͳ͍
ϓϩηε • ฒྻϓϩάϥϛϯάͱ͍͑εϨου • Node.jsʹεϨουͳ͍ • ϓϩηεΛ͏
child_process.fork() ϫʔΧʔϓϩηεΛཱͯΔ const processes = [] for (var i =
0; i < number; i++) { processes.push(fork(program, [], { stdio: ['ignore', 'ignore', process.stderr, 'ipc'] })) }
֤ϓϩηεʹৼΓ͚Δ // ϑΥϧμͷϑΝΠϧҰཡΛऔಘ const dir = `${process.cwd()}/data/public/cache` const stream =
readdirp({ root: dir, fileFilter: '*.html' }) // ࢠϓϩηεͰύʔε let count = 0 stream.on('data', (data) => { // ϥϯυϩϏϯͰϑΝΠϧΛ count++; processes[count % processes.length].send(data) })
݁Ռɿ80sʂ͖Ε͍ʹ2ഒ
ͬͱ͍ͨ͘͠
Node.jsʹεϨουͳ͍ͱ ݴͬͨͳɺ͋Εӕͩ https://github.com/xk/node-threads-a-gogo • C++ AddonͰωΠςΟϒεϨουΛىಈ
ɿNode 6.x Ͱಈ͘ • Node 6.xͰ͔͠ಈ͔ͳ͍ • Node 6.x ͩͱͦΕ͚ͩͰ30%͙Β͍͍
• node-threads-a-gogo ͷ Node 10ରԠ • 4࣌ؒؤுͬͯఘΊͨ
Node.jsʹεϨουͳ͍ͱ ݴͬͨͳɺ͋Εӕͩʢ̎ʣ https://nodejs.org/api/worker_threads.html • v10.5.0@6/20 Ҏ߱ • ΤΫεϖϦϝϯλϧ • --experimental-worker
• ϑϥάΛ͚ͭΔͱಡΈࠐ·ΕΔϞδϡʔϧ
worker_threads.Worker child_process.fork()ͱେମҰॹ const workers = [] for (var i =
0; i < number; i++) { workers.push(new Worker(program)) }
threadʹৼΓ͚ // ϑΥϧμͷϑΝΠϧҰཡΛऔಘ const dir = `${process.cwd()}/data/public/cache` const stream =
readdirp({ root: dir, fileFilter: '*.html' }) // ϫʔΧʔͰύʔε let count = 0 stream.on('data', (data) => { // ϥϯυϩϏϯͰϑΝΠϧΛ count++; workers[count % workers.length].postMessage(data) })
ɿC++ Addonಈ͔ͳ ͍ • libxmljs͕͑ͳ͍ • 7.5ഒ͕ɺ͘ͳΔ • https://github.com/nodejs/node/issues/ 21481
ͬͱ͍ͨ͘͠
ίΞΛ૿ͤฒྻ • 2ίΞͰ2ഒ͕ݶքͳΒɺͨ͘͞ΜίΞͷ͋ ΔϚγϯΛ͍͍͑ • AWS EC2 c4.8xlarge • 36ίΞ
=> 80s͕2.2sʹ!? • 2.016USD/࣌ؒ
None
c4.8xlarge • ͦͦCPU͕͍͢͝ • 1ฒྻͰ90sʢx1.8ʣ • 12ฒྻͰ8s • ݶքʢ36ίΞΛ͍Εͳ͍ʣ
ϘτϧωοΫෆ໌ • ಡΈࠐΈIO͕ϘτϧωοΫʁ • SSDϚγϯʢi3.4xlargeʣΛ͕ͬͯ มΘΒͳ͍ • ϓϩηεͷݶքʁ • εϨουΛࢼ͔ͨͬͨ͠
ຊͷ·ͱΊ • libxmljsΛͬͯ 7.5ഒ • 2$/hͷϚγϯͰ 1.8ഒ • ฒྻϓϩάϥϛϯάͰ 11.3
ഒ • worker threadsͷҠߦ͕؆୯ ฒྻϓϩάϥϛϯά͓͍͍͠
ฒྻϓϩάϥϛϯά͠Α͏ worker threadsΛָ͠Έʹ͠·͠ΐʔ