こんにちは皆さん、私は非常に実用的なredisユースケースの質問があります。 Redisで平均要求時間を以下のjsコードで保存したいとします。基本的に私はnode.js + redisを使用して平均リクエスト時間を保存する
var rc=require('redis').createClient()
,rc2=require('redis').createClient()
,test_data=[
['path/1', 100]
,['path/2', 200]
,['path/1', 50]
,['path/1', 70]
,['path/3', 400]
,['path/2', 150]
];
rc.del('reqtime');
rc.del('reqcnt');
rc.del('avgreqtime');
for(var i=0, l=test_data.length; i<l; i++) {
var item=test_data[i], req_path=item[0], req_time=item[1];
console.log('debug: iteration # %d, item=%j', i, item);
rc.zincrby('reqtime', req_time, req_path);
rc.zincrby('reqcnt', 1, req_path, function(err, c) {
rc2.zscore('reqtime', req_path, function(err, t) {
var avg=t/c;
console.log('req_path='+req_path+',t='+t+',c='+c);
console.log('debug: added member %s to sorted set "avgreqtime" with score %f', req_path, avg);
rc2.zadd('avgreqtime', avg, req_path);
});
});
}
rc.quit();
rc2.quit();
平均要求時間を計算し、各要求項目([req_path、req_time])時Redisのために保存しようとしています。しかしavgreqtimeキーの期待どおりに動作していないです。私が得たstdoutから
debug: iteration # 0, item=["path/1",100]
debug: iteration # 1, item=["path/2",200]
debug: iteration # 2, item=["path/1",50]
debug: iteration # 3, item=["path/1",70]
debug: iteration # 4, item=["path/3",400]
debug: iteration # 5, item=["path/2",150]
req_path=path/2,t=undefined,c=1
debug: added member path/2 to sorted set "avgreqtime" with score %f NaN
req_path=path/2,t=undefined,c=1
debug: added member path/2 to sorted set "avgreqtime" with score %f NaN
req_path=path/2,t=undefined,c=2
debug: added member path/2 to sorted set "avgreqtime" with score %f NaN
req_path=path/2,t=undefined,c=3
debug: added member path/2 to sorted set "avgreqtime" with score %f NaN
req_path=path/2,t=undefined,c=1
debug: added member path/2 to sorted set "avgreqtime" with score %f NaN
req_path=path/2,t=undefined,c=2
debug: added member path/2 to sorted set "avgreqtime" with score %f NaN
Redis関数内のデバッグ行は、各繰り返しではなく、最後に一度に出力されます。私はこれがnode.jsの非同期性と関係していると思いますが、この作業をどのように手に入れるかという手がかりはありません。実験として、私も成功せず、次のとforループを交換してみました:
for(var i=0, l=test_data.length; i<l; i++) {
var item=test_data[i], req_path=item[0], req_time=item[1];
console.log('debug: iteration # %d, item=%j', i, item);
rc.multi()
.zincrby('reqtime', req_time, req_path)
.zincrby('reqcnt', 1, req_path)
.exec(function(err, replies) {
console.log('debug(%s): got %j', req_path, replies);
var avg=replies[0]/replies[1];
rc2.zadd('avgreqtime', avg, req_path);
});
}
私は、各反復で、この時間を合計要求時間を得たが、問題は、最後のreq_pathある「パス/ 2」とreq_path棒でありますtest_dataでその結果のみ「パス/ 2」avgreqtimeする保存されます、それは間違っている:私はRedisの2.4.5使用しています
debug: iteration # 0, item=["path/1",100]
debug: iteration # 1, item=["path/2",200]
debug: iteration # 2, item=["path/1",50]
debug: iteration # 3, item=["path/1",70]
debug: iteration # 4, item=["path/3",400]
debug: iteration # 5, item=["path/2",150]
debug(path/2): got ["100","1"]
debug(path/2): got ["200","1"]
debug(path/2): got ["150","2"]
debug(path/2): got ["220","3"]
debug(path/2): got ["400","1"]
debug(path/2): got ["350","2"]
を、ノードRedisのクライアントはあなたの推測で正しいhttps://github.com/mranney/node_redis
作品で原料のこの種を管理することができます。この興味深いモジュールを指摘してくれてありがとう。 – ricochen
このモジュールに慣れてきて、私はちょうどその例を書きました(私のワードプレスの投稿の1つ)[http://ricochen.wordpress.com/2011/10/15/node-js-example-2-parallel-私は数ヶ月前に書いた[処理する]。非同期モジュールを使用するコードはずっと簡単です。 – ricochen