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.1k
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
Using Ruby in the browser is wonderful
ledsun
1
2.3k
Rubyで書いたテトリスをブラウザで動かしてみた
ledsun
0
2k
ruby.wasm に関する進捗報告
ledsun
0
950
Hacking Guide of the ruby.wasm
ledsun
0
1.3k
私の作ったruby.wasm アプリケーション
ledsun
0
570
Load gem from browser
ledsun
2
1.5k
パラメタライズドテスト
ledsun
0
490
ゆっくり動くと速く動ける / If you move slowly, you can move more fast
ledsun
0
950
WebSockets and Ruby : avoiding the pitfalls of multithreading
ledsun
0
950
Other Decks in Technology
See All in Technology
ソフトウェア設計と生成AI
masuda220
PRO
8
1.2k
iOS研修【MIXI 24新卒技術研修】
mixi_engineers
PRO
0
160
Bedrockの宇宙最速アウトプットしまくってたら書籍出版できた話
minorun365
PRO
2
230
Post-hoc EMA - EMAの減衰パラメータの事後最適化
yu4u
1
190
ACRiルーム最新情報とAMD GPUサーバーのご紹介
anjn
0
180
複雑なUI実装の壁を越えるための考え方事例紹介 (iOS/Android間で実装を合わせるヒント)
fumiyasac0921
1
110
Azure Backup はどこまでランサムウェアに対抗できるの?
murachiakira
0
120
データ可視化をやりたくて北海道におひっこし / TechRAMEN 2024 Conference
sorami
0
260
間違いが許されないケースでLLMを使うためには @GenAI Playground Meetup #01
nrryuya
10
3.8k
.NET Aspire を始めよう
okazuki
0
180
現場のエンジニアから見た採用担当との協働
corocn
5
2.1k
シフトレフトで挑む セキュリティの生産性向上
sekido
PRO
0
330
Featured
See All Featured
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
17
450
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
23
1.9k
Making the Leap to Tech Lead
cromwellryan
128
8.7k
Scaling GitHub
holman
458
140k
BBQ
matthewcrist
82
9k
Pencils Down: Stop Designing & Start Developing
hursman
118
11k
KATA
mclloyd
23
13k
[RailsConf 2023] Rails as a piece of cake
palkan
39
4.4k
Embracing the Ebb and Flow
colly
82
4.3k
A Philosophy of Restraint
colly
201
16k
StorybookのUI Testing Handbookを読んだ
zakiyama
19
4.9k
Speed Design
sergeychernyshev
12
300
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Λָ͠Έʹ͠·͠ΐʔ