利用Gearman實現併發查詢(Multi-Query)

這個樣例是想從數據庫查詢出幾個結果集,通常的作法是,一個接一個的發送查詢,而後彙總結果進行輸出。

如下咱們利用Gearman的gearman_client_run_tasks實現併發的查詢,gearman_client_run_tasks接口可以一次性的提交多個任務,而後在callback函數中異步的處理結果。php


PHP的示比例如如下:數據庫

The client:併發

<?php

$client = new GearmanClient();
$client->addServer();

// initialize the results of our 3 "query results" here
$userInfo = $friends = $posts = null;

// This sets up what gearman will callback to as tasks are returned to us.
// The $context helps us know which function is being returned so we can 
// handle it correctly.
$client->setCompleteCallback(function(GearmanTask $task, $context) use (&$userInfo, &$friends, &$posts) {
    switch($context) {
        case 'lookup_user':
            $userInfo = $task->data();
            break;
        case 'baconate':
            $friends = $task->data();
            break;
        case 'get_latest_posts_by':
            $posts = $task->data();
            break;
    }
});

// Here we queue up multiple tasks to be execute in *as much* parallelism as gearmand can give us
$client->addTask('lookup_user', 'joe@joe.com', 'lookup_user');
$client->addTask('baconate', 'joe@joe.com', 'baconate');
$client->addTask('get_latest_posts_by', 'joe@joe.com', 'get_latest_posts_by');

echo "Fetching...\n";
$start = microtime(true);
$client->runTasks();
$totaltime = number_format(microtime(true) - $start, 2);

echo "Got user info in: $totaltime seconds:\n";
var_dump($userInfo, $friends, $posts);


The worker:

<?php

$worker = new GearmanWorker();
$worker->addServer();

$worker->addFunction('lookup_user', function(GearmanJob $job){
    // normally you'd so some very safe type checking and query binding to a database here.
    // ...and we're gonna fake that.
    sleep(3);
    return 'The user requested ('. $job->workload() .') is 7 feet tall and awesome';
});

$worker->addFunction('baconate', function(GearmanJob $job){
    sleep(3);
    return 'The user ('. $job->workload() .') is 1 degree away from Kevin Bacon';
});

$worker->addFunction('get_latest_posts_by', function(GearmanJob $job){
    sleep(3);
    return 'The user ('. $job->workload() .') has no posts, sorry!';
});

while ($worker->work());

執行結果:

Fetching...
Got user info in: 9.00 seconds:
string(59) "The user requested (joe@joe.com) is 7 feet tall and awesome"
string(56) "The user (joe@joe.com) is 1 degree away from Kevin Bacon"
string(43) "The user (joe@joe.com) has no posts, sorry!"</span>

發現仍是用了9S時間,那是因爲僅僅有一個worker,它僅僅能是順序運行。


一塊兒執行三個worker或不少其它,再來試試:異步

Fetching...
Got user info in: 3.00 seconds:
string(59) "The user requested (joe@joe.com) is 7 feet tall and awesome"
string(56) "The user (joe@joe.com) is 1 degree away from Kevin Bacon"
string(43) "The user (joe@joe.com) has no posts, sorry!"</span>


這僅僅是一個並行運行的樣例,實際應用中可以有更好的併發性能。函數

相關文章
相關標籤/搜索