2015-08-06 15 views
23

Gearman PHP eklentisi yoluyla büyük yükler gönderdiğimde işleri görevlere aktarmak için yavaş olan Gearman kullanan bir sorunum var. Aslında, o yükü o kadar büyük bulmuyoruz (30MB). Her şey (PHP, Gearman, node) şimdilik yerel olarak çalışıyor, bu yüzden ağ erişimi darboğaz değildir. bir sorun değil bu sonuçta bir şeyler yapacak benim nodejs işçiİstemci büyük yükü gönderdiğinde dişli çark yavaş çalışıyor

ini_set('memory_limit', '1G'); 

$client= new GearmanClient(); 
$client->addServer('127.0.0.1', '4730'); 

$schema = file_get_contents('schema.json'); 
$data = file_get_contents('data.json'); 

$gearmanData = [ 
    'schema' => $schema, 
    'data' => $data 
]; 

echo "Encoding in JSON the payload\n"; 

$gearmanDataString = json_encode($gearmanData, JSON_FORCE_OBJECT); 

echo "Sending job to Gearman\n"; 

// This line takes long to execute... 
$result = $client->doNormal("validateJsonSchema", $gearmanDataString); 

echo "Job finished\n"; 

var_dump($result); 

, ama bu işçi kodunu göstermek için boş:

PHP İşte

PHP istemcisidir

var gearmanode = require('gearmanode'); 

var worker = gearmanode.worker({host: '127.0.0.1' port: 4730}); 

worker.addFunction('validateJsonSchema', function (job) { 
    console.log('I will do something'); 

    job.workComplete('Toasty!'); 
}); 

Çalışanımı arka planda başlatıyorum ve sonra da istemciyi çalıştırıyorum ve $client->doNormal (yalnızca çıktıdan sonra) yaparken 30 saniye boyunca donuyor ng Gearman'a gönderme işi) ve PHP'nin var_dump üzerinden string(7) "Toasty!" çıktısı ile tamamlanır. Yani işe yarıyor, ancak işlenmesi uzun sürüyor.

Ayrıca, yükün boyutunu küçültür (data.json), daha az zaman alır, bu nedenle yük boyutu önemli gibi görünüyor. Bunu PHP göre neredeyse aynı şeyi yapıyor, node.js müşteri kullanma

$worker= new GearmanWorker(); 
$worker->addServer('127.0.0.1', '4730'); 
$worker->addFunction("validateJsonSchema", "validateJsonSchema"); 
while ($worker->work()); 

function validateJsonSchema($job) 
{ 
    return 'ToastyPHP!'; 
} 

GÜNCELLEME

:

aynı sonuçla, PHP aynı işçiyi kod çalıştı çok daha hızlı yürütür (~ 3.5 saniye). PHP sürümünde yanlış bir şey mi yapıyorum yoksa daha hızlı yapmak için bazı yapılandırmalarda eksik miyim?

Benim node.js istemci:

var gearmanode = require('gearmanode'); 
var fs = require('fs'); 

var start = Date.now(); 

var client = gearmanode.client(); 

schema = fs.readFileSync('schema.json', 'utf8'); 
data = fs.readFileSync('data.json', 'utf8'); 

var submitData = JSON.stringify({ "data": data, "schema": schema }); 

// Runs much faster than PHP 
var job = client.submitJob('validateJsonSchema', submitData, {background: false}); 

job.on('complete', function() { 
    console.log('RESULT >>> ' + job.response); 
    client.close(); 

    var end = Date.now(); 

    console.log(end-start + ' milliseconds'); // Always shows around 3500 milliseconds 
}); 

Herhangi ipucu bu neden oluyor? Gearman bu büyüklükteki yükü hallediyor mu? Kitabımda 30MB büyük değil.

+0

Komut dosyanızın nerede uzun sürdüğünü görmek için bazı temel zamanlama hata ayıklamalarını yapardım. – cmorrissey

+0

@cmorrissey Zaten 30 saniyede alırım, eğer yükü yarıya indirirsek, ~ 15 saniye sürer ... bu yüzden yükün büyüklüğüne direkt olarak bağlıdır, ama neden olduğunu anlamıyorum o kadar büyük bir yük o kadar çok değil ki, vites kolu tarafından ele alınacak kadar çok zaman harcanıyor. – MaxiWheat

+0

ama komut dosyasında 30 saniye sürüyor, aslında dişli mi, yoksa json_encode' gibi mi? – cmorrissey

cevap

1

Bu kodun sizin için uygun olup olmadığını kontrol edin, işi tamamlamak için çok az zaman ayırın.

worker.php:

echo "Starting\n"; 
$gmworker = new GearmanWorker(); 

# Add default server (localhost). 
$gmworker->addServer('127.0.0.1', '4730'); 
$gmworker->addFunction("jsonValid", "jsonValid"); 



print "Waiting for job...\n"; 
while ($gmworker->work()) { 
    if ($gmworker->returnCode() != GEARMAN_SUCCESS) { 
     echo "return_code: " . $gmworker->returnCode() . "\n"; 
     break; 
    } 
} 

function jsonValid($job) 
{ 
    return 'ToastyPHP!'; 
} 

Client.php ben olmak addTask ve runTasks yöntemler yerine doNormal.For json verilerini kullandık

ini_set('memory_limit', '1G'); 

$client = new GearmanClient(); 
$client->addServer('127.0.0.1', '4730'); 
$client->setCompleteCallback("complete"); 
$time = time(); 

echo "<pre>Sending job..." . "\n"; 


$schema = file_get_contents('AllSets.json'); 
$data = file_get_contents('AllSets.json'); 


$gearmanData = Array(
    'schema' => $schema, 
    'data' => $data 
); 

$gearmanDataString = json_encode($gearmanData, JSON_FORCE_OBJECT); 

$client->addTask("jsonValid", $gearmanDataString, null, 'Json'); 
$client->runTasks(); 

echo "Job finished\n"; 

$endtime = time(); 
print "Completed in " . ($endtime - $time) . ' seconds' . "\n"; 

function complete($task) 
{ 
    print "Unique : " . $task->unique() . "\n"; 
    print "Data : " . $task->data() . "\n"; 
} 

kullandığım göndermek AllSets.json dosyası http://mtgjson.com/ yaklaşık 30Mb boyutunda (toplam yük), iş 1 sn sonra işlenmiş ve yaklaşık 200 MB bir dosya denedikten sonra 4 saniye sürdü.

İlgili konular