Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 从单个REDIS实例读取Nodejs集群架构_Node.js_Redis_Cluster Computing - Fatal编程技术网

Node.js 从单个REDIS实例读取Nodejs集群架构

Node.js 从单个REDIS实例读取Nodejs集群架构,node.js,redis,cluster-computing,Node.js,Redis,Cluster Computing,我正在使用Nodejscluster模块让多个工人运行。 我创建了一个基本的体系结构,其中将有一个主进程,它基本上是一个处理多个请求的express服务器,主进程的主要任务是将来自请求的传入数据写入REDIS实例。其他工作人员(NUMOFCPU-1)将是非主控的,即他们不会处理任何请求,因为他们只是消费者。我有两个特性,即ABC和DEF。我通过指定非主辅助对象的类型,将其均匀分布在各个功能上 例如:在8芯机器上: 1将是通过express server处理请求的主实例 剩余的(8-1=7)将均匀

我正在使用Nodejs
cluster
模块让多个工人运行。 我创建了一个基本的体系结构,其中将有一个主进程,它基本上是一个处理多个请求的express服务器,主进程的主要任务是将来自请求的传入数据写入REDIS实例。其他工作人员(NUMOFCPU-1)将是非主控的,即他们不会处理任何请求,因为他们只是消费者。我有两个特性,即ABC和DEF。我通过指定非主辅助对象的类型,将其均匀分布在各个功能上

例如:在8芯机器上:

1将是通过express server处理请求的主实例

剩余的(8-1=7)将均匀分布。4至功能:ABD,3至fetaure:DEF

非主工作人员基本上是消费者,即他们从只有主工作人员才能写入数据的REDIS读取数据

下面是相同的代码:

if (cluster.isMaster) {
  // Fork workers.
  for (let i = 0; i < numCPUs - 1; i++) {
    ClusteringUtil.forkNewClusterWithAutoTypeBalancing();
  }

  cluster.on('exit', function(worker) {
    console.log(`Worker ${worker.process.pid}::type(${worker.type}) died`);
    ClusteringUtil.removeWorkerFromList(worker.type);
    ClusteringUtil.forkNewClusterWithAutoTypeBalancing();
  });

  // Start consuming on server-start
  ABCConsumer.start();
  DEFConsumer.start();

  console.log(`Master running with process-id: ${process.pid}`);
} else {
  console.log('CLUSTER  type', cluster.worker.process.env.type, 'running on', process.pid);
  if (
    cluster.worker.process.env &&
    cluster.worker.process.env.type &&
    cluster.worker.process.env.type === ServerTypeEnum.EXPRESS
  ) {
    // worker for handling requests
    app.use(express.json());
    ...
  }
{

消费者只需接受消息并在忙时停止

module.exports.startHeartbeat = startHeartbeat = async function(config = {}) {
  if (!config || !config.type || !config.listKey) {
    return;
  }

  heartbeatIntervalObj[config.type] = setInterval(async () => {
    await asyncLindex(config.listKey, -1).then(async res => {
      if (res) {
        await getFreeWorkerAndDoJob(res, config);
        stopHeartbeat(config);
      }
    });
  }, HEARTBEAT_INTERVAL);
};
理想情况下,消息应该只由该特定功能的一个使用者读取。消费之后,它被标记为忙碌,所以在空闲之前它不会再消费(我已经处理了这个问题)。下一条消息只能由其他可用使用者中的一个使用者处理

const stringifedData = JSON.stringify(req.body);
  const key = uuidv1();

  const asyncHsetRes = await asyncHset(type, key, stringifedData);

  if (asyncHsetRes) {
    await asyncRpush(FeatureKeyEnum.REDIS.ABC_MESSAGE_QUEUE, key);
    res.send({ status: 'success', message: 'Added to processing queue' });
  } else {
    res.send({ error: 'failure', message: 'Something went wrong in adding to queue' });
  }
请帮我解决这个问题。同样,我希望一条消息只被一个免费的消费者阅读,其余的免费消费者应该等待新的消息


谢谢

我不确定我是否完全理解您的Redis consumers架构,但我觉得它与Redis本身的用例相矛盾。您试图实现的本质上是基于队列的消息传递,它能够在消息完成后提交消息

Redis有自己的pub/sub功能,但它是建立在fire和forget原则之上的。它不区分消费者——它只是将数据发送给所有消费者,假设这是他们处理传入数据的逻辑

我建议您使用RabbitMQ之类的队列服务器。您可以通过AMQP 0-9-1支持的一些功能实现您的目标:消息确认、消费者的预回迁计数等。您可以使用非常灵活的配置设置集群,如ok,我希望有X个消费者,每个消费者一次可以处理1条唯一的(!)消息,只有在他们让服务器(rabbitmq)知道他们成功完成了消息处理后,他们才会收到新的消息。这是高度可配置和健壮的

但是,如果您希望使用一些完全管理的服务来实现无服务器,这样您就不会像虚拟机或其他任何东西一样运行您选择的消息队列服务器,那么您可以使用AWS SQS。它有非常相似的API和特性列表


希望有帮助

谢谢,弗拉迪斯拉夫。你的回答给了我更多的见解,但我仍然需要一些能够准确解决这个问题的东西。唯一的要求是如何在多个NODEJS进程中使用REDIS消息,但是一个进程应该同时使用一条消息,而不是其他进程。好的,您可以在REDIS和使用者之间放置另一个进程。该过程将接收来自redis的消息,并将其随机分发到消费者的池中。或者只是以某种方式修改您的消息,这样流程就会知道哪些消息应该使用,哪些消息应该忽略,因为其他人会使用它们。什么阻止您使用队列?