Node-redis: パイプライン

作成日 2014年01月13日  ·  9コメント  ·  ソース: NodeRedis/node-redis

こんにちは、みんな、

プログラムで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倍以上の違いがあります。

ありがとう、
ドミトリー

Feature Request fixed / done

最も参考になるコメント

すべてのコマンドは「パイプライン化」されて送信されますが、1つまたは2つの理由により、これらが同じパイプライン書き込みフレームで送信されることはありません。

  1. sismemberのコールバックは、hgetall呼び出しを呼び出すものです。したがって、特定のsismember呼び出しに対して、これらのコマンドがパイプライン化されるのを暗黙的に防止しています。 コールバックは、Redisが応答するまで呼び出されません。
  2. baseclientが異なる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が応答するよりも速く送信された場合は別のコンテキストから送信されますが、依存するコンテキストには応答しません

全てのコメント9件

client.multiおよびmulti.execコマンドを介して実行されますか?

こんにちは@ saritasa-パイプラインは自動です。 それは常にクライアントの内部で起こっています。 有効にするためにmultiまたはexecを使用する必要はありません。

こんにちはブライス、

  1. 混乱していますが、node_redis内の「マルチ」関数の目的は何ですか?
  2. コマンドを自動的にパイプライン化するために使用されるアルゴリズムは何ですか?

ありがとう、
ドミトリー

マルチオペレーションはRedisプロトコル仕様に基づいており、パイプライン以外のトランザクション目的があります: http

パイプラインの仕組みに関して: http

ブライスに感謝します。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つの理由により、これらが同じパイプライン書き込みフレームで送信されることはありません。

  1. sismemberのコールバックは、hgetall呼び出しを呼び出すものです。したがって、特定のsismember呼び出しに対して、これらのコマンドがパイプライン化されるのを暗黙的に防止しています。 コールバックは、Redisが応答するまで呼び出されません。
  2. baseclientが異なる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以降で考えられているようにパイプラインを使用します。

このページは役に立ちましたか?
0 / 5 - 0 評価