Comment concevoir redis pub/sub pour un système de messagerie instantanée?

je suis nouveau sur le redis pub/sub. J'ai un chat dans le système qui est comme IM. Je voudrais donc utiliser redis pub/sub. Comme j'ai examiné les échantillons la plupart d'entre eux sont conçus sur la base d'un salon de discussion. Dans mon système, j'aurai plusieurs salles de chat entre utilisateurs comme;

A:B
A:C
D:C
E:F

Donc, les lignes ci-dessus sont les chambres. Et j'ai implémenté le serveur avec node.js comme ci-dessous;

var store = redis.createClient();
var pub = redis.createClient();
io.sockets.on('connection', function (socket) {
    var sub = redis.createClient();

    sub.on("message", function(pattern, data){
            data = JSON.parse(data);
        socket.send(JSON.stringify({ type: "chat", key: pattern, nick: data.nickname, message: data.text }))
        }
    });

    socket.on('message', function (messageData) {
        store.incr("messageNextId", function(e, messageId) {
        var room = ""
        var from = messageData.clientId > socket.nickname ? socket.nickname : messageData.clientId;
        var to = messageData.clientId < socket.nickname ? socket.nickname : messageData.clientId;   
            room = from + ":" + to;

        var message = { id: messageId, nickname: socket.nickname, text: messageData.text };
        store.rpush("rooms:" + room, JSON.stringify(message), function(e, r) {  
             pub.publish(room, JSON.stringify(message))
        });
    });
});

comme vous pouvez le voir je crée un nouveau redis abonné pour chaque connexion. Dans d'autres échantillons de salon de discussion, le client abonné redis est créé globalement. Et il n'existe que trois connexions en tout temps et cela résout leur problème parce que lorsqu'un éditeur publie un message, tous les clients connectés devraient l'obtenir. Mais j'ai une contrainte ici. Je veux ouvrir une session de chat entre deux utilisateurs et seuls ces utilisateurs devraient être les abonnés. Le code ci-dessus fonctionne comme je le voudrais mais je ne sais pas s'il est correct pour redis de créer un nouveau client abonné pour chaque connexion.

ce serait génial d'entendre vos suggestions. Merci à l'avance.

14
demandé sur Ali Ersöz 2012-04-13 17:59:35

1 réponses

comme toujours, vous devez comparer des choses comme ceci pour votre propre cas d'utilisation -- il n'est pas possible de donner des conseils généraux. Vous pourriez avoir besoin d'augmenter le nombre maximum de fichiers ouverts sur votre système, soit à l'échelle du système ou pour l'utilisateur redis. Cela s'applique également à l'utilisateur exécutant le serveur web, bien sûr.

cela dit, vous devez vous assurer d'écouter socket.on('disconnect') et quit() l'abonné redis quand un utilisateur quitte. Vous pourriez également être intéressé de savoir cette prise.io a un backend redis, qui utilise redis pub / sub, et il a également le concept de chambres, de sorte que vous pourriez vous épargner quelques problèmes en utilisant ce que vous êtes déjà en fonction de socket.io.

modifier: après un contrôle rapide, je reçois ce message d'erreur de Redis après 991 abonnés:

Ready check failed: Error: Error: ERR max number of clients reached

voici de la valeur par défaut redis.conf :

# Set the max number of connected clients at the same time. By default
# this limit is set to 10000 clients, however if the Redis server is not
# able ot configure the process file limit to allow for the specified limit
# the max number of allowed clients is set to the current file limit
# minus 32 (as Redis reserves a few file descriptors for internal uses).
#
# Once the limit is reached Redis will close all the new connections sending
# an error 'max number of clients reached'.
#
# maxclients 10000

mon système (Ubuntu 11.11) livré avec une limite par défaut nofile de 1024, donc mon test rapide devrait échouer Après 992 clients connectés, ce qui semble à peu près juste à partir du test (j'ai aussi un client pour l'éditeur). Je vous suggère d'inspecter votre limite nofile (sur mon système c'est dans /etc/security/limits.{conf,d/*} et votre réglage redis maxclients , et puis benchmark, benchmark, benchmark!

20
répondu Linus Gustav Larsson Thiel 2012-04-13 15:02:19