Redis
 sql >> Teknologi Basis Data >  >> NoSQL >> Redis

Node.js, Socket.io, Redis pub/sub volume tinggi, kesulitan latensi rendah

Saya pikir ini adalah pertanyaan yang masuk akal dan telah menelitinya secara singkat beberapa waktu lalu. Saya menghabiskan sedikit waktu mencari contoh yang mungkin dapat Anda ambil dari beberapa tips bermanfaat.

Contoh

Saya suka memulai dengan contoh langsung:

  • kode contoh ringan
  • Node.js + Redis Pub/Sub + demo socket.io

Sampel ringan adalah satu halaman (perhatikan bahwa Anda ingin mengganti redis-node-client dengan sesuatu seperti node_redis oleh Matt Ranney:

/*
 * 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");

Dokumen

Ada banyak sekali dokumentasi di luar sana, dan apis berubah dengan cepat pada jenis tumpukan ini sehingga Anda harus mempertimbangkan relevansi waktu setiap dokumen.

  • aliran aktivitas simpul
  • contoh pengecoran awan
  • cara membuat simpul redis pubsub
  • latensi redis
  • buku resep redis Menggunakan Pub/Sub untuk Komunikasi Asinkron
  • kiat umum linkedin
  • pengikatan simpul redis
  • pertanyaan nodejs grup google

Pertanyaan Terkait

Hanya beberapa pertanyaan terkait, ini adalah topik hangat di tumpukan:

  • Redis pub/sub untuk server obrolan di node.js
  • Bagaimana merancang redis pub/sub untuk sistem pesan instan?

Kiat penting (ymmv)

Matikan atau optimalkan penggabungan soket, gunakan binding yang efisien, pantau latensi, dan pastikan Anda tidak menduplikasi pekerjaan (yaitu tidak perlu memublikasikan ke semua pendengar dua kali).




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. flushdb tidak menghapus semua kunci di redis?

  2. MENGERINGKAN RedisTemplate generik di Musim Semi 4

  3. Klien Redis

  4. Apakah mungkin untuk membuat beberapa penyimpanan cache menggunakan abstraksi cache Spring dengan redis?

  5. Pod DigitalOcean memiliki PersistentVolumeClaims langsung yang tidak terikat