こんにちは、みんな、
プログラムでnode_redisでパイプラインを有効にする方法は?
ほとんどの場合、自動的に発生するとドキュメントに記載されているのを見ました。node_redisのアプリケーションコードからプログラムで強制する方法があることを理解したいと思います。
[ ec2-user @ devops〜 ] $ redis-benchmark -n 100000 -t set、get -P 16 -q -h 10.0.1.10
セット:1秒あたり199600.80リクエスト
GET:193050.19リクエスト/秒
[ ec2-user @ devops〜 ] $ redis-benchmark -n 100000 -t set、get -q -h 10.0.1.12
セット:1秒あたり14098.41リクエスト
GET:1秒あたり13743.82リクエスト
Redisノードでは10倍以上の違いがあります。
ありがとう、
ドミトリー
client.multiおよびmulti.execコマンドを介して実行されますか?
こんにちは@ saritasa-パイプラインは自動です。 それは常にクライアントの内部で起こっています。 有効にするためにmultiまたはexecを使用する必要はありません。
こんにちはブライス、
ありがとう、
ドミトリー
ブライスに感謝します。http://redis.io/topics/pipeliningがどのように機能するかを理解しています。 node.jsアプリケーションで-リクエストがパイプライン化されるようにコードをどのように構成する必要がありますか?
したがって、以下の例では
hgetall&expire-パイプライン化されているかどうか? 呼び出しの1つはコールバック内にあります。
関数getByID(テーブル、ID、次){
if(!success)return setTimeout(function(){
getByID(table、id、next);
}、2000);
var end = utils.getEndTime(),
base = getBase(),
client = getClient(PK2str(table, id)),
key = getHashID(table, id);
base.sismember(table, key, function (err, val) {
if (err || !val) return next();
client.hgetall(key, function (err, val) {
if (err || !val) return next(new Error('Expired'), id);
val = arrays_parse(table, val);
next(null, val);
client.expire(key, cfg.ttl.shards);
if (!exports.silent) {
profiler.log('cache', {
'table': table,
'id': key,
'method': 'getByID',
'data': val,
'time': end()
});
}
});
});
}
すべてのコマンドは「パイプライン化」されて送信されますが、1つまたは2つの理由により、これらが同じパイプライン書き込みフレームで送信されることはありません。
base
とclient
が異なるRedisクライアントである場合、それらは同じパイプラインを_決して_共有できません。パイプライン化のメリットを確認するには、コマンドを同じコンテキスト*から実行する必要があります。 たとえば、redisパイプラインドキュメントのPINGの例と同様です。
// These commands will all be pipelined together:
client.ping()
client.ping()
client.ping()
client.ping(function () {
// This would *NEVER* be in the same pipeline frame as the other four because it requires a reply to be received first
client.ping()
})
*または、Redisが応答するよりも速く送信された場合は別のコンテキストから送信されますが、依存するコンテキストには応答しません
今それを手に入れました-ありがとう! これは非常に貴重なコメントです!
node_redisの「自動パイプライン」は公式のredisで参照されているパイプラインではないと思います。
この時間はRTT(ラウンドトリップ時間)と呼ばれます。 クライアントが連続して多くのリクエストを実行する必要がある場合(たとえば、同じリストに多くの要素を追加したり、データベースに多くのキーを入力したりする場合)、これがパフォーマンスにどのように影響するかを簡単に確認できます。 たとえば、RTT時間が250ミリ秒の場合(インターネット経由のリンクが非常に遅い場合)、サーバーが1秒あたり100kの要求を処理できる場合でも、1秒あたり最大4つの要求を処理できます。
使用されるインターフェースがループバックインターフェースである場合、RTTははるかに短くなります(たとえば、私のホストは127.0.0.1にpingを実行する0.044ミリ秒を報告します)が、連続して多数の書き込みを実行する必要がある場合は、それでも多くなります。
公式redisによるパイプライン化とは、複数のコマンドを組み合わせて1回送信し、node_redisでは対処されないRTTによる遅延に対抗することを意味します。 また、node_redisの「自動パイプライン」は、実際には、Nodeの非同期プログラミングモデルを使用して、できるだけ多くのコマンドを同時に送信しています。
これはこの問題を議論する良い記事です。 http://informatikr.com/2012/redis-pipelining.html
@Vizwind @saritasa .multiと.batchはどちらも、バージョン2.2以降で考えられているようにパイプラインを使用します。
最も参考になるコメント
すべてのコマンドは「パイプライン化」されて送信されますが、1つまたは2つの理由により、これらが同じパイプライン書き込みフレームで送信されることはありません。
base
とclient
が異なるRedisクライアントである場合、それらは同じパイプラインを_決して_共有できません。パイプライン化のメリットを確認するには、コマンドを同じコンテキスト*から実行する必要があります。 たとえば、redisパイプラインドキュメントのPINGの例と同様です。
*または、Redisが応答するよりも速く送信された場合は別のコンテキストから送信されますが、依存するコンテキストには応答しません