Node.js 如何将redis与node js群集一起使用

Node.js 如何将redis与node js群集一起使用,node.js,redis,Node.js,Redis,我一直在使用redis作为我的nodejs服务器的内存存储。 会话也通过redis进行管理 目前我一直在做的是,每当我的服务器连接到它时,我就会刷新我的redis,这样每当服务器启动时就不会有会话 像这样: redisClient.on('connect', function () { redisClient.flushdb(function (err, succeeded) { logger.debug("redis db cleared on startup--",

我一直在使用
redis
作为我的
nodejs
服务器的内存存储。 会话也通过redis进行管理

目前我一直在做的是,每当我的服务器连接到它时,我就会刷新我的
redis
,这样每当服务器启动时就不会有会话

像这样:

redisClient.on('connect', function () {
    redisClient.flushdb(function (err, succeeded) {
        logger.debug("redis db cleared on startup--", succeeded); // will be true if successfull
    });
});
我还将
redis
用于一些其他数据存储,如一些
队列

但是现在我想在我的服务器上实现集群

num_processes = require('os').cpus().length;
if (cluster.isMaster) {
console.log(`Master ${process.pid} is running`);
var workers = [];

// Helper function for spawning worker at index 'i'.
var spawn = function(i) {
    console.log("spawing at index---",i);
    workers[i] = cluster.fork();
    console.log("----worker id-------", workers[i].id,"-------");
    // Optional: Restart worker on exit
    workers[i].on('exit', function(code, signal) {
        console.log(`code is ${code} and signal is ${signal}`)
        console.log(`worker ${workers[i].process.pid} died array index is ---${i}`);
        console.log('respawning worker', i);
        spawn(i);
    });
    workers[i].on('listening', () => {
        workers[i].send({'index' : i });
    });
};

// Spawn workers.
for (var i = 0; i < num_processes; i++) {
    spawn(i);
} // Code to run if we're in a worker process
} else {
var redis = require('redis');
const sio_redis = require('socket.io-redis'),

redisClient = redis.createClient();
redisClient.on('connect', function () {
    redisClient.flushdb(function (err, succeeded) {
        logger.debug("redis db cleared on startup--", succeeded); // will be true if successfull
    });
});

var RedisStore = require('connect-redis')(session);
const redisStore = new RedisStore({'host': 'localhost', 'port': 6379, 'client': redisClient});
var server = require('http').Server(app);
var listeningServer = server.listen(3002);
}
我的问题是,如果我有4个
内核
,我的服务器上将运行4个节点实例

num_processes = require('os').cpus().length;
if (cluster.isMaster) {
console.log(`Master ${process.pid} is running`);
var workers = [];

// Helper function for spawning worker at index 'i'.
var spawn = function(i) {
    console.log("spawing at index---",i);
    workers[i] = cluster.fork();
    console.log("----worker id-------", workers[i].id,"-------");
    // Optional: Restart worker on exit
    workers[i].on('exit', function(code, signal) {
        console.log(`code is ${code} and signal is ${signal}`)
        console.log(`worker ${workers[i].process.pid} died array index is ---${i}`);
        console.log('respawning worker', i);
        spawn(i);
    });
    workers[i].on('listening', () => {
        workers[i].send({'index' : i });
    });
};

// Spawn workers.
for (var i = 0; i < num_processes; i++) {
    spawn(i);
} // Code to run if we're in a worker process
} else {
var redis = require('redis');
const sio_redis = require('socket.io-redis'),

redisClient = redis.createClient();
redisClient.on('connect', function () {
    redisClient.flushdb(function (err, succeeded) {
        logger.debug("redis db cleared on startup--", succeeded); // will be true if successfull
    });
});

var RedisStore = require('connect-redis')(session);
const redisStore = new RedisStore({'host': 'localhost', 'port': 6379, 'client': redisClient});
var server = require('http').Server(app);
var listeningServer = server.listen(3002);
}
num_进程=require('os').cpu().length;
if(cluster.isMaster){
log(`Master${process.pid}正在运行`);
var工人=[];
//用于在索引“i”处生成工作程序的助手函数。
var spawn=函数(i){
log(“在索引--”处的spawing,i);
workers[i]=cluster.fork();
console.log(“----worker-id------”,workers[i].id,“----”;
//可选:退出时重新启动工作进程
工人[i]。在('exit',函数(代码,信号)上{
log(`code是${code},signal是${signal}`)
log(`worker${workers[i].process.pid}数组索引为--${i}`);
控制台日志(“重生工人”,i);
产卵(i);
});
工人[i].关于('倾听',()=>{
workers[i].send({'index':i});
});
};
//产卵工人。
对于(var i=0;i
如果任何实例由于某种原因退出或死亡,它将清除redis中的所有会话和数据


我不想发生这种事。在这种情况下,我应该如何使用redis,以便清除与该实例对应的会话和数据?

我认为基本上有两种方法可以解决这个问题:

  • 不要冲洗redis
  • 将刷新与实例启动分开
不要冲水 您说要在启动时清理会话数据。好的,让会话不在内存中的一个要点是在会话之间持久化它们,并使实际的应用程序服务器(Node.js app)保持无状态

例如,您可以在所有会话数据上设置过期密钥。因此,每次“保存”会话时,您也会在该会话上设置Ex,甚至可以选择在每次访问该会话时延长该TTL(因此,一个会话从最后一次触摸它起有效12小时,或者其他)。或者,根据您的使用情况,您的会话中间件可以做到这一点,例如

或者根本不让它过期

独立冲洗 也许你只是刷新会话,因为你希望有突破性的变化,而你的旧会话将无法工作。或者有一个明确的要求,即在每次新部署时,都要清理会话数据。无论如何,你要把这个分开。例如,将您的
server.js
作为您的应用程序,并拥有一个单独的
会话清理.js
文件,用于连接到redis、刷新和断开连接。然后进行如下npm设置:

"scripts": {
    "session.cleanup": "node lib/session-cleanup.js",
    "start": "npm run session.cleanup && node lib/server.js",
    ...
}
这样,在运行
server.js
并运行集群模式之前,您将首先清理会话。如果集群实例死而复生,则什么也不会发生


现在,每次你重新部署,你都会清理它。或者甚至从“开始”中删除它,并让您的部署管道调用显式地运行session.cleanup
。您甚至可以在管理UI中公开一个按钮,以便在运行时执行此操作(这可能会使您注销:)。关键是,会话清理现在与服务器启动是一个单独的问题。

您可以检查当前进程是否为主进程。这样,它只会在您第一次启动应用程序时刷新。如果任何fork重新启动,则不会刷新数据库

redisClient = redis.createClient();
redisClient.on('connect', function() {
    if (cluster.isMaster) {
        redisClient.flushdb(function(err, succeeded) {
            logger.debug("redis db cleared on startup--", succeeded); // will be true if successfull
        });
    }else{
        logger.debug("Forked instance no need to flush redis db"); // 
    }
});

你将如何运行实例?我已经添加了代码,实例是如何运行的?你能告诉我什么时候应该使用redis群集吗?当你需要扩展时,通常会使用redis群集。我不能真正回答你的问题,你必须做一些研究和学习。