— Redis DBからデータ(50アイテム)を取得してローカルホストにスローするシンプルなアプリを作成しました。私はApacheBench(c = 100、n = 50000)を実行し、デュアルコアT2080 @ 1.73GHz(私の6年間のラップトップ)で半ばまともな150リクエスト/秒を取得していますが、procの使用法は非常に残念です表示:
Nodeの設計どおり、コアは1つしか使用されていませんが、Node.jsクラスターを使用できれば、リクエスト/秒をほぼ2倍の約300に、おそらくそれ以上に増やすことができると思います。私はかなりいじりましたが、以下にリストされている私のアプリで使用するために ここに与えられたコード を置く方法を理解することができませんでした:
var
express = require( 'express' ),
app = express.createServer(),
redis = require( 'redis' ).createClient();
app.configure( function() {
app.set( 'view options', { layout: false } );
app.set( 'view engine', 'jade' );
app.set( 'views', __dirname + '/views' );
app.use( express.bodyParser() );
} );
function log( what ) { console.log( what ); }
app.get( '/', function( req, res ) {
redis.lrange( 'items', 0, 50, function( err, items ) {
if( err ) { log( err ); } else {
res.render( 'index', { items: items } );
}
});
});
app.listen( 8080 );
また、アプリはI/Oを集中的に使用することを強調したいと思います(CPUを集中的に使用しないため、クラスターよりも threads-a-gogo の方が適しています)。
これを理解するのにいくつかの助けが欲しいです。
実際、ワークロードは実際にはI/Oバウンドではありません。ヒスイベースの動的ページ生成のコストのため、CPUバウンドです。翡翠テンプレートの複雑さは推測できませんが、単純なテンプレートを使用しても、HTMLページの生成にはコストがかかります。
私のテストでは、次のテンプレートを使用しました。
html(lang="en")
head
title Example
body
h1 Jade - node template engine
#container
ul#users
each user in items
li User:#{user}
Redisのitemsキーに100個のダミー文字列を追加しました。
私のボックスでは、node.js CPUが100%の場合に475 req/sを取得します(これは、このデュアルコアボックスで50%のCPU消費を意味します)。置き換えましょう:
res.render( 'index', { items: items } );
沿って:
res.send( '<html lang="en"><head><title>Example</title></head><body><h1>Jade - node template engine</h1><div id="container"><ul id="users"><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li><li>User:NOTHING</li></ul></div></body></html>' );
現在、ベンチマークの結果は2700 req/sに近づいています。したがって、ボトルネックは明らかにHTMLページのフォーマットによるものです。
この状況でクラスターパッケージを使用することは良い考えであり、それは簡単です。コードは次のように変更できます。
var cluster = require('cluster')
if ( cluster.isMaster ) {
for ( var i=0; i<2; ++i )
cluster.fork();
} else {
var
express = require( 'express' ),
app = express.createServer(),
redis = require( 'redis' ).createClient();
app.configure( function() {
app.set( 'view options', { layout: false } );
app.set( 'view engine', 'jade' );
app.set( 'views', __dirname + '/views' );
app.use( express.bodyParser() );
});
function log( what ) { console.log( what ); }
app.get( '/', function( req, res ) {
redis.lrange( 'items', 0, 50, function( err, items ) {
if( err ) { log( err ); } else {
res.render( 'index', { items: items } );
}
});
});
app.listen( 8080 );
}
現在、ベンチマークの結果は750 req/sに近く、CPU消費量は100%です(最初の475 req/sと比較されます)。