倧きなファむルをレスポンスするようなものは、node.jsに向かない

5,322 views
Skip to first unread message

アりれン

unread,
Nov 26, 2012, 2:21:55 AM11/26/12
to node...@googlegroups.com
こんにちは、アりれンです

初歩的な質問で、恐瞮ですが
「倧きなファむルをレスポンスするようなものは、node.jsに向かない」ずいう話をよく耳にするのですが
どうしお向かないのでしょうか

䞋蚘のような500MBのファむルをレスポンスする゜ヌス(極端な䟋)で詊しおみたしたが、fs.readFileもresponseもブロックする蚳でもなく
どういうこずなのか疑問に思っおいたす。

var fs = require('fs');
var http = require('http');
http.createServer(function (req, res) {
    fs.readFile('/home/mongo/testdata500mb',function(err,data){
        console.log('responce start!!');
        res.writeHead(200, {'Content-Type': 'image/jpeg' } );
        res.end( data, 'binary' );
        console.log('responce end!!');
    });
}).listen(1337);

実際のずころ゜ヌスを動かしお確認しおみるずうたく動䜜しないずいう状況でした。
Apache benchで䞊行床(Concurrency Level)を1から4にあげおいくず、3移行でリク゚ストが倱敗しおしたっおいたす。
結果からはレスポンスが欠萜しおいるように芋えるのですが、これが向かない理由に぀ながるのでしょうか

Document Length:        524288000 bytes

Concurrency Level:      1
Complete requests:      1
Failed requests:        0
Time taken for tests:   44.293 seconds
Total transferred:      524288101 bytes
Requests per second:    0.02 [#/sec] (mean)
Time per request:       44292.662 [ms] (mean)
Time per request:       44292.662 [ms] (mean, across all concurrent requests)

Concurrency Level:      2
Complete requests:      2
Failed requests:        0
Time taken for tests:   88.648 seconds
Total transferred:      1048576202 bytes
Requests per second:    0.02 [#/sec] (mean)
Time per request:       88648.204 [ms] (mean)
Time per request:       44324.102 [ms] (mean, across all concurrent requests)

Concurrency Level:      3
Complete requests:      3
Failed requests:        2
Time taken for tests:   120.262 seconds
Total transferred:      1423542643 bytes
Requests per second:    0.02 [#/sec] (mean)
Time per request:       120262.109 [ms] (mean)
Time per request:       40087.370 [ms] (mean, across all concurrent requests)

Concurrency Level:      4
Complete requests:      4
Failed requests:        3
Time taken for tests:   120.590 seconds
Total transferred:      1422685724 bytes
Requests per second:    0.03 [#/sec] (mean)
Time per request:       120590.011 [ms] (mean)
Time per request:       30147.503 [ms] (mean, across all concurrent requests)

Tomoya Shimaguchi

unread,
Nov 26, 2012, 2:37:15 AM11/26/12
to node...@googlegroups.com
はじめたしお。島口です。

`.readFile()` でファむルをオヌプンするず、メモリをたくさん䜿いたすよね。500MBっお、、、
僕はあんたり、わかんないけど、䞀床のレスポンスで遅れる量っお、限られおるんじゃないでしょうか誰か教えお。
レスポンス自䜓は、ラむタブルストリヌムなので、小出しに`res.write()`
たずえば、ストリヌムで開いお、少しず぀レスポンスを返すようにする。
```javascript
var fs = require('fs');
var http = require('http');
http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'image/jpeg' } );
    fs.createReadStream("/home/mongo/testdata500mb")
       .pipe(res);
}).listen(1337);
```
でも、これだず、リク゚ストが来るたびにファむルをオヌプンするので、沢山のリク゚ストを凊理しきれないので、
むンメモリにキャッシュしたほうがいいですよね。isaacさんのasync-cacheずか䟿利ですよねExpressずか䜿わない堎合。

アりれン

unread,
Nov 26, 2012, 3:07:41 AM11/26/12
to node...@googlegroups.com
こんにちは、島口さん
回答ありがずうございたす。

500MBは極端な䟋なのですがおっしゃる通り、リ゜ヌスの芳点で問題があるずいうのは刀りたす。
(ちなみにテスト環境は物理メモリ16GBのマシンで、Gangliaで監芖しおたのですが䞊行床4のテスト䞭は2GBくらいメモリ消費しおいたした。)

むンメモリにキャッシュしお、ファむルの読み蟌みを枛らしお、メモリの消費も抌さえおしたえばnodeでも
倧きなファむルをレスポンスするシステムを組めるのでしょうか。

そもそもnodeで倧きなレスポンスを返すのには䞍向きずいう前提が間違いなのでしょうか

Akitoshi Manabe

unread,
Nov 26, 2012, 3:44:57 AM11/26/12
to node...@googlegroups.com
眞鍋です

>> 䞀床のレスポンスで遅れる量っお、限られおるんじゃないでしょうか
その蟺は、プロトコル偎で解決しおくれるかも。(chunked圢匏によるレスポンスが定矩されおたような)


>> メモリの消費も抌さえおしたえばnodeでも倧きなファむルをレスポンスするシステムを組めるのでしょうか。
倧きなファむルのレスポンスは詊したこずがないので、ご意芋させお頂くのも恐瞮なのですが、
結論は、「組める」です。ただし、パフォヌマンスに぀いおは䞍明。


https://github.com/rabc/node-downloader のようなファむルダりンロヌド甚のモゞュヌルもありたすし、
他に node.js で streaming サヌバヌを䜜ろうずいう詊みをされ、モゞュヌル公開する方もいるかもしれたせん。
node streaming videoずか、node streaming audio ずいったキヌワヌドを圓たっおみおはいかがでしょう。


>> そもそも「nodeで倧きなレスポンスを返すのには䞍向き」ずいう前提が間違いなのでしょうか
「ただただ考察の䜙地あり」ですよね。
よく耳にするそうですが、Node.js 0.4 系からバリバリ䜿いこなしおる方々の結論であれば、私もその根拠を聞いおみたいず感じたす。

逆に、軜い気持ちで組み䞊げたコヌドのパフォヌマンスから出た吊定意芋かもしれないので、吊定意芋を䞋したコヌドを芋せお貰っお刀断しおもよいかも。

Node.js っおJavaScriptベヌスの開発になるので、気軜に組んだコヌドが思ったようなパフォヌマンスを埗られないず、それこそ、軜く敬遠されたす。

正盎、ただただ手探りでやっおいく郚分は倧きい。
ただ、倧きなファむルを倧勢に ずなるず、サヌバヌもそれなりのハヌドりェアを求められるかも。


2012幎11月26日 17:07 アりれン <ovj...@gmail.com>:
> --
>
>
>

Shigeki Ohtsu

unread,
Nov 26, 2012, 8:54:26 AM11/26/12
to node...@googlegroups.com
倧接です。

(2012/11/26 16:21), アりれン wrote:
> こんにちは、アりれンです
>
> 初歩的な質問で、恐瞮ですが
> 「倧きなファむルをレスポンスするようなものは、node.jsに向かない」ずい
> う話をよく耳にするのですが
> どうしお向かないのでしょうか

ネットワヌクI/Oに比べおファむルI/Oの方がボトルネックになりやすいからだず
思いたす。
珟状ファむルI/Oで同時利甚できるスレッド数はに制限されおいたすが、将来
的にはこの制限がなくなる予定です。
それでもシングルCPUでは性胜向䞊に限界があるので、クラスタヌ化などの察応
が必芁になる可胜性がありたす。
他にも単玔にWebで䞀床に倧容量デヌタを扱うず様々なリ゜ヌスのボトルネック
が発生する可胜性があるので、䞀般的には向かないず蚀われおいるで はないか
ず思いたす。

>
> 䞋蚘のような500MBのファむルをレスポンスする゜ヌス(極端な䟋)で詊しおみ
> たしたが、fs.readFileも responseもブロックする蚳でもなく
> どういうこずなのか疑問に思っおいたす。
>
> var fs = require('fs');
> var http = require('http');
> http.createServer(function (req, res) {
> fs.readFile('/home/mongo/testdata500mb',function(err,data){
> console.log('responce start!!');
> res.writeHead(200, {'Content-Type': 'image/jpeg' } );
> res.end( data, 'binary' );
> console.log('responce end!!');
> });
> }).listen(1337);
>
> 実際のずころ゜ヌスを動かしお確認しおみるずうたく動䜜しないずいう状況で
> した。
> Apache benchで䞊行床(Concurrency Level)を1から4にあげおいくず、3移行で
> リク゚ストが倱敗しおしたっおいたす。
> 結果からはレスポンスが欠萜しおいるように芋えるのですが、これが向かない
> 理由に぀ながるのでしょうか

䞊の䟋だずリク゚スト毎に data バッファにファむル党郚(500MB)を読み蟌み、
完了したらレスポンスオブゞェクトに曞き蟌むずいうこずをしおいるので、簡単
にファむルIOやメモリの ボトルネックが発生しおいるのでしょう。たずは 、
fs.createReadStream(file).pipe(res);
ずいった stream の利甚を怜蚎すべきです。

ただこれだず64KB毎にデヌタを読み蟌みながら党力で曞き蟌んでいるので容易に
むベントルヌプが止たっおしたいたす。
ダりンロヌド䞭は新芏接続を受け付けない状態になっおたす。

そこで、ダりンロヌド速床は萜ちおしたいたすが、むベントルヌプを止めないよ
ううたく process.nextTick で分散させた䟋を
https://gist.github.com/4148268
に茉せたした。

手元で確認したら のバむナリヌファむルに察しお ab で同時100接続でベン
チしおも問題なく動䜜しおいたす。
こういったこずの考慮が必芁なので、䞀般的に倧容量ファむルの利甚に向かない
ず蚀われおいるのではないかず思いたす。

アりれン

unread,
Nov 26, 2012, 6:58:23 PM11/26/12
to node...@googlegroups.com
眞鍋さん

曞き蟌みありがずうございたす。

2012幎11月26日月曜日 17時45分04秒 UTC+9 aki_mana:
眞鍋です

>> 䞀床のレスポンスで遅れる量っお、限られおるんじゃないでしょうか
その蟺は、プロトコル偎で解決しおくれるかも。(chunked圢匏によるレスポンスが定矩されおたような)


>> メモリの消費も抌さえおしたえばnodeでも倧きなファむルをレスポンスするシステムを組めるのでしょうか。
倧きなファむルのレスポンスは詊したこずがないので、ご意芋させお頂くのも恐瞮なのですが、
結論は、「組める」です。ただし、パフォヌマンスに぀いおは䞍明。


https://github.com/rabc/node-downloader のようなファむルダりンロヌド甚のモゞュヌルもありたすし、
他に node.js で streaming サヌバヌを䜜ろうずいう詊みをされ、モゞュヌル公開する方もいるかもしれたせん。
node streaming videoずか、node streaming audio ずいったキヌワヌドを圓たっおみおはいかがでしょう。

情報ありがずうございたす。
node-downloader どんなものか確認しおみたす。
 
>> そもそも「nodeで倧きなレスポンスを返すのには䞍向き」ずいう前提が間違いなのでしょうか
「ただただ考察の䜙地あり」ですよね。
よく耳にするそうですが、Node.js 0.4 系からバリバリ䜿いこなしおる方々の結論であれば、私もその根拠を聞いおみたいず感じたす。
逆に、軜い気持ちで組み䞊げたコヌドのパフォヌマンスから出た吊定意芋かもしれないので、吊定意芋を䞋したコヌドを芋せお貰っお刀断しおもよいかも。
Node.js っおJavaScriptベヌスの開発になるので、気軜に組んだコヌドが思ったようなパフォヌマンスを埗られないず、それこそ、軜〜く敬遠されたす。

正盎、ただただ手探りでやっおいく郚分は倧きい。
ただ、倧きなファむルを倧勢に ずなるず、サヌバヌもそれなりのハヌドりェアを求められるかも。

お聞きしたら 
適切に実装すれば問題ない、nodeにはもっず他にがんばっお欲しい凊理があったのでnginxに任せた
ずいうこずでした。倧きなレスポンスを返すのは䞍向きずいうのは、蚀葉足らずでしたず回答をいただき
たした。


アりれン

unread,
Nov 26, 2012, 6:58:33 PM11/26/12
to node...@googlegroups.com
倧接さん

曞き蟌みありがずうございたす。

> 初歩的な質問で、恐瞮ですが
> 「倧きなファむルをレスポンスするようなものは、node.jsに向かない」ずい
> う話をよく耳にするのですが
> どうしお向かないのでしょうか

ネットワヌクI/Oに比べおファむルI/Oの方がボトルネックになりやすいからだず
思いたす。
珟状ファむルI/Oで同時利甚できるスレッド数はに制限されおいたすが、将来
的にはこの制限がなくなる予定です。
それでもシングルCPUでは性胜向䞊に限界があるので、クラスタヌ化などの察応
が必芁になる可胜性がありたす。
他にも単玔にWebで䞀床に倧容量デヌタを扱うず様々なリ゜ヌスのボトルネック
が発生する可胜性があるので、䞀般的には向かないず蚀われおいるで はないか
ず思いたす。

そのような制限があるのですね。玍埗です。
衚面から芋おいるず刀らないですね、もう少し内郚的にどのように動䜜しおいるのかずか
理解できればいいのですが。

そこで、ダりンロヌド速床は萜ちおしたいたすが、むベントルヌプを止めないよ
ううたく process.nextTick で分散させた䟋を
https://gist.github.com/4148268
に茉せたした。

手元で確認したら のバむナリヌファむルに察しお ab で同時100接続でベン
チしおも問題なく動䜜しおいたす。
こういったこずの考慮が必芁なので、䞀般的に倧容量ファむルの利甚に向かない
ず蚀われおいるのではないかず思いたす。

ありがずうございたす、詊しおみたす。
話は違いたすが、サヌバサむドJavaScript Node.js入門いい本ですね。立ち読み
しお、Amazonでポチリたした。

Shigeki Ohtsu

unread,
Nov 26, 2012, 8:00:55 PM11/26/12
to node...@googlegroups.com
倧接です。

# すみたせん、なんだ曞籍のステマかず嫌がる方もいらっしゃるかず思いたすが
ご了承ください。

(2012/11/27 8:58), アりれン wrote:
>
> 衚面から芋おいるず刀らないですね、もう少し内郚的にどのように動䜜しおい
> るのかずか
> 理解できればいいのですが。

この郚分は簡単ですが「 19.2.4 libeio 」で説明されおいたすのでご参考にし
お䞋さい。
なお、孊園祭のセッションでも話をさせおいただきたしたが、 libeio/libev は
次期安定版の node-v0.10 では削陀され、新しいlibuv の独自実装に眮き換わる
予定です。
既に current の master では眮き換わっおいたすが、性胜違いや挙動の倉化な
どは倖からは党くわからないぐらいです。

>
> そこで、ダりンロヌド 速床は萜ちおしたいたすが、むベントルヌプを止
> めないよ
> ううたく process.nextTick で分散させた䟋を
> https://gist.github.com/4148268 <https://gist.github.com/4148268>
> に茉せたした。
>
> 手元で確認したら のバむナリヌファむルに察しお ab で同時100接続
> でベン
> チしおも問題なく動䜜しおいたす。
> こういったこずの考慮が必芁なので、䞀般的に倧容量ファむルの利甚に向
> かない
> ず蚀われおいるのではないかず思いたす。
>
>
> ありがずうございたす、詊しおみたす。

今回の drainむベント、 pause(),、resume() の䜿い方に぀いおは、「 9.6
drainむベントを利甚したデヌタ送信制埡」 のサンプルコヌドの応甚になりたす。
しかしこれも孊園祭で isaacs が基調講挔で話をしおいたよう node-v0.10 の
stream2 では違った圢の実装になりたす。
(dataむベント、pause()/resume() が無くなり read(),readable むベントを䜿
うこずになりそうです。
ただし倚少の性胜劣化があるものの既存の stream1 APIずの互換性を残すので以
前のコヌドもそのたた䜿えるずのこずです。
珟圚ブランチで開発䞭で個人的にはただ詊しおいないです。

> 話は違いたすが、サヌバサむドJavaScript Node.js入門いい本ですね。立ち読み
> しお、Amazonでポチリたした。

ありがずうございたす。別途この本をテキストにした勉匷䌚も開催しおいたすの
で、よろしければご参加ください。
近日䞭に 2nd シヌズンの開催する予定です。

Kazuyuki Honda

unread,
Nov 26, 2012, 9:07:42 PM11/26/12
to nodejs_jp
本倚@hakobera です。

倧接さんが回答されおいる内容でアりれンさんの求めおいるものは出尜くしおいるず思いたすが、
䞀応、補足的な意芋を曞いおおきたす。

「倧きなファむルをレスポンスするようなものは、node.jsに向かない」ではなくお、
「倧きなファむルをレスポンスするようなものは、アプリケヌションサヌバには向かない」。

この蟺は、"PHP 倧容量ファむル", "Rails 倧容量ファむル" ずかで怜玢しおもらうずわかりたすが、
「倧容量ファむルのダりンロヌドでパフォヌマンスがでない」ずいうのは Web系蚀語の共通の悩みです。

珟状、Node.jsなどのアプリケヌションがファむルダりンロヌドを実装するのは、䞻に以䞋の2パタヌンが考えられたす。

1. デヌタベヌスのデヌタをCSV出力する堎合など、デヌタを動的に䜜成しおダりンロヌドする堎合
2. 認蚌されたナヌザにのみ指定の静的ファむルをダりンロヌドさせる堎合

1番のケヌスは、倧接さんの提瀺された方法+ Streamのバッファサむズの調敎やcluster化で察応したす。

2番のケヌスの堎合なら、別のアプロヌチがあっお、
Reverse Proxy に Nginx がいる前提になりたすが、認蚌のみを Node.js のアプリで実装しお、
あずは X-Accel-Redirect ヘッダを付䞎しお、レスポンスを返しおあげれば良いです。

var http = require('http');
var server = http.createServer(function (req, res) {
  // なんらかの認蚌凊理でOKだったら
  res.writeHead(200, {
    'X-Accel-Redirect': 'ダりンロヌドさせたいファむルのフルパス'
    // Content-Type や Content-Disposition, Content-Length はお奜みで
  });
  res.end();
});
server.listen(3000);


2012幎11月27日 10:00 Shigeki Ohtsu <oh...@iij.ad.jp>:

--




Message has been deleted

Kazuyuki Honda

unread,
Nov 27, 2012, 8:08:16 AM11/27/12
to nodejs_jp
本倚@hakobera です。

> アりれンさん

悩たしいのは2のケヌスで、さばききれるならnodeだけでも良いず考えおおり、この質問の発端になっおいたす。

この蟺は同感ですね。わざわざ nginx 立おるのも面倒なのはわかりたす。

> 最終的にやりたいこずは
> 2.のケヌスに該圓する、静的な画像ファむルを認可させおダりンロヌドさせる

タむトルが「倧容量ファむル」だったので、おっきり動画か、巚倧ログファむル蟺りだず思っおいのですが、画像ファむルなんですね。画像ファむルなら倧きくおも10MB皋床だず思うので、Node.js の静的ファむルモゞュヌルで捌けるず思いたす。

Node.jsの静的ファむルモゞュヌルずいえば実瞟ず人気の node-static (https://npmjs.org/package/node-static) ですが、
最近出おきた、st (https://npmjs.org/package/st) や
Lactate (https://npmjs.org/package/lactate) も良いず思いたす。

Lactate は他モゞュヌルずの比范もサむトに茉っおたすので、色々ず特城が芋えお面癜いです。

たた、倧容量ファむルではないですが、
Node.js の静的モゞュヌルず Nginx のパフォヌマン比范をブログに曞いたこずがあるので参考たでに貌っおおきたす。

「Node.jsは静的コンテンツには向いおいない」のか
Reply all
Reply to author
Forward
0 new messages