In diesem Artikel wird hauptsächlich vorgestellt, wie Knoten Prozesskommunikation nutzen, um Cluster-Shared-Memory zu realisieren. Der Herausgeber findet es ziemlich gut, daher werde ich es jetzt mit Ihnen teilen und als Referenz geben. Folgen wir dem Herausgeber und schauen wir uns das an. Ich hoffe, es kann allen helfen.
Die Standard-API von Node.js bietet keinen gemeinsam genutzten Prozessspeicher. Durch die Sendemethode der IPC-Schnittstelle und die Überwachung von Nachrichtenereignissen kann jedoch ein Mechanismus für die Zusammenarbeit zwischen mehreren Prozessen durch Kommunikation realisiert werden . Shared Memory betreiben.
##Grundlegende Verwendung von IPC:
// worker进程 发送消息 process.send(‘读取共享内存'); // master进程 接收消息 -> 处理 -> 发送回信 cluster.on('online', function (worker) { // 有worker进程建立,即开始监听message事件 worker.on(‘message', function(data) { // 处理来自worker的请求 // 回传结果 worker.send(‘result') }); });
In Node.js, über send und on The Die durch ('Nachricht', Rückruf) implementierte IPC-Kommunikation verfügt über mehrere Funktionen. Erstens können Master und Worker miteinander kommunizieren, Worker können jedoch nicht direkt miteinander kommunizieren, Worker können jedoch indirekt über die Master-Weiterleitung kommunizieren. Darüber hinaus werden die über die Sendemethode übergebenen Daten vor der Weitergabe von JSON.stringify verarbeitet. Nach dem Empfang werden sie mit JSON.parse analysiert. Daher wird das Buffer-Objekt nach der Übergabe zu einem Array, die Funktion kann jedoch nicht direkt übergeben werden. Andererseits können alle Datentypen außer Puffer und Funktion direkt übertragen werden (was bereits sehr leistungsfähig ist, und Puffer und Funktion können auch mit alternativen Methoden übertragen werden).
Basierend auf den oben genannten Merkmalen können wir eine Lösung für die gemeinsame Nutzung des Speichers über IPC entwerfen:
1 Als Benutzer des gemeinsam genutzten Speichers betreibt der Arbeitsprozess den gemeinsam genutzten Speicher nicht direkt, sondern durch send Die Methode benachrichtigt den Masterprozess, einen Schreib- (Set) oder Lesevorgang (Get) auszuführen.
2. Der Masterprozess initialisiert ein Objektobjekt als gemeinsam genutzten Speicher und liest und schreibt den Schlüsselwert des Objekts gemäß der vom Worker gesendeten Nachricht.
3. Da prozessübergreifende Kommunikation verwendet wird, handelt es sich bei den vom Worker initiierten Set- und Get-Vorgängen um asynchrone Vorgänge. Der Master führt die tatsächlichen Lese- und Schreibvorgänge entsprechend der Anforderung aus und gibt die Ergebnisse dann an den Worker zurück ( d. h. die Ergebnisdaten werden an den Worker gesendet.
##Datenformat
Um asynchrone Lese- und Schreibfunktionen zwischen Prozessen zu realisieren, muss das Format der Kommunikationsdaten standardisiert werden.
Das erste sind die Anforderungsdaten des Arbeiters:
requestMessage = { isSharedMemoryMessage: true, // 表示这是一次共享内存的操作通信 method: ‘set', // or ‘get' 操作的方法 id: cluster.worker.id, // 发起操作的进程(在一些特殊场景下,用于保证master可以回信) uuid: uuid, // 此次操作的(用于注册/调用回调函数) key: key, // 要操作的键 value: value // 键对应的值(写入) }
Nach Erhalt der Daten führt der Master die entsprechenden Vorgänge gemäß der Methode aus und Senden Sie dann gemäß requestMessage.id die Ergebnisdaten an den entsprechenden Mitarbeiter. Das Datenformat lautet wie folgt:
responseMessage = { isSharedMemoryMessage: true, // 标记这是一次共享内存通信 uuid: requestMessage.uuid, // 此次操作的唯一标示 value: value // 返回值。get操作为key对应的值,set操作为成功或失败 }
Die Bedeutung der Standardisierung des Datenformats ist Folgendes Der Master kann die Verarbeitungsergebnisse nach Erhalt der Anfrage an den entsprechenden Mitarbeiter senden, und nach Erhalt des zurückgegebenen Ergebnisses kann der Mitarbeiter den dieser Kommunikation entsprechenden Rückruf aufrufen, um eine Zusammenarbeit zu erreichen.
Nach der Standardisierung des Datenformats besteht der nächste Schritt darin, zwei Codesätze für den Master-Prozess und den Worker-Prozess zu entwerfen, um die Kommunikation zu überwachen und Kommunikationsdaten zu verarbeiten, um die Funktion des gemeinsam genutzten Speichers zu realisieren.
##User-Klasse
Instanzen der User-Klasse arbeiten im Worker-Prozess und sind dafür verantwortlich, Anfragen zum Betrieb des Shared Memory zu senden und auf Antworten vom Master zu warten.
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); };
##Manager-Klasse
Instanzen der Manager-Klasse arbeiten im Master-Prozess und werden zum Initialisieren eines verwendet Objekt als gemeinsam genutzter Speicher und fügt entsprechend der Anforderung der Benutzerinstanz Schlüssel-Wert-Paare im gemeinsam genutzten Speicher hinzu oder liest den Schlüsselwert und sendet dann das Ergebnis zurück.
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]; };
## So verwenden Sie
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] }); } }
Das Obige ist a pass Die durch die IPC-Kommunikation implementierte Multiprozess-Shared-Memory-Funktion. Es ist zu beachten, dass diese Methode Daten direkt im Speicher des Master-Prozesses speichert. Sie können hier einige einfache Eliminierungsstrategien hinzufügen um die Speichernutzung zu optimieren. Wenn außerdem die auf einmal gelesenen und geschriebenen Daten relativ groß sind, erhöht sich auch der Zeitaufwand für die IPC-Kommunikation entsprechend.
Vollständiger Code: https://github.com/x6doooo/sharedmemory
Verwandte Empfehlungen:
Über laravel5.2 und redis_cluster Einführung in die Konfiguration
Detaillierte Einführung in die Shared-Memory-Kommunikation
Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der Knotenimplementierung des Cluster-Shared-Memory. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!