Node.js + Redis内存泄漏。难道我做错了什么?

时间:2015-09-26 19:20:42

标签: node.js memory-leaks redis node-redis

var redis = require("redis"),
client = redis.createClient();

for(var i =0 ; i < 1000000; i++){
    client.publish('channel_1', 'hello!');
}

执行代码后,Node进程占用1.2GB内存并保留在那里; GC不会减少分配的内存。如果我模拟200万条消息或4x500000,则节点因内存错误而崩溃。

节点:0.8。*,稍后尝试过4.1.1但没有任何改变 Redis:2.8,效果很好(1MB分配内存)。

我的服务器每小时将发布超过100万封邮件。所以这绝对不可接受(每小时都会崩溃)。

更新测试

var redis = require("redis"),
    client = redis.createClient();

var count = 0;
var x;

function loop(){
    count++;
    console.log(count);

    if(count > 2000){
        console.log('cleared');
        clearInterval(x);
    }
    for(var i =0 ; i < 100000; i++){
        client.set('channel_' + i, 'hello!');
    }

}

x = setInterval(loop, 3000);

这分配~50Mb,峰值为200Mb,现在GC下降内存回到50Mb

1 个答案:

答案 0 :(得分:1)

如果您查看node_redis客户端来源,您会看到每个send操作returns a boolean指示命令队列是否已超过高水位线(默认情况下) 1000)。如果你要记录这个返回值(或者,启用redis.debug_mode),你很可能会看到false很多 - 表明你发送的请求比Redis要多得多一次处理所有。

如果结果不是这样,那么命令队列确实会被定期清除,这意味着GC很可能是问题。

无论哪种方式,请尝试jfriend00的建议。毫无延迟地发送1M +异步消息(所以基本上一次性发送)不是一个好的测试。队列需要时间来清除,GC需要时间来完成它的工作。

来源: Backpressure and Unbounded Concurrency&amp; Node-redis client return values