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
350
Watching Ruby in browsers
ledsun
0
77
Using Ruby in the browser is wonderful
ledsun
1
2.9k
Rubyで書いたテトリスをブラウザで動かしてみた
ledsun
0
2.3k
ruby.wasm に関する進捗報告
ledsun
0
1.1k
Hacking Guide of the ruby.wasm
ledsun
0
1.5k
私の作ったruby.wasm アプリケーション
ledsun
0
630
Load gem from browser
ledsun
2
1.7k
パラメタライズドテスト
ledsun
0
550
Other Decks in Technology
See All in Technology
私なりのAIのご紹介 [2024年版]
qt_luigi
1
120
Opcodeを読んでいたら何故かphp-srcを読んでいた話
murashotaro
0
280
ガバメントクラウドのセキュリティ対策事例について
fujisawaryohei
0
560
マイクロサービスにおける容易なトランザクション管理に向けて
scalar
0
140
終了の危機にあった15年続くWebサービスを全力で存続させる - phpcon2024
yositosi
19
19k
Storage Browser for Amazon S3
miu_crescent
1
240
.NET 9 のパフォーマンス改善
nenonaninu
0
1.1k
オプトインカメラ:UWB測位を応用したオプトイン型のカメラ計測
matthewlujp
0
180
大幅アップデートされたRagas v0.2をキャッチアップ
os1ma
2
540
WACATE2024冬セッション資料(ユーザビリティ)
scarletplover
0
210
alecthomas/kong はいいぞ / kamakura.go#7
fujiwara3
1
300
kargoの魅力について伝える
magisystem0408
0
210
Featured
See All Featured
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
111
49k
Why Our Code Smells
bkeepers
PRO
335
57k
How GitHub (no longer) Works
holman
311
140k
Fontdeck: Realign not Redesign
paulrobertlloyd
82
5.3k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
132
33k
Build The Right Thing And Hit Your Dates
maggiecrowley
33
2.4k
A Modern Web Designer's Workflow
chriscoyier
693
190k
Fireside Chat
paigeccino
34
3.1k
Thoughts on Productivity
jonyablonski
67
4.4k
Bootstrapping a Software Product
garrettdimon
PRO
305
110k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
280
13k
Faster Mobile Websites
deanohume
305
30k
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Λָ͠Έʹ͠·͠ΐʔ