2013-02-12 49 views
16

似乎所有的節點工作進程都在工作,就好像它正在執行相同應用程序的新副本一樣。但是想保留節點集羣中所有節點工作人員(子進程)共享的變量。有沒有簡單的方法來做到這一點?如何保留共享節點集羣中所有節點進程的變量?

+2

你看過像redis這樣的數據庫嗎?即使有辦法,沒有適當的鎖定機制,這聽起來像一個壞主意。 – 2013-02-12 06:08:00

+0

@Aaron Dufour感謝您的回覆。是。 redis是一種選擇。我也想過了。但是我不能使用數據庫來做到這一點嗎? – 2013-02-12 06:23:29

+1

我不認爲這樣的方法存在。您當然可以想出一些東西,例如使用'process.send'和'worker.send'(請參閱'cluster'文檔),但它既不安全也不快。像Redis這樣的臨時數據存儲絕對是您的最佳選擇。 – 2013-02-12 14:30:37

回答

14

所有工作進程確實是應用程序的新副本。每個工作者都是使用child_process.spawn創建的全功能流程。 所以不,他們不共享變量。這可能是最好的方式。 如果您想在工作進程(通常會話)之間共享信息,您應該查看將這些信息存儲在數據庫中。

如果您準備好一直走節點,您可以使用類似dnode這樣的東西讓您的工作人員向主進程詢問數據。

+0

dnode鏈接轉到'File not found'頁面 – zavg 2015-05-30 22:26:53

+1

謝謝,我現在指向github回購。 – Floby 2015-06-01 10:06:37

+0

我需要將媒體管道(實例化對象)傳遞給我,這是我無法用redis或關鍵值存儲進行的操作: – Antoine 2017-12-24 02:21:23

12

您可以嘗試在主進程和子進程之間進行通信。例如:

腳本test.master.js:

var cluster = require('cluster'); 
var childScript = __dirname + '/test.child.js'; 

cluster.setupMaster({ exec: childScript }); 

proc = cluster.fork(); 
proc.on('message', function(message) { 
    console.log('message from child: ', message); 
    proc.send('Hello from master!'); 
}); 

腳本test.child.js:

console.log('Child initializing..'); 

process.on('message', function(message) { 
    console.log('message from master: ', message); 
}); 

process.send('Hello from Child!'); 
2

我覺得集羣的整體思路是具有可獨立運行的實例不同的cpus。共享內存(一個全局變量),它們都可以訪問和更改引入更多的複雜性(鎖等),並使這些實例相互依賴。

外部數據庫將是一個很好的解決方案,因爲它處理所有數據訪問問題,但它很可能會降低性能。

消息傳遞是一個更好的主意。您可以在集羣中保存var的本地實例。當羣集更新該值時,向其餘部分發送消息並更新該值。這非常棒,因爲它是異步和非阻塞的,但您的價值更新不會立即反映出來。

這個怎麼樣:在數據庫上存儲變量,每次值變化都會通知實例。他們可以將新值存儲在本地變量中,並僅在需要時才撥打db調用

4

我爲它使用了外部memcached或redis服務器。

+1

你能分享一個例子嗎?我打算從memcache中的子項獲取數據集以從master獲取數據集,但不工作 – mithra 2016-01-20 10:26:58

+0

這適合作爲評論而不是作爲答案 – renatoargh 2017-05-08 19:03:35

0

如果您想要以只讀方式分享內容,請查看mmap-object。我將它用於大內存查找表。

剛剛在一臺服務器上檢查,一個346M文件總共佔用了156M的內存(mmap只能訪問內存中的頁面)和mmap對象在44個進程中共享,每個進程的開銷爲3.5M。

因爲它是隻讀的,所以我不必擔心進程間鎖定和可能帶來的混亂。