Maison  >  Article  >  interface Web  >  Quelles sont les méthodes pour que Cluster partage la mémoire ?

Quelles sont les méthodes pour que Cluster partage la mémoire ?

php中世界最好的语言
php中世界最好的语言original
2018-04-16 13:34:361325parcourir

Cette fois, je vais vous montrer comment faire en sorte que Cluster partage de la mémoire et quelles sont les précautions pour que Cluster partage de mémoire. Ce qui suit est un cas pratique, jetons un coup d'œil.

L'API standard de Node.js ne fournit pas de mémoire partagée de processus. Cependant, grâce à la méthode d'envoi de l'interface IPC et à la surveillance des événements de message, un mécanisme de collaboration entre plusieurs processus peut être implémenté pour faire fonctionner la mémoire partagée via. communication. .

##Utilisation de base de l'IPC :

// worker进程 发送消息
process.send(‘读取共享内存');
 
// master进程 接收消息 -> 处理 -> 发送回信
cluster.on('online', function (worker) {
   // 有worker进程建立,即开始监听message事件
   worker.on(‘message', function(data) {
     // 处理来自worker的请求
     // 回传结果
     worker.send(‘result')
   });
});

Dans Node.js, via send et on('message', La communication IPC mise en œuvre par callback) présente plusieurs caractéristiques. Tout d'abord, le maître et les travailleurs peuvent communiquer entre eux, mais les travailleurs ne peuvent pas communiquer directement entre eux, mais les travailleurs peuvent communiquer indirectement via le transfert principal. De plus, les données transmises via la méthode d'envoi seront traitées par JSON.stringify avant d'être transmises. Après avoir été reçues, elles seront analysées à l'aide de JSON.parse. Par conséquent, l'objet Buffer deviendra un tableau après avoir été transmis, mais la fonction ne peut pas être transmise directement. D'un autre côté, tous les types de données à l'exception du tampon et de la fonction peuvent être directement transférés (ce qui est déjà très puissant, et le tampon et la fonction peuvent également être transférés en utilisant des méthodes alternatives).

Sur la base des caractéristiques ci-dessus, nous pouvons concevoir une solution pour partager de la mémoire via IPC :

1. En tant qu'utilisateur de mémoire partagée, le processus de travail n'exploite pas directement la mémoire partagée, mais informe le processus maître via la méthode d'envoi d'effectuer des opérations d'écriture (définir) ou de lecture (obtenir).

2. Le processus maître initialise un objet Object en tant que mémoire partagée, et lit et écrit la valeur clé de l'Object en fonction du message envoyé par le travailleur.

3. Étant donné que la communication entre processus est utilisée, les opérations set et get initiées par le travailleur sont des opérations asynchrones. Le maître effectue des opérations de lecture et d'écriture réelles en fonction de la demande, puis renvoie les résultats au travailleur (c'est-à-dire qu'il envoie le résultat). données au travailleur).

##Format des données

Afin de mettre en œuvre des fonctions de lecture et d'écriture asynchrones entre les processus, le format des données de communication doit être standardisé.

Le premier concerne les données de demande du travailleur :

requestMessage = {
  isSharedMemoryMessage: true, // 表示这是一次共享内存的操作通信
  method: ‘set', // or ‘get' 操作的方法
  id: cluster.worker.id, // 发起操作的进程(在一些特殊场景下,用于保证master可以回信)
  uuid: uuid, // 此次操作的(用于注册/调用回调函数)
  key: key, // 要操作的键
  value: value // 键对应的值(写入)
}

Après avoir reçu les données, le maître effectuera les opérations correspondantes selon la méthode, puis enverra les données de résultat au travailleur correspondant selon requestMessage.id. Le format des données est le suivant :

responseMessage = {
  isSharedMemoryMessage: true, // 标记这是一次共享内存通信
  uuid: requestMessage.uuid, // 此次操作的唯一标示
  value: value // 返回值。get操作为key对应的值,set操作为成功或失败
}

. L'importance de la normalisation du format des données est qu'après avoir reçu la demande, le maître peut envoyer le résultat du traitement au travailleur correspondant, et une fois que le travailleur a reçu le résultat renvoyé, il peut appeler le rappel correspondant à la communication, réalisant ainsi une collaboration.

Après avoir standardisé le format des données, la prochaine chose à faire est de concevoir deux ensembles de codes, respectivement pour le processus maître et le processus de travail, pour surveiller la communication et traiter les données de communication afin de réaliser la fonction de mémoire partagée.

##Classe d'utilisateurs

Les instances de la classe User fonctionnent dans le processus de travail et sont responsables de l'envoi des demandes d'exploitation de la mémoire partagée et de l'écoute des réponses du maître.

var User = function() {
  var self = this;
  self.uuid = 0;
 
  // 缓存回调函数
  self.getCallbacks = {};
 
  // 接收每次操作请求的回信
  process.on('message', function(data) {
    
    if (!data.isSharedMemoryMessage) return;
    // 通过uuid找到相应的回调函数
    var cb = self.getCallbacks[data.uuid];
    if (cb && typeof cb == 'function') {
      cb(data.value)
    }
    // 卸载回调函数
    self.getCallbacks[data.uuid] = undefined;
  });
};
 
// 处理操作
User.prototype.handle = function(method, key, value, callback) {
 
  var self = this;
  var uuid = self.uuid++;
 
  process.send({
    isSharedMemoryMessage: true,
    method: method,
    id: cluster.worker.id,
    uuid: uuid,
    key: key,
    value: value
  });
 
  // 注册回调函数
  self.getCallbacks[uuid] = callback;
 
};
 
User.prototype.set = function(key, value, callback) {
  this.handle('set', key, value, callback);
};
 
User.prototype.get = function(key, callback) {
  this.handle('get', key, null, callback);
};

##Classe Manager

Les instances de la classe Manager fonctionnent dans le processus maître pour initialiser un objet en tant que mémoire partagée et, selon la demande de l'instance utilisateur, ajouter des paires clé-valeur à la mémoire partagée ou lire la valeur clé, puis envoyer le résultat. dos.

var Manager = function() {
 
  var self = this;
  
  // 初始化共享内存
  self.sharedMemory = {};
    
  // 监听并处理来自worker的请求
  cluster.on('online', function(worker) {
    worker.on('message', function(data) {
      // isSharedMemoryMessage是操作共享内存的通信标记
      if (!data.isSharedMemoryMessage) return;
      self.handle(data);
    });
  });
};
 
Manager.prototype.handle = function(data) {
  var self = this;
  var value = this[data.method](data);
 
  var msg = {
    // 标记这是一次共享内存通信
    isSharedMemoryMessage: true,       
    // 此次操作的唯一标示
    uuid: data.uuid,
    // 返回值
    value: value
  };
 
  cluster.workers[data.id].send(msg);
};
 
// set操作返回ok表示成功
Manager.prototype.set = function(data) {
  this.sharedMemory[data.key] = data.value;
  return 'OK';
};
 
// get操作返回key对应的值
Manager.prototype.get = function(data) {
  return this.sharedMemory[data.key];
};

##Comment utiliser

if (cluster.isMaster) {
 
  // 初始化Manager的实例
  var sharedMemoryManager = new Manager();
 
  // fork第一个worker
  cluster.fork();
 
  // 1秒后fork第二个worker
  setTimeout(function() {
    cluster.fork();
  }, 1000);
   
} else {
 
  // 初始化User类的实例
  var sharedMemoryUser = new User();
 
  if (cluster.worker.id == 1) {
    // 第一个worker向共享内存写入一组数据,用a标记
    sharedMemoryUser.set('a', [0, 1, 2, 3]);
  }
 
  if (cluster.worker.id == 2) {
    // 第二个worker从共享内存读取a的值
    sharedMemoryUser.get('a', function(data) {
      console.log(data); // => [0, 1, 2, 3]
    });
  }
  
}

Ce qui précède est une fonction de mémoire partagée multi-processus implémentée via la communication IPC. Il convient de noter que cette méthode met directement en cache les données dans la mémoire du processus maître Vous devez faire attention à l'utilisation de la mémoire. ici. Quelques stratégies d'élimination simples pour optimiser l'utilisation de la mémoire. De plus, si les données lues et écrites en une seule fois sont relativement volumineuses, le temps de communication IPC augmentera également en conséquence.

Je pense que vous maîtrisez la méthode après avoir lu le cas dans cet article. Pour des informations plus intéressantes, veuillez prêter attention aux autres articles connexes sur le site Web chinois de php !

Lecture recommandée :

Comment télécharger des fichiers Excel avec el-upload

Obtenir dynamiquement les octets et les caractères du contenu d'entrée actuel Nombre

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn