PHP Resque with phpredis

In my quest of speed and performance, I wanted to implement a queue system in my PHP backed-end website, to defer non-essential tasks, such as logging, send notification/email, warming up cache etc …

There’s already some good and popular messaging system like Gearman and rabbitMQ, and many others that’s written for java, ruby etc …

Resque, from the folks at Github, is a Redis-backed library and can do almost the same thing, but it’s written in ruby.

PHPResque to the rescue

PHP-Resque is a php port by Chris Boulton for resque. You just have to install redis on your server, then use php-resque to queue your php jobs. Just start the workers, and they will poll a queue periodically for jobs to execute.

The worker

$queues = 'default'; // Name of the queue
$interval = 5; // Seconds between each polling

$worker = new Resque_Worker($queues);
$worker->work($interval);

A queue in Resque is just a key-value set. The worker will just pop() the default queue, and execute the returned job, until it’s empty.

The job

To add a job in the default queue:


$args = array('user_id' => 25, 'type' => 'registration');
Resque::enqueue('default', 'SendEmail', $args);

So, how is this used ?

Executing a job will instantiate the SendEmail class, and execute the mandatory perform() method. The $args arguments will be available inside the method via $this->args. Obviously, you have to create a class for each job.

class SendEmail
{
    public function setUp()
    {
        // ... Set up environment for this job
    }

    public function perform()
    {
        // Retrieve the user's email in the database
        // Send him an email using the registration template
    }

    public function tearDown()
    {
        // ... Remove environment for this job
    }
}

You can create as many workers as you want, that will be polling a different queue, at a different interval. You can also create workers on different server, and shard redis.

Php-resque also come with utilities like event/hook system, job statuses tracker, and workers stats. See documentation for more details.

Finally, you should not start workers within you php application. Php-resque come with a resque.php file, that you can run to start the worker via CLI

bash -c "QUEUE=default INTERVAL=5 php YOURPATHTOPHPRESQUE/resque.php" >/dev/null 2>&1 &

This will start a new worker after setting the QUEUE and INTERVAL variables. See resque.php code for the other variables that you can/have to set.

Documentation

Note

There’s many API for PHP to communicate with Redis : Redis PHP Bindings, phpredis, Predis, Redisent.
PHP-Resque uses Redisent, that works out of the box without additional steps (beside installing redis itself). It’s convenient, but not as efficient as phpredis, that is an native PHP extension.
If you can compile phpredis for your php installation, I recommend you the phpredis version of phpresque.

PHPResque doesn’t come with an user interface , you should wrap it with your code to extract and display informations like jobs statuses, workers statuses, and to start/stop/restart workers.

I mainly uses PHPresque via a CakePHP plugin, more informations later.

Other alternatives

Celeri, can also use Redis as message broker, though not efficient as if you use the recommended rabbitMQ message broker.