복붙노트

[REDIS] Node.js를, Socket.io, 레디 스 펍 / 서브 높은 볼륨, 낮은 지연 시간의 어려움

REDIS

Node.js를, Socket.io, 레디 스 펍 / 서브 높은 볼륨, 낮은 지연 시간의 어려움

socket.io/node.js을들이 결합되어 다중 전송을 처리 할 수있는 서버 이벤트에 의해 구동되는 실시간 웹 방송 시스템을 구축하기위한 시도 술집 / 하위 레디 스 때, 세 가지 방법이있을 것 같습니다 :

번호 하나는 모든 클라이언트에 대해 한 번 레디 스 하위 및 관련 이벤트를 처리 할 수 ​​있습니다. 번호는 2 개 이벤트 레디 스 펍 / 서브에 더 직접적인 후크를. 번호 3는 간단하지만 메시징 이벤트를 통해 제공 작은 제어 할 수 있습니다.

하지만, 내 테스트에서 모든 전시 1 개 이상 연결된 클라이언트와의 예기치 않게 낮은 성능을 제공합니다. 문제의 서버 이벤트가 가능한 한 빨리으로 레디 스 채널에 게시 1000 메시지입니다, 가능한 한 빨리로 배포합니다. 성능은 (로그 분석을위한 레디 스 목록에 타임 스탬프 것을 기반 socket.io 클라이언트)에 연결된 클라이언트에서 타이밍에 의해 측정된다.

나는 추측 옵션 1, 서버는 메시지를 수신에, 순차적으로 연결된 모든 클라이언트에 기록하는 것이 무엇입니까. 옵션 2에서, 서버 (클라이언트 가입에 한 번) 각 메시지에 여러 번 수신하고 해당 클라이언트에 기록합니다. 이 연결된 모든 클라이언트에 전달 될 때까지 두 경우 모두, 서버는 두 번째 메시지 이벤트에 도착하지 않습니다. 상황이 명확하게 상승 동시성 악화.

이것은 스택 기능의 인식 지혜와 상충 보인다. 나는 믿고 싶어,하지만 난 사투를 벌인거야.

이 시나리오는 이러한 도구 (메시지의 높은 볼륨의 낮은 대기 시간 분포를) 그냥 옵션을 (아직?)인가, 아니면 속임수를 놓친 거지?

해결법

  1. ==============================

    1.나는 이것이 합리적인 질문이라고 생각하고 잠깐 동안의 뒷면을 연구했다. 나는 당신이에서 유용한 정보를 픽업 할 수 있다는 예를 검색 할 약간의 시간을 보냈다.

    나는 이것이 합리적인 질문이라고 생각하고 잠깐 동안의 뒷면을 연구했다. 나는 당신이에서 유용한 정보를 픽업 할 수 있다는 예를 검색 할 약간의 시간을 보냈다.

    나는 곧장 앞으로 예제로 시작하고자 :

    빛 샘플 (당신이 매트 Ranney에 의한 node_redis 같은 뭔가 레디 스 노드 클라이언트를 대체 할 수 있습니다 유의 한 페이지입니다 :

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

    이 문서의 톤이 밖으로, 그리고 각 문서의 시간 관련성을 무게해야합니다 있도록 API는 빠르게 스택의이 유형에 변화하고있다.

    불과 몇 관련 질문이 스택에 뜨거운 주제는 다음과 같습니다

    끄거나 최적화 소켓 풀링, 효율적인 바인딩, 모니터의 대기 시간을 사용하고, 당신이 복제하지 않는 작업 (즉, 필요 두 번 모든 리스너에 게시)를하지 않습니다.

  2. from https://stackoverflow.com/questions/10557826/node-js-socket-io-redis-pub-sub-high-volume-low-latency-difficulties by cc-by-sa and MIT license