Redis
 sql >> Baza danych >  >> NoSQL >> Redis

Node.js, Socket.io, Redis pub/sub wysoki poziom głośności, małe opóźnienia

Pomyślałem, że to rozsądne pytanie i jakiś czas temu krótko je zbadałem. Poświęciłem trochę czasu na szukanie przykładów, z których możesz znaleźć przydatne wskazówki.

Przykłady

Lubię zaczynać od prostych przykładów:

  • lekki przykładowy kod
  • Node.js + Redis Pub/Sub + demo socket.io

Lekki przykład to pojedyncza strona (pamiętaj, że będziesz chciał zastąpić redis-node-client czymś w rodzaju node_redis autorstwa Matta Ranneya:

/*
 * Mclarens Bar: Redis based Instant Messaging
 * Nikhil Marathe - 22/04/2010

 * A simple example of an IM client implemented using
 * Redis PUB/SUB commands so that all the communication
 * is offloaded to Redis, and the node.js code only
 * handles command interpretation,presentation and subscribing.
 * 
 * Requires redis-node-client and a recent version of Redis
 *    http://code.google.com/p/redis
 *    http://github.com/fictorial/redis-node-client
 *
 * Start the server then telnet to port 8000
 * Register with NICK <nick>, use WHO to see others
 * Use TALKTO <nick> to initiate a chat. Send a message
 * using MSG <nick> <msg>. Note its important to do a
 * TALKTO so that both sides are listening. Use STOP <nick>
 * to stop talking to someone, and QUIT to exit.
 *
 * This code is in the public domain.
 */
var redis = require('./redis-node-client/lib/redis-client');

var sys = require('sys');
var net = require('net');

var server = net.createServer(function(stream) {
    var sub; // redis connection
    var pub;
    var registered = false;
    var nick = "";

    function channel(a,b) {
    return [a,b].sort().join(':');
    }

    function shareTable(other) {
    sys.debug(nick + ": Subscribing to "+channel(nick,other));
    sub.subscribeTo(channel(nick,other), function(channel, message) {
        var str = message.toString();
        var sender = str.slice(0, str.indexOf(':'));
        if( sender != nick )
        stream.write("[" + sender + "] " + str.substr(str.indexOf(':')+1) + "\n");
    });
    }

    function leaveTable(other) {
    sub.unsubscribeFrom(channel(nick,other), function(err) {
        stream.write("Stopped talking to " + other+ "\n");
    });
    }

    stream.addListener("connect", function() {
    sub = redis.createClient();
    pub = redis.createClient();
    });

    stream.addListener("data", function(data) {
    if( !registered ) {
        var msg = data.toString().match(/^NICK (\w*)/);
        if(msg) {
        stream.write("SERVER: Hi " + msg[1] + "\n");
        pub.sadd('mclarens:inside', msg[1], function(err) {
            if(err) {
            stream.end();
            }
            registered = true;
            nick = msg[1];
// server messages
            sub.subscribeTo( nick + ":info", function(nick, message) {
            var m = message.toString().split(' ');
            var cmd = m[0];
            var who = m[1];
            if( cmd == "start" ) {
                stream.write( who + " is now talking to you\n");
                shareTable(who);
            }
            else if( cmd == "stop" ) {
                stream.write( who + " stopped talking to you\n");
                leaveTable(who);
            }
            });
        });
        }
        else {
        stream.write("Please register with NICK <nickname>\n");
        }
        return;
    }

    var fragments = data.toString().replace('\r\n', '').split(' ');
    switch(fragments[0]) {
    case 'TALKTO':
        pub.publish(fragments[1]+":info", "start " + nick, function(a,b) {
        });
        shareTable(fragments[1]);
        break;
    case 'MSG':
        pub.publish(channel(nick, fragments[1]),
            nick + ':' +fragments.slice(2).join(' '),
              function(err, reply) {
              if(err) {
                  stream.write("ERROR!");
              }
              });
        break;
    case 'WHO':
        pub.smembers('mclarens:inside', function(err, users) {
        stream.write("Online:\n" + users.join('\n') + "\n");
        });
        break;
    case 'STOP':
        leaveTable(fragments[1]);
        pub.publish(fragments[1]+":info", "stop " + nick, function() {});
        break;
    case 'QUIT':
        stream.end();
        break;
    }
    });

    stream.addListener("end", function() {
    pub.publish(nick, nick + " is offline");
    pub.srem('mclarens:inside', nick, function(err) {
        if(err) {
        sys.debug("Could not remove client");
        }
    });
    });
});

server.listen(8000, "localhost");

Dokumenty

Istnieje mnóstwo dokumentacji, a interfejsy API szybko się zmieniają w tego typu stosach, więc będziesz musiał rozważyć znaczenie czasowe każdego dokumentu.

  • strumienie aktywności węzła
  • przykład odlewni w chmurze
  • jak węzeł redis pubsub
  • opóźnienie redis
  • książka kucharska redis wykorzystująca Pub/Sub do komunikacji asynchronicznej
  • ogólne wskazówki linkedin
  • Powiązania redis węzłów
  • pytanie nodejs o grupach google

Powiązane pytania

Tylko kilka powiązanych pytań, to gorący temat na stosie:

  • Redis pub/sub dla serwera czatu w node.js
  • Jak zaprojektować redis pub/sub dla systemu wiadomości błyskawicznych?

Ważne wskazówki (ymmv)

Wyłącz lub zoptymalizuj pulę gniazd, używaj wydajnych powiązań, monitoruj opóźnienia i upewnij się, że nie duplikujesz pracy (tj. nie musisz publikować dwukrotnie dla wszystkich słuchaczy).




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Serializacja Redis poprzedzona dodatkowym ciągiem

  2. Python i Redis:najlepsze praktyki aplikacji menedżera/pracownika

  3. Jak utworzyć db (key_space) w redis

  4. Python-redis:pobierz dane binarne po skonfigurowaniu klienta z decode_responses=True

  5. Wprowadzenie do struktur danych Redis:mapy bitowe