Jak zaprojektować redis pub / sub dla systemu komunikatorów?

Jestem nowy w redis pub / sub. Mam czat w systemie, który jest jak im. Więc chciałbym użyć redis pub / sub. Ponieważ zbadałem próbki, większość z nich została zaprojektowana w oparciu o Czat. W moim systemie będę miał wiele czatów między użytkownikami jak;

A:B
A:C
D:C
E:F
/ Align = "center" bgcolor = "# e0ffe0 " / cesarz chin / / align = center / I zaimplementowałem serwer z węzłem.js jak poniżej;
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))
        });
    });
});

Jak widzisz, tworzę nowego abonenta redis dla każdego połączenia. W innym czacie próbki redis klient Abonenta jest tworzony globalnie. I istnieją tylko trzy połączenia przez cały czas i to rozwiązuje ich problem, ponieważ kiedy wydawca publikuje wiadomość, wszyscy podłączeni klienci powinni ją otrzymać. Ale mam tu pewne ograniczenia. Chcę otworzyć sesję czatu między dwoma użytkownikami i tylko ci użytkownicy powinni być subskrybentami. Powyższy kod działa tak, jak chciałbym, ale nie wiem, czy redis jest w porządku, aby utworzyć nowego klienta Abonenta dla każdego połączenia.

To miło będzie usłyszeć Twoje sugestie. Z góry dzięki.

Author: Ali Ersöz, 2012-04-13

1 answers

Jak zawsze, musisz porównywać takie rzeczy do własnego użytku-nie można udzielać ogólnych porad. Może być konieczne zwiększenie maksymalnej liczby otwartych plików w systemie, zarówno dla całego systemu, jak i dla użytkownika redis. Dotyczy to oczywiście również użytkownika prowadzącego Twój serwer WWW.

To powiedziawszy, powinieneś upewnić się, że słuchasz socket.on('disconnect') i quit() Abonenta redis, gdy użytkownik odchodzi. Możesz być również zainteresowany, aby wiedzieć, że socket.io posiada zaplecze redis, który wykorzystuje redis pub / sub, a także ma koncepcję pokoi, więc możesz zaoszczędzić sobie kłopotów, używając tego, ponieważ już zależy od socket.io.

Edit: Po szybkim sprawdzeniu dostaję komunikat o błędzie z Redis po 991 subskrybentach:

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

Tutaj jest z domyślnego 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

Mój system (Ubuntu 11.11) ma domyślny nofile limit 1024, więc mój szybki test powinien zawieść po 992 połączonych klientach, co wydaje się być w porządku z testu (mam też jednego klienta dla wydawcy). Moja sugestia dla ciebie to sprawdzenie swojego nofile limitu (w moim systemie jest to w /etc/security/limits.{conf,d/*} i twoje ustawienie redis maxclients, a następnie benchmark, benchmark, benchmark!

 20
Author: Linus Gustav Larsson Thiel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-13 15:02:19