2016-12-30 2 views
1

Ich habe ein NodeJS Programm, das ein Bild aus einem Text in meiner Datenbank erstellt mit ImageMagick. Das Programm wird zu Mittag gegessen von meiner NodeJs ServerNodeJS Fork-Prozess verlangsamt alle anderen gegabelten Prozesse, wenn ich neu starte

import childProcess from 'child_process'; 
let args = [':imageId', '--max_old_space_size=4096']; 
childProcess.fork('createImage.js', args); 

Der Prozess der Erstellung eines Bildes unter Verwendung ist ziemlich langsam kann es für einzelne Bild mit der Größe 114x84cm 5-6min auf meinem lokalen Rechner erfolgt.

Ich werde versuchen zu erklären, was im Programmlebenszyklus passiert.

Also, ich habe Server, der auf Prozess MyServer ausgeführt wird, wenn jemand ein Bild MyServer Forks einen neuen Prozess anfordert.

Der neue Prozess ImageCreator1 hat eine Schleife aus Versprechen und wird warten, bis alle gelöst sind. Jedes Versprechen schafft einen Teil dieses großen Bild ImageMagick

In meiner Tätigkeit Monitor kann ich sehen, dass es einige laufende Prozesse

Process Name | %CPU 
MyServer  - 0.3 
ImageCreator1 - 30.0 
convert  - 0.1 
convert  - 0.1 
convert  - 0.2 
convert  - 0.1 

Auch kann ich sehen, dass ImageCreator1 async 4-5 ImageMagick convert Prozesse laufen Erstellen Sie all diese erforderlichen kleinen Bilder.

Das alles dauert 5 Minuten. um das große Bild zu erstellen.

Also wenn ich zwei ImageCreators starte, wird die Zeit auf 9min erhöht.

Process Name | %CPU 
MyServer  - 0.3 
ImageCreator1 - 30.0 
ImageCreator2 - 40.0 
convert  - 0.1 
convert  - 0.1 
convert  - 0.2 
convert  - 0.1 
convert  - 0.1 
convert  - 0.1 
convert  - 0.2 
convert  - 0.1 

und wenn ich anfangen ImageCreator3 oder ImageCreator4 wird immer langsamer und langsamer. Ich dachte, dass wenn ich einen neuen Prozess beginne und wenn dieser Prozess den Job für 5min beendet. Wenn ich dann fünf Prozesse gleichzeitig starte, muss jeder von ihnen für 5 Minuten fertig sein. aber scheint, dass mit jedem neuen ImageCreator die Zeit für alle erhöht wird.

Ich bin immer noch im Lernstadium mit NodeJs und diesem OS Zeug, also wenn jemand erklären kann, was los ist, wäre großartig.

!!! UPDATE IMAGECREATOR CODE !!!

console.time('imageCreator'); 
process.title = 'imageCreator'+process.argv[2]; 

const fs = require('fs'); 
const gm = require('gm').subClass({imageMagick:true}); 
const Promise = require('bluebird'); 

var images = [], rows = []; 
for(var i = 1; i<=100;i++){ 
    images.push(i); 
} 

for(var i = 1; i<=10;i++){ 

    rows.push(Promise.reduce(images, function(total, image){ 

     return new Promise(function(resolve, reject) { 

      gm('xc:rgb('+(image*2)+','+image+','+(image*2)+')') 
      .in('-units', 'PixelsPerInch') 
      .in('-size', '100x100') 
      .in('-density', 300) 
      .in('-page', '+'+(image-100)*100+'+0') 
      .toBuffer('miff', function(err, stream){ 
        fs.appendFile(__dirname+'/test'+process.argv[2]+'.miff', stream, function(err){ 
         if(err) reject(err); 
         else resolve(image); 
        }); 
      }); 

     }); 

    })); 

} 


Promise.all(rows).then(function() { 
    console.timeEnd('imageCreator'); 
}); 

Also habe ich einige Tests durchgeführt, um herauszufinden, welcher Teil meines Skripts problematisch ist. Hier ist ein Beispiel, was passiert, wenn ich das auf meinem Mac starte. Durch die Art und Weise habe ich ImageMagick neu kompilieren so jetzt habe ich:

Version: ImageMagick 6.9.7-2 Q16 x86_64 2017-01-03 http://www.imagemagick.org 
Copyright: © 1999-2017 ImageMagick Studio LLC 
License: http://www.imagemagick.org/script/license.php 
Features: Cipher DPC Modules 
Delegates (built-in): bzlib freetype jng jpeg ltdl lzma png tiff xml zlib 

Also, wenn ich das Skript oben auf einem Terminal laufen bekomme ich die Zeit wie:

Terminal1 - imageCreator: 7498.438ms - 7.4984380002sec. 

Aber wenn ich versuche, auf zwei Terminals an gleichzeitig:

Terminal1 - imageCreator: 14632.522ms - 14.632522sec. 
Terminal2 - imageCreator: 13734ms - 13.734sec. 

Wie Sie die Zeit sehen kann fast für beide verdoppelt.

Mein Computer hat:

processor:2.7 GHz Intel Core i5 
memory:8 GB 1867 MHz DDR3 

so, was los ist, ich denke, der Widder ist hier beteiligt, aber ich bin nicht sehr gut mit diesen niedrigen Niveau Sachen so, wenn jemand es wäre toll erklären kann. Vielen Dank im Voraus.

+0

Ein Bild zu sagen ist 114cm x 84cm sagt uns nicht viel - bei einer "dpi" von 1 wäre das 9.000 Pixel, aber bei 600 dpi wäre es 3.500.000.000 Pixel. –

+0

Sorry für die späte Antwort, die 'dpi' des Bildes ist 300dpi, aber ist das wirklich wichtig? Lassen Sie uns sagen, wenn ich Prozess laufen lasse und ein Bild mit 72dpi umwandel und während dieser Prozess einen anderen starte, wird die Zeit für beide erhöht. Ich weiß nicht, ob das Problem in ImageMagick oder Nodejs ist, muss noch ein bisschen mehr Tests machen, ich werde versuchen, was @rdegges freigegebenen Link vorschlagen ImageMagick mit --disable-openmp kompilieren und wird mein Nodejs-Programm ohne ImageMagick und zu posten simulieren das Ergebnis. Vielen Dank für Ihren Kommentar. – Alex

+0

Was ich meine ist, ist 114cm x 84cm 45inches x 33 Zoll. So wird Ihr Bild bei 300 dpi 45 * 300 * 33 * 300 Pixel haben, d.h. 133 Megapixel. Wenn es Farbe ist, mit 3 Kanälen (RGB) und 16-Bit/Pixel, müssen Sie das mit 6 multiplizieren, so dass es mindestens 800 MB RAM für jedes Bild benötigt. Vielleicht sollten Sie den Code in 'ImageCreator' anzeigen und die RAM-Limits Ihres Prozesses betrachten, da Sie möglicherweise auf die Festplatte ausgelagert werden. –

Antwort

1

Wie viele CPU-Kerne hat der Computer, auf dem Sie diesen Code ausführen,? Wenn Sie einen neuen Prozess mit child_process erstellen, starten Sie einen neuen Prozess - das bedeutet, dass der OS-Scheduler versucht, den neuen Prozess parallel zu Ihrem übergeordneten Prozess auszuführen - aber erfordert mehrere CPUs.

Wenn Sie nicht mehrere CPUs haben, wird der OS-Scheduler zwischen dem Ausführen Ihres Hauptprozesses und Ihrem Kindprozess wechseln und jeder CPU-Zeit auf derselben CPU geben, wodurch er nicht wirklich ausgeführt wird sie in "parallel", da immer nur eine Anweisung ausgeführt wird.

Eine andere Sache, auf die Sie achten sollten, ist ImageMagick: Ist es sicher, in mehreren Prozessen ausgeführt zu werden?

Ich bin nicht sehr vertraut mit ImageMagick, aber nach this old thread von 2009 (das kann heute sehr unterschiedlich sein), verwendet ImageMagick seine eigene Threading: so führt es gleichzeitig in mehreren Prozessen keine Beschleunigung führen.

Hoffe, dass hilft!

Verwandte Themen