Node-redis: Rohrleitungen

Erstellt am 13. Jan. 2014  ·  9Kommentare  ·  Quelle: NodeRedis/node-redis

Hallo Leute,

Wie kann man Pipelining in node_redis programmgesteuert aktivieren?

Ich habe in der Dokumentation gesehen, dass dies in den meisten Fällen automatisch geschieht - und ich möchte verstehen, ob es eine Möglichkeit gibt, es programmgesteuert aus dem Anwendungscode in node_redis zu erzwingen

[ ec2-user@devops ~]$ redis-benchmark -n 100000 -t set,get -P 16 -q -h 10.0.1.10
SET: 199600,80 Anfragen pro Sekunde
GET: 193050,19 Anfragen pro Sekunde

[ ec2-user@devops ~]$ redis-benchmark -n 100000 -t set,get -q -h 10.0.1.12
SET: 14098,41 Anfragen pro Sekunde
GET: 13743,82 Anfragen pro Sekunde

Beim Redis-Knoten beträgt der Unterschied mehr als das Zehnfache.

Danke,
Dmitri

Feature Request fixed / done

Hilfreichster Kommentar

Alle Befehle werden "pipelined" gesendet, aber diese würden aus einem oder zwei Gründen niemals im selben Pipeline-Schreibrahmen gesendet:

  1. Der Rückruf für den sismember ruft den hgetall-Aufruf auf – daher verhindern Sie implizit, dass diese Befehle für einen bestimmten sismember-Aufruf zusammengeführt werden. Der Rückruf wird erst aufgerufen, wenn Redis antwortet.
  2. Wenn base und client unterschiedliche Redis-Clients sind, könnten sie _NIEMALS_ dieselbe Pipeline teilen.

Befehle müssen aus demselben Kontext* ausgeführt werden, um einen Nutzen aus dem Pipelining zu sehen. ZB ähnlich dem PING-Beispiel in den Redis-Pipelining-Dokumenten:

// 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()
})

* oder aus separaten Kontexten, wenn schneller gesendet wird, als Redis antwortet, aber niemals abhängige Kontexte antworten

Alle 9 Kommentare

Erfolgt dies über die Befehle client.multi und multi.exec?

Hallo @saritasa - das Pipelining erfolgt automatisch. Es geschieht immer innerhalb des Clients. Sie müssen nicht multi oder exec verwenden, um es zu aktivieren.

Hallo Bryce,

  1. Ich bin verwirrt, was ist dann der Zweck von "Multi"-Funktionen in node_redis?
  2. Welcher Algorithmus wird für die automatische Pipeline der Befehle verwendet?

Danke,
Dmitri

Multi-Operationen stammen aus der Redis-Protokollspezifikation, sie haben einen transaktionalen Zweck außerhalb des Pipelining: http://redis.io/commands/multi

In Bezug auf die Funktionsweise von Pipelining: http://redis.io/topics/pipelining Dies ist nur eine Frage des Clients, der Befehle so schnell an Redis schreibt, wie Sie sie senden, ohne auf die Antwort zu warten, bevor Sie den nächsten schreiben. Der Client verfolgt die gesendeten Befehle und ordnet die Antworten dann den gesendeten Befehlen neu an, sobald Redis antwortet.

Danke Bryce, ich verstehe, wie http://redis.io/topics/pipelining funktioniert. in einer node.js-Anwendung - wie sollte der Code strukturiert sein, damit die Anfragen weitergeleitet werden?

also im Beispiel unten

hgetall & verfallen - sind Pipelines oder nicht? Einer der Anrufe ist ein Rückruf.


Funktion getByID(Tabelle, ID, nächste) {
if (!success) return setTimeout(function() {
getByID(Tabelle, ID, nächste);
}, 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()
            });
        }
    });  
});

}

Alle Befehle werden "pipelined" gesendet, aber diese würden aus einem oder zwei Gründen niemals im selben Pipeline-Schreibrahmen gesendet:

  1. Der Rückruf für den sismember ruft den hgetall-Aufruf auf – daher verhindern Sie implizit, dass diese Befehle für einen bestimmten sismember-Aufruf zusammengeführt werden. Der Rückruf wird erst aufgerufen, wenn Redis antwortet.
  2. Wenn base und client unterschiedliche Redis-Clients sind, könnten sie _NIEMALS_ dieselbe Pipeline teilen.

Befehle müssen aus demselben Kontext* ausgeführt werden, um einen Nutzen aus dem Pipelining zu sehen. ZB ähnlich dem PING-Beispiel in den Redis-Pipelining-Dokumenten:

// 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()
})

* oder aus separaten Kontexten, wenn schneller gesendet wird, als Redis antwortet, aber niemals abhängige Kontexte antworten

habe es jetzt bekommen - danke! Das ist ein sehr wertvoller Kommentar!

Ich denke, node_redis "automatisches Pipelining" ist nicht das Pipelining, auf das von offiziellen Redis verwiesen wird.

Diese Zeit wird RTT (Round Trip Time) genannt. Es ist sehr leicht zu erkennen, wie sich dies auf die Leistung auswirken kann, wenn ein Client viele Anfragen hintereinander ausführen muss (zum Beispiel das Hinzufügen vieler Elemente zu derselben Liste oder das Auffüllen einer Datenbank mit vielen Schlüsseln). Wenn die RTT-Zeit beispielsweise 250 Millisekunden beträgt (bei einer sehr langsamen Verbindung über das Internet), können wir selbst dann, wenn der Server 100.000 Anfragen pro Sekunde verarbeiten kann, maximal vier Anfragen pro Sekunde verarbeiten.
Wenn die verwendete Schnittstelle eine Loopback-Schnittstelle ist, ist die RTT viel kürzer (zum Beispiel meldet mein Host 0,044 Millisekunden Ping 127.0.0.1), aber es ist immer noch viel, wenn Sie viele Schreibvorgänge hintereinander ausführen müssen.

Das Pipelining durch offizielles Redis bedeutet, mehrere Befehle zu kombinieren und einmal zu senden, um der Latenz aufgrund von RTT entgegenzuwirken, die von node_redis nicht angesprochen wird. Und "automatica pipelining" in node_redis sendet tatsächlich so viele Befehle wie möglich gleichzeitig, indem das asynchrone Programmiermodell von Node verwendet wird.

Hier ist ein guter Artikel zu diesem Thema. http://informatikr.com/2012/redis-pipelining.html

@Vizwind @saritasa sowohl .multi als auch .batch verwenden Pipelining, wie ab Version 2.2 gedacht.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

dotSlashLu picture dotSlashLu  ·  5Kommentare

abhaygarg picture abhaygarg  ·  5Kommentare

Mickael-van-der-Beek picture Mickael-van-der-Beek  ·  6Kommentare

adamgajzlerowicz picture adamgajzlerowicz  ·  4Kommentare

Atala picture Atala  ·  3Kommentare