私はnodejsを初めて使いました。データベースからデータを読み込み、計算することができます。これを高速化するために、nodejsクラスタモジュールを使用します。NodeJSクラスタ:マスタのワーカーからのデータを削減する方法は?
が牽引グローバル変数です:(ジャスト減らすマップのように、マップおよびセットを変更するために)pairMapと名前セットは、と私はマスター・プロセスで労働者に仕事を割り当て、そして、彼らはいくつかの計算作業を行う
しかし、pairMapとnameSetは変更されず空ではないようです。(doMasterActionのコード) (別の奇妙なことは、私はデータをコンソールにしていますが、最終的には変更されましたが、マスタープロセスでは空に戻ります)。次のように
データは、(私は主要なアイデアを抽出)である:
const Promise = require('bluebird');
const cluster = require('cluster');
const numCPUs = require('os').cpus().length;
const fs = Promise.promisifyAll(require('fs'))
const utils = {
mergeMap:(source,dest)=>{
for(let [key,value] of Object.entries(source)){
if(!dest.has(key)) dest.set(key,value);
for(let [type,arr] of Object.entries(value)){
const final = new Set([...dest.get[key][type],...arr])
dest.get[key][type] = final;
}
}
}
}
/**
* key: [email protected]||[email protected]
* value: {to: [id1,id2,id3],cc,bcc}
* @param row
* @param map
* @param nameSet
*/
function countLinks(res,map,nameSet) {
nameSet.add(res);
map.set(res,{ 'test': Math.floor(Math.random()*10+1)});
}
class hackingTeamPrepare {
constructor(bulk=100000,total = 1150000){
this.bulk = bulk;
this.count = Math.ceil(total/this.bulk);
const parallelArr = new Array(this.count).fill(0).map((v,i)=> i);
this.jobs = parallelArr.map(v=> 'key'+v);
this.pairMap = new Map();
this.nameSet = new Set();
this.bindThis();
}
bindThis(){
this.doWorkerAction = this.doWorkerAction.bind(this);
this.doMasterAction = this.doMasterAction.bind(this);
}
doMasterAction() {
const workers = [],result = {};
const self = this;
let count = 0,timeout;
for(let i=0;i<numCPUs;i++){
const worker = cluster.fork();
workers[i] = worker;
}
cluster.on('online', (worker) => {
worker.send(self.jobs.shift());
});
cluster.on('exit', function() {
if(self.jobs.length===0) return;
console.log('A worker process died, restarting...');
});
cluster.on('message',function (senderWorkder,info) {
const { workerId,jobIndex } = info;
result[jobIndex] = true;
console.log(`----worker ${workerId} done job: ${jobIndex}----`);
const finish = !self.jobs.length && Object.keys(result).length===self.count;
if(finish){
// -----------------!!here!!--------------------------**
console.log('-------finished-------',self.pairMap,self.nameSet); // Map {}, Set {}
for(let id in cluster.workers){
const curWorker = cluster.workers[id];
curWorker.disconnect();
}
}else{
if(!self.jobs.length) return;
senderWorkder.send(self.jobs.shift());
}
})
}
/**
* {[person1,person2]: {to,cc,bcc}}
*/
doWorkerAction() {
//Process为worker, receive from master
const self = this;
process.on('message',(sql)=>{
const jobPromise = Promise.resolve(sql).then(res => {
countLinks(res,self.pairMap,self.nameSet);
const data = {
workerId: process.pid,
jobIndex: sql,
}
// send to master
process.send(data);
}).catch(err=> {
console.log('-----query error----',err)
});
})
}
readFromPG(){
if(cluster.isMaster){
this.doMasterAction();
}else if (cluster.isWorker){
this.doWorkerAction();
}
}
init(){
this.readFromPG();
}
}
const test = new hackingTeamPrepare(2,10);
test.init();
誰もがこれで私を助けることができますか?
私はマスタープロセスで手動でデータをマージしようとしましたが、worker.sendによって送信されたデータはその中のオブジェクトを無視しているようです。
はい、私はいくつかの時間後にこの溶液に変更し、私はからデータを送信するときことがわかりました作業者をマスターするには、マップまたはセットタイプ(すべてが空の{}に変更されている)を含むべきではありません。理由を理解できません。 – luchen
と私はWebstormでクラスタをデバッグできないようですか? – luchen
私の更新された回答を見る –