SlideShare a Scribd company logo
1 of 156
Work Queues
                      with Gearman and CodeIgniter




CI Conf ’12 - San Francisco


Erik Giberti - JD Supra
Senior Developer
@giberti
Who Am I?
What’s a Work Queue Anyway?
What’s a Work Queue Anyway?

  “A sequence of stored data or programs awaiting
  processing.”
    ~ American Heritage Dictionary
What’s a Work Queue Anyway?

  “A sequence of stored data or programs awaiting
  processing.”
    ~ American Heritage Dictionary



  “[F]or storing messages as they travel between
  computers.”
    ~ Amazon SQS site
What’s a Work Queue Anyway?

  “A sequence of stored data or programs awaiting
  processing.”
    ~ American Heritage Dictionary



  “[F]or storing messages as they travel between
  computers.”
    ~ Amazon SQS site



  “[I]t’s the nervous system for how distributed processing
  communicates”
    ~ Gearman site
The Client Worker Pattern
You might be using them already...
You might be using them already...
<?php

    // filename: do_some_work.php
    $conn = mysqli_connect($server, $user, $pass, $database);

    $select = “SELECT * FROM things WHERE status = ‘not done’ ORDER BY timestamp ASC”;
    $res = $conn->query($select);

    while($work = $res->fetch_assoc()){
!
        //
!       // do work
!       //

        $update = “UPDATE things SET status = ‘done’ WHERE id = {$things[‘id’]}”;
!       $conn->query($update);
    }
It works!
It works!
It’s simple to understand
   Get work -> do work -> done.
It works!
It’s simple to understand
   Get work -> do work -> done.
Can be implemented in other languages
   This job/worker could have been created in Python, Java... whatever!
It works!
It’s simple to understand
   Get work -> do work -> done.
Can be implemented in other languages
   This job/worker could have been created in Python, Java... whatever!
Can be deployed on a different server
   So long as it can talk to the DB
It works!
It’s simple to understand
   Get work -> do work -> done.
Can be implemented in other languages
   This job/worker could have been created in Python, Java... whatever!
Can be deployed on a different server
   So long as it can talk to the DB
It’s persistent
   MySQL is pretty good at keeping data
What’s wrong with that?
What’s wrong with that?
Runs at the frequency that cron fires it off
   Can only run once a minute
What’s wrong with that?
Runs at the frequency that cron fires it off
   Can only run once a minute
Single threaded
   Race condition if you start two overlapping threads
   Mitigation strategies
      Have workers kill themselves every minute
      Use modulus to only do certain jobs in certain threads
      Create different DB pools for each worker
What’s wrong with that?
Runs at the frequency that cron fires it off
   Can only run once a minute
Single threaded
   Race condition if you start two overlapping threads
   Mitigation strategies
      Have workers kill themselves every minute
      Use modulus to only do certain jobs in certain threads
      Create different DB pools for each worker

Hits the database at the predefined frequency
   Wasting DB resources
      Hardest tech in most stacks to scale...
Worker Take 2
Worker Take 2

// filename: do_some_work_two.php
$conn = mysqli_connect($server, $user, $pass, $database);

$select = “SELECT * FROM things WHERE status = ‘not done’ ORDER BY timestamp ASC LIMIT 1”;
$done = false;

while(!$done){
     $res = $conn->query($select);
     if($res->num_rows == 1){
!         $work = $res->fetch_assoc();

!        //
!        // do some stuff
!        //

         $update = “UPDATE things SET status = ‘done’ WHERE id = {$things[‘id’]}”;
!        $conn->query($update);

    } else {
!        sleep(1);
    }
}
A little better?
A little better?
It’s simple to understand
   Get work -> do work -> repeat
A little better?
It’s simple to understand
   Get work -> do work -> repeat
Can be implemented in other languages
   This job/worker could have been created in Python, Java... whatever!
A little better?
It’s simple to understand
   Get work -> do work -> repeat
Can be implemented in other languages
   This job/worker could have been created in Python, Java... whatever!
Can be deployed on a different server
   So long as it can talk to the DB
A little better?
It’s simple to understand
   Get work -> do work -> repeat
Can be implemented in other languages
   This job/worker could have been created in Python, Java... whatever!
Can be deployed on a different server
   So long as it can talk to the DB
It’s persistent
   MySQL is pretty good at keeping data
A little better?
It’s simple to understand
   Get work -> do work -> repeat
Can be implemented in other languages
   This job/worker could have been created in Python, Java... whatever!
Can be deployed on a different server
   So long as it can talk to the DB
It’s persistent
   MySQL is pretty good at keeping data
It’s near real time
   Maximum delay of 1 second between jobs
What’s wrong with that?
What’s wrong with that?
Runs at the frequency of the sleep() delay
   1 second waits are pretty good for offloaded tasks
   Can tweak the timing delay to our level of tolerance
      usleep() for finer control of the interval and less than 1 second intervals are
      possible!
What’s wrong with that?
Runs at the frequency of the sleep() delay
   1 second waits are pretty good for offloaded tasks
   Can tweak the timing delay to our level of tolerance
      usleep() for finer control of the interval and less than 1 second intervals are
      possible!

Less likely to hit a race condition
   Same mitigation strategies apply
What’s wrong with that?
Runs at the frequency of the sleep() delay
   1 second waits are pretty good for offloaded tasks
   Can tweak the timing delay to our level of tolerance
      usleep() for finer control of the interval and less than 1 second intervals are
      possible!

Less likely to hit a race condition
   Same mitigation strategies apply
Hits the database even more!
   MySQL can cache queries pretty well with MyISAM tables...
   ... but your using InnoDB ... right?
- a quick history lesson

Originally developed by Danga Interactive to solve specific issues
in the building and hosting of LiveJournal.com. It was originally
announced in 2005 and was written in Perl.
- a quick history lesson

Originally developed by Danga Interactive to solve specific issues
in the building and hosting of LiveJournal.com. It was originally
announced in 2005 and was written in Perl.

It was ported to C by a number of big companies, like Google
and enjoys wide support from the community; not that much
really goes wrong with it.
- a quick history lesson

Originally developed by Danga Interactive to solve specific issues
in the building and hosting of LiveJournal.com. It was originally
announced in 2005 and was written in Perl.

It was ported to C by a number of big companies, like Google
and enjoys wide support from the community; not that much
really goes wrong with it.

Incidentally, Danga Interactive also created Memcached
- a quick history lesson

Originally developed by Danga Interactive to solve specific issues
in the building and hosting of LiveJournal.com. It was originally
announced in 2005 and was written in Perl.

It was ported to C by a number of big companies, like Google
and enjoys wide support from the community; not that much
really goes wrong with it.

Incidentally, Danga Interactive also created Memcached

Danga Interactive exists no more, it was sold to Six Apart then
LiveJournal was sold to SUP. Six Apart was acquired by SAY
Media.
How Gearman Work Queues Stack Up
How Gearman Work Queues Stack Up
They’re simple to understand
  Get work -> do work -> repeat
How Gearman Work Queues Stack Up
They’re simple to understand
  Get work -> do work -> repeat
They can work across languages
  Jobs are simple strings, so they can pass whatever you want
  Additionally, tools exist for things like MySQL to trigger new jobs
How Gearman Work Queues Stack Up
They’re simple to understand
  Get work -> do work -> repeat
They can work across languages
  Jobs are simple strings, so they can pass whatever you want
  Additionally, tools exist for things like MySQL to trigger new jobs
They can work across servers
  Workers don’t need to live where clients do
How Gearman Work Queues Stack Up
They’re simple to understand
   Get work -> do work -> repeat
They can work across languages
   Jobs are simple strings, so they can pass whatever you want
   Additionally, tools exist for things like MySQL to trigger new jobs
They can work across servers
   Workers don’t need to live where clients do
Persistent
   This requires additional configuration
How Gearman Work Queues Stack Up
They’re simple to understand
   Get work -> do work -> repeat
They can work across languages
   Jobs are simple strings, so they can pass whatever you want
   Additionally, tools exist for things like MySQL to trigger new jobs
They can work across servers
   Workers don’t need to live where clients do
Persistent
   This requires additional configuration
Real Time
How Gearman Work Queues Stack Up
They’re simple to understand
   Get work -> do work -> repeat
They can work across languages
   Jobs are simple strings, so they can pass whatever you want
   Additionally, tools exist for things like MySQL to trigger new jobs
They can work across servers
   Workers don’t need to live where clients do
Persistent
   This requires additional configuration
Real Time
Bonus: Can be asynchronous and synchronous!
But I don’t have this sort of workload...
But I don’t have this sort of workload...
                O’RLY?
Have you seen this pattern?
class Upload extends CI_Controller {

!        function index(){

!        !        $this->load->helper(array(‘url’));
!        !        $ul_config = array( /* ... */ );
!        !        $this->load->library(‘upload’, $ul_config);
!        !        if($this->upload->do_upload()){

!        !        !          $file_info = $this->upload->data();
!        !        !          $img_config = array( /* ... */);
!        !        !          $this->load->library(‘image_lib’, $img_config);
!        !        !          $this->image_lib->resize();

!        !        !          // watermark too?
!        !        !          // write to the database
!        !        !          // move to web accessible directory

!        !        !          redirect(site_url(‘controller/next’));

!        !        } else { /* error handling code */ }
!        }
}
It Works
It Works


Reasonably fast in many circumstances
It Works


Reasonably fast in many circumstances



Most modern servers can handle a few of these calls at the
same time.
But there are limitations...
But there are limitations...
Cameras take big images
   The iPhone 4 is a 5 megapixel camera, most files are about 2Mb
   Entry level DSLR cameras are 14 megapixel with 5Mb files
But there are limitations...
Cameras take big images
   The iPhone 4 is a 5 megapixel camera, most files are about 2Mb
   Entry level DSLR cameras are 14 megapixel with 5Mb files
What about multiple uploads
   Present the form, upload one image, process, repeat?
   Provide a block of upload fields and hope it’s enough?
   Use HTML5 / Flash plugin to send multiple files?
      Hope you have enough CPU & RAM to crunch them in parallel.
But there are limitations...
Cameras take big images
   The iPhone 4 is a 5 megapixel camera, most files are about 2Mb
   Entry level DSLR cameras are 14 megapixel with 5Mb files
What about multiple uploads
   Present the form, upload one image, process, repeat?
   Provide a block of upload fields and hope it’s enough?
   Use HTML5 / Flash plugin to send multiple files?
      Hope you have enough CPU & RAM to crunch them in parallel.

Processing may delay the client longer than the default
timeout.
   What happens to your user’s confidence in your product if things are
   slow?
Okay, I’m interested
 how do I add it?
Gearmand runs as another daemon/service in your stack.
  Can be a different server or run along side everything else
Gearmand runs as another daemon/service in your stack.
   Can be a different server or run along side everything else
Gearman’s only job is to facilitate the handling of these
messages
   It can optionally store them in a persistent store to recover from
   system reboots, service restarts, etc.
Gearmand runs as another daemon/service in your stack.
   Can be a different server or run along side everything else
Gearman’s only job is to facilitate the handling of these
messages
   It can optionally store them in a persistent store to recover from
   system reboots, service restarts, etc.
PHP talks to the Gearmand server via an API extension
   Just like MySQL, Memcached, Postgresql, APC and other tools
Gearmand runs as another daemon/service in your stack.
   Can be a different server or run along side everything else
Gearman’s only job is to facilitate the handling of these
messages
   It can optionally store them in a persistent store to recover from
   system reboots, service restarts, etc.
PHP talks to the Gearmand server via an API extension
   Just like MySQL, Memcached, Postgresql, APC and other tools
Your client and worker code pass messages back and forth
to Gearman
   You’ll use a predefined set of PHP function calls to do this
Getting Gearmand running - installers for many systems
Getting Gearmand running - installers for many systems
Linux: apt-get, yum etc
   sudo apt-get install gearmand
   sudo yum install gearmand
Getting Gearmand running - installers for many systems
Linux: apt-get, yum etc
   sudo apt-get install gearmand
   sudo yum install gearmand
Windows: cygwin ...
Getting Gearmand running - installers for many systems
Linux: apt-get, yum etc
   sudo apt-get install gearmand
   sudo yum install gearmand
Windows: cygwin ...
OS X: ...
   Install a package manager: MacPorts, Homebrew
       sudo port install gearmand
       brew install gearmand

   Add a Virtual Machine that has an installer...
Getting Gearmand running - compile your own
Getting Gearmand running - compile your own
Get your dependencies
   sudo yum install gpp gcc-c++ boost boost-devel libevent libevent-devel libuuid libuuid-
   devel
Getting Gearmand running - compile your own
Get your dependencies
   sudo yum install gpp gcc-c++ boost boost-devel libevent libevent-devel libuuid libuuid-
   devel
Get the latest stable source from gearman.org (Launchpad)
   wget https://launchpad.net/gearmand/trunk/0.34/+download/gearmand-0.34.tar.gz
Getting Gearmand running - compile your own
Get your dependencies
   sudo yum install gpp gcc-c++ boost boost-devel libevent libevent-devel libuuid libuuid-
   devel
Get the latest stable source from gearman.org (Launchpad)
   wget https://launchpad.net/gearmand/trunk/0.34/+download/gearmand-0.34.tar.gz
Unpack, Compile and Install
   tar -xzf gearmand-0.34.tar.gz
   cd gearmand-0.34.tar.gz
   ./configure
   make
   sudo make install
Getting Gearmand running - compile your own
Get your dependencies
   sudo yum install gpp gcc-c++ boost boost-devel libevent libevent-devel libuuid libuuid-
   devel
Get the latest stable source from gearman.org (Launchpad)
   wget https://launchpad.net/gearmand/trunk/0.34/+download/gearmand-0.34.tar.gz
Unpack, Compile and Install
   tar -xzf gearmand-0.34.tar.gz
   cd gearmand-0.34.tar.gz
   ./configure
   make
   sudo make install
Add appropriate system hooks to start the service on reboot
   chkconfig
   systemctl
   ?
Configuring Gearmand
Configuring Gearmand
Default install is pretty good
   Load gearmand as a background service
   No persistence
   Listens on all available interfaces at port 4730
Configuring Gearmand
Default install is pretty good
   Load gearmand as a background service
   No persistence
   Listens on all available interfaces at port 4730
Persistence
   Easily enabled using
       MySQL based databases (Drizzle, MySQL, MariaDB etc)
       Postgresql
       SQL Lite
       Memcached
   Add the appropriate flags to your init script for details on each
       Docs: http://gearman.org/index.php?id=manual:job_server#persistent_queues
       Example: MySQL
              /sbin/gearmand -q libdrizzle --libdrizzle-host=127.0.0.1 --libdrizzle-user=gearman 
                  --libdrizzle-password=secret --libdrizzle-db=queue --libdrizzle-table=gearman 
                  --libdrizzle-mysql
Configuring Gearmand
Defaults to single thread (mostly)
   Some versions default to use more than one...
   Non-blocking I/O which works very fast with a single thread
   To give each of the internals a dedicated thread use
       /sbin/gearmand -d -t 3
   Additional threads are then used for client worker connections
Configuring Gearmand
Defaults to single thread (mostly)
   Some versions default to use more than one...
   Non-blocking I/O which works very fast with a single thread
   To give each of the internals a dedicated thread use
       /sbin/gearmand -d -t 3
   Additional threads are then used for client worker connections
Security
   Lock gearmand to a single IP
       /sbin/gearmand -d -L 127.0.0.1
   Change the port from the default 4730
       /sbin/gearmand -d -L 127.0.0.1 -p 7003
Configuring Gearmand
Defaults to single thread (mostly)
   Some versions default to use more than one...
   Non-blocking I/O which works very fast with a single thread
   To give each of the internals a dedicated thread use
       /sbin/gearmand -d -t 3
   Additional threads are then used for client worker connections
Security
   Lock gearmand to a single IP
       /sbin/gearmand -d -L 127.0.0.1
   Change the port from the default 4730
       /sbin/gearmand -d -L 127.0.0.1 -p 7003

HTTP Access
   Gearmand supports a pluggable interface architecture and can use HTTP for
   communication. Requests are sent using GET and POST data.
Configuring Gearmand for high availability
Configuring Gearmand for high availability
Gearmand doesn’t replicate data
  May be a weak point depending on your use case
Configuring Gearmand for high availability
Gearmand doesn’t replicate data
  May be a weak point depending on your use case
Redundancy without a load balancer
  In the client logic, add multiple servers and let the driver sort it out
  Workers register themselves with each gearmand server
  Done.
Configuring Gearmand for high availability
Gearmand doesn’t replicate data
  May be a weak point depending on your use case
Redundancy without a load balancer
  In the client logic, add multiple servers and let the driver sort it out
  Workers register themselves with each gearmand server
  Done.
Configuring Gearmand for high availability
Easy to load balance
   Put the two servers behind a load balancer
   Each client connects to the load balancer
   Workers register themselves with each gearmand server
   Done.
Configuring Gearmand for high availability
Easy to load balance
   Put the two servers behind a load balancer
   Each client connects to the load balancer
   Workers register themselves with each gearmand server
   Done.
Adding Gearman API to PHP
Adding Gearman API to PHP
Package managers to the rescue again!
  sudo apt-get install php-pecl-gearman
  sudo yum install php-pecl-gearman
Adding Gearman API to PHP
Package managers to the rescue again!
   sudo apt-get install php-pecl-gearman
   sudo yum install php-pecl-gearman
Pecl
   sudo pecl install gearman
   sudo echo “extension=gearman.so” > /etc/php.d/gearman.ini
Adding Gearman API to PHP
Package managers to the rescue again!
   sudo apt-get install php-pecl-gearman
   sudo yum install php-pecl-gearman
Pecl
   sudo pecl install gearman
   sudo echo “extension=gearman.so” > /etc/php.d/gearman.ini
Quick test
   php -i | grep “gearman support”
       gearman support => enabled
Adding Gearman API to PHP
Package managers to the rescue again!
   sudo apt-get install php-pecl-gearman
   sudo yum install php-pecl-gearman
Pecl
   sudo pecl install gearman
   sudo echo “extension=gearman.so” > /etc/php.d/gearman.ini
Quick test
   php -i | grep “gearman support”
       gearman support => enabled

Restart any services with PHP resident in memory
   Apache, Nginx, etc
Can we get to the code already?
Gearman in PHP - The Client
Clients create the jobs and tasks for the workers to do
Gearman in PHP - The Client
Clients create the jobs and tasks for the workers to do
Create a client object
   $gm = new GearmanClient();
Gearman in PHP - The Client
Clients create the jobs and tasks for the workers to do
Create a client object
   $gm = new GearmanClient();
Define the server(s) to use
   $gm->addServer(); // defaults to localhost:4730
Gearman in PHP - The Client
Clients create the jobs and tasks for the workers to do
Create a client object
   $gm = new GearmanClient();
Define the server(s) to use
   $gm->addServer(); // defaults to localhost:4730
Create the job and wait for a response
   $jobdata = “/* any valid string */”;
   do {
          $res = $gm->do(‘image_resize’, $jobdata);
   } while ($gm->returnCode() != GEARMAN_SUCCESS);
Gearman in PHP - The Client
Clients create the jobs and tasks for the workers to do
Create a client object
   $gm = new GearmanClient();
Define the server(s) to use
   $gm->addServer(); // defaults to localhost:4730
Create the job and wait for a response
   $jobdata = “/* any valid string */”;
   do {
           $res = $gm->do(‘image_resize’, $jobdata);
   } while ($gm->returnCode() != GEARMAN_SUCCESS);
Or don’t
   $jobid = $gm->doBackground(‘image_resize’, $jobdata);
Gearman in PHP - The Worker
Workers do the jobs and tasks the clients request
Gearman in PHP - The Worker
Workers do the jobs and tasks the clients request
Define the callbacks
   function callback_resize($job){ /* do stuff */ }
   function callback_watermark($job){ /* do stuff */ }
Gearman in PHP - The Worker
Workers do the jobs and tasks the clients request
Define the callbacks
   function callback_resize($job){ /* do stuff */ }
   function callback_watermark($job){ /* do stuff */ }
The callbacks will fetch the actual message data and do the work
   function callback_resize($job){
       $data = $job->getWorkload();
        /* do stuff */
   }
Gearman in PHP - The Worker
Workers do the jobs and tasks the clients request
Define the callbacks
   function callback_resize($job){ /* do stuff */ }
   function callback_watermark($job){ /* do stuff */ }
The callbacks will fetch the actual message data and do the work
   function callback_resize($job){
       $data = $job->getWorkload();
        /* do stuff */
   }
Create a worker object
   $gm = new GearmanWorker();
Gearman in PHP - The Worker
Workers do the jobs and tasks the clients request
Define the callbacks
   function callback_resize($job){ /* do stuff */ }
   function callback_watermark($job){ /* do stuff */ }
The callbacks will fetch the actual message data and do the work
   function callback_resize($job){
       $data = $job->getWorkload();
        /* do stuff */
   }
Create a worker object
   $gm = new GearmanWorker();
Define the server(s) to respond to
   $gm->addServer(); // defaults to localhost:4730
Gearman in PHP - The Worker
Tell the server which callbacks to use for each task
    $gm->addFunction(‘resize’, ‘callback_resize’);
    $gm->addFunction(‘watermark’, ‘callback_watermark’);
Gearman in PHP - The Worker
Tell the server which callbacks to use for each task
    $gm->addFunction(‘resize’, ‘callback_resize’);
    $gm->addFunction(‘watermark’, ‘callback_watermark’);
Alternately, use an anonymous function
    $gm->addFunction(‘resize’, function($job){
          $data = $job->workload();
           /* do stuff */
    });
Gearman in PHP - The Worker
Tell the server which callbacks to use for each task
    $gm->addFunction(‘resize’, ‘callback_resize’);
    $gm->addFunction(‘watermark’, ‘callback_watermark’);
Alternately, use an anonymous function
    $gm->addFunction(‘resize’, function($job){
          $data = $job->workload();
           /* do stuff */
    });
Callback functions can post status updates on their progress back to the client
    function callback_resize($job){
           /* do stuff */
           $job->sendStatus($numerator, $denominator);
    }
Gearman in PHP - The Worker
Tell the server which callbacks to use for each task
    $gm->addFunction(‘resize’, ‘callback_resize’);
    $gm->addFunction(‘watermark’, ‘callback_watermark’);
Alternately, use an anonymous function
    $gm->addFunction(‘resize’, function($job){
          $data = $job->workload();
           /* do stuff */
    });
Callback functions can post status updates on their progress back to the client
    function callback_resize($job){
           /* do stuff */
           $job->sendStatus($numerator, $denominator);
    }
Wait for work to do
    while($gm->work());
Example Clients in CodeIgniter
class Photos extends CI_Model {

!        public function resize_sync($filename){
!        !        $gm = new GearmanClient();
!        !        $gm->addServer('127.0.0.1', 4730);
!        !        do {
!        !        !         $res = $gm->do('image_resize', $filename);
!        !        !         switch($gm->returnCode()){
!        !        !         !        case GEARMAN_WORK_FAIL:
!        !        !         !        !         return FALSE;
!        !        !         !        case GEARMAN_SUCCESS:
!        !        !         !        !         return TRUE;
!        !        !         }
!        !        } while ($gm->returnCode() != GEARMAN_SUCCESS);!
    !             return TRUE;
!        }

!        public function resize_async($filename){
!        !        $gm = new GearmanClient();
!        !        $gm->addServer('127.0.0.1', 4730);
!        !        $res = $gm->doBackground('image_resize', $filename);
                   if(!$res){ return FALSE; }
    !             return TRUE;
!        }

}
The Callback Handlers
class Photos extends CI_Model {

!        public function resize_sync($filename){ /* ... */ }
!        public function resize_async($filename){ /* ... */ }

!        static public function image_resize($job){
!        !        $filename = $job->workload();
!        !        $CI =& get_instance();
!        !        $config = array(
!        !        !         'source_image' => $filename,
!        !        !         'create_thumbnail' => TRUE,
!        !        !         'maintain_ratio' => TRUE,
!        !        !         'width' => 800,
!        !        !         'height' => 600,
!        !        );
!        !        $CI->image_lib->initialize($config);
!        !        $CI->image_lib->resize();
!        !        $CI->image_lib->clear();
!        !        return true;
!        }
!        static public function image_watermark($job){ /* ... */ }

}
The Worker
class Photos extends CI_Model {

!        public function resize_sync($filename){ /* ... */ }
!        public function resize_async($filename){ /* ... */ }

!        static public function image_resize($job){ /* ... */ }
!        static public function image_watermark($job){ /* ... */ }

!        public function gearman_worker()
!        {!       !
!        !        $gm = new GearmanWorker();
!        !        $gm->addServer('127.0.0.1', 4730);
!        !        $gm->addFunction('image_resize', 'Photos::image_resize');
!        !        $gm->addFunction('image_watermark', 'Photos::image_watermark');
!        !        while($gm->work());
!        }

}
Bringing it all together

class Upload extends CI_Controller {

!        function   index(){
!        !          $this->load->model('photos');
!        !          $this->load->helper(array(‘url’));
!        !          $ul_config = array( /* ... */ );
!        !          $this->load->library(‘upload’, $ul_config);
!        !          if($this->upload->do_upload()){

!        !          !        $file_info = $this->upload->data();
!        !          !        $this->photos->resize_async($file_info['full_path']);

!        !          !        redirect(site_url(‘controller/next’));

!        !          } else { /* error handling code */ }
!        }

!        function worker(){
!        !        $this->load->model('photos');
!        !        $this->photos->gearman_worker();
!        }

}
Running your workers

#!/bin/bash
SCRIPT="index.php upload worker"!    #   this is your CI controller/method
WORKDIR=/var/www/html/ !    !        #   this is your CI app root
MAX_WORKERS=5!     !        !        #   number of workers
PHP=/usr/bin/php! !         !        #   location of PHP on your system
COUNT=0! !         !        !        #   internal use variable

for i in `ps -afe | grep "$SCRIPT" | grep -v grep | awk '{print $2}'`
do
!        COUNT=$((COUNT+1))
done

if test $COUNT -lt $MAX_WORKERS
then
!        cd $WORKDIR
!        $PHP $SCRIPT
else
!        echo There are enough workers running already.
fi
Demo Time: Image Resizing
About the job data
Job data is always a string
About the job data
Job data is always a string
You can serialize data to pass more complex objects
   $data = array(
        ‘filename’ => $filename,
        ‘methods’ => array(‘resize’, ‘watermark’),
        ‘user_id’ => $user_id,
   );
   $jobdata = json_encode($data);
   $gm->doBackground(‘processor’, $jobdata);
About the job data
Job data is always a string
You can serialize data to pass more complex objects
   $data = array(
        ‘filename’ => $filename,
        ‘methods’ => array(‘resize’, ‘watermark’),
        ‘user_id’ => $user_id,
   );
   $jobdata = json_encode($data);
   $gm->doBackground(‘processor’, $jobdata);
And then deserialize it in the worker
   $jobdata = $job->workload();
   $data = json_decode($jobdata, true);
About the job data
In theory, you can pass about 2Gb per message
  Limited by the server protocol which uses a 32 bit integer to define
  message size.
About the job data
In theory, you can pass about 2Gb per message
   Limited by the server protocol which uses a 32 bit integer to define
   message size.
You can pass binary data by encoding it
   $binary_base64 = base64_encode($binary);
About the job data
In theory, you can pass about 2Gb per message
   Limited by the server protocol which uses a 32 bit integer to define
   message size.
You can pass binary data by encoding it
   $binary_base64 = base64_encode($binary);
But use it sparingly
   Any data passed is stored in memory
   and your persistent store (if enabled)
   and is likely on disk already
   Base 64 encoded data is roughly 1 1/2 times the size of the source
   data too
      Compressing the binary data first can help
About the job data
Don’t pass 2Gb objects
About the job data
Don’t pass 2Gb objects
Keep your message data small, less than 64K is perfect
   Amazon’s SQS has a hard limit of 64K
About the job data
Don’t pass 2Gb objects
Keep your message data small, less than 64K is perfect
   Amazon’s SQS has a hard limit of 64K
Pass pointers instead
   Pass paths and filenames instead of files
   Pass cache keys instead of complex class objects
      that won’t deserialize right anyway
About the job data
Don’t pass 2Gb objects
Keep your message data small, less than 64K is perfect
   Amazon’s SQS has a hard limit of 64K
Pass pointers instead
   Pass paths and filenames instead of files
   Pass cache keys instead of complex class objects
      that won’t deserialize right anyway

Gearman is not a data store!
Another Example
Analytics: Problem
We wanted to provide near realtime analytics to our clients
Analytics: Problem
We wanted to provide near realtime analytics to our clients
   We liked the data we could scrape out of Google
Analytics: Problem
We wanted to provide near realtime analytics to our clients
   We liked the data we could scrape out of Google
      Networks Referrers Location
Analytics: Problem
We wanted to provide near realtime analytics to our clients
   We liked the data we could scrape out of Google
      Networks Referrers Location
   so we did... for a while... and it was good!
Analytics: Problem
We wanted to provide near realtime analytics to our clients
   We liked the data we could scrape out of Google
      Networks Referrers Location
   so we did... for a while... and it was good!
   But Google has API limits for getting data out of Analytics
Analytics: Problem
We wanted to provide near realtime analytics to our clients
   We liked the data we could scrape out of Google
      Networks Referrers Location
   so we did... for a while... and it was good!
   But Google has API limits for getting data out of Analytics
      Only a few thousand requests per day
Analytics: Problem
We wanted to provide near realtime analytics to our clients
   We liked the data we could scrape out of Google
      Networks Referrers Location
   so we did... for a while... and it was good!
   But Google has API limits for getting data out of Analytics
      Only a few thousand requests per day
      Batching requests was good - but not ideal
Analytics: Problem
We wanted to provide near realtime analytics to our clients
   We liked the data we could scrape out of Google
      Networks Referrers Location
   so we did... for a while... and it was good!
   But Google has API limits for getting data out of Analytics
      Only a few thousand requests per day
      Batching requests was good - but not ideal
      Data was only monthly, no daily, weekly breakdowns
Analytics: Problem
We wanted to provide near realtime analytics to our clients
   We liked the data we could scrape out of Google
      Networks Referrers Location
   so we did... for a while... and it was good!
   But Google has API limits for getting data out of Analytics
      Only a few thousand requests per day
      Batching requests was good - but not ideal
      Data was only monthly, no daily, weekly breakdowns
      Still ended up taking weeks to gather a full month of data
Analytics: Problem
We wanted to provide near realtime analytics to our clients
   We liked the data we could scrape out of Google
      Networks Referrers Location
   so we did... for a while... and it was good!
   But Google has API limits for getting data out of Analytics
      Only a few thousand requests per day
      Batching requests was good - but not ideal
      Data was only monthly, no daily, weekly breakdowns
      Still ended up taking weeks to gather a full month of data
   We already had scraped a significant amount of Google data so any
   future collection would need to play nice with the existing data
Analytics: Solution
Build our own platform that gathered exactly what we wanted
modeled after Google Analytics
Analytics: Solution
Build our own platform that gathered exactly what we wanted
modeled after Google Analytics
How we did our tracking pixel
Analytics: Solution
Build our own platform that gathered exactly what we wanted
modeled after Google Analytics
How we did our tracking pixel
   The page has a small javascript file included that
Analytics: Solution
Build our own platform that gathered exactly what we wanted
modeled after Google Analytics
How we did our tracking pixel
   The page has a small javascript file included that
   captures the current url, user agent, referrer and so on
Analytics: Solution
Build our own platform that gathered exactly what we wanted
modeled after Google Analytics
How we did our tracking pixel
   The page has a small javascript file included that
   captures the current url, user agent, referrer and so on
   and embeds it as an image tag with a carefully crafted URL for the 1x1
   tracking pixel /statistics/pixel/?ua=Mozilla%2F...
Analytics: Solution
Build our own platform that gathered exactly what we wanted
modeled after Google Analytics
How we did our tracking pixel
   The page has a small javascript file included that
   captures the current url, user agent, referrer and so on
   and embeds it as an image tag with a carefully crafted URL for the 1x1
   tracking pixel /statistics/pixel/?ua=Mozilla%2F...
   The pixel request is handled by CodeIgniter, which returns the image,
Analytics: Solution
Build our own platform that gathered exactly what we wanted
modeled after Google Analytics
How we did our tracking pixel
   The page has a small javascript file included that
   captures the current url, user agent, referrer and so on
   and embeds it as an image tag with a carefully crafted URL for the 1x1
   tracking pixel /statistics/pixel/?ua=Mozilla%2F...
   The pixel request is handled by CodeIgniter, which returns the image,
   but not before we lookup the country, state, city of the originating IP and
   pass that data into Gearman for future processing.
Analytics: Solution
Build our own platform that gathered exactly what we wanted
modeled after Google Analytics
How we did our tracking pixel
   The page has a small javascript file included that
   captures the current url, user agent, referrer and so on
   and embeds it as an image tag with a carefully crafted URL for the 1x1
   tracking pixel /statistics/pixel/?ua=Mozilla%2F...
   The pixel request is handled by CodeIgniter, which returns the image,
   but not before we lookup the country, state, city of the originating IP and
   pass that data into Gearman for future processing.
   The Gearman worker then parses and normalizes the data,
Analytics: Solution
Build our own platform that gathered exactly what we wanted
modeled after Google Analytics
How we did our tracking pixel
   The page has a small javascript file included that
   captures the current url, user agent, referrer and so on
   and embeds it as an image tag with a carefully crafted URL for the 1x1
   tracking pixel /statistics/pixel/?ua=Mozilla%2F...
   The pixel request is handled by CodeIgniter, which returns the image,
   but not before we lookup the country, state, city of the originating IP and
   pass that data into Gearman for future processing.
   The Gearman worker then parses and normalizes the data,
   performs a host lookup on the source IP (which is often very slow) all
   before recording the result in our datastore.
Demo Time: Analytics
Patterns and Recipes
Patterns and Recipes
One to one
  Workers can run in optimized environments for specific tasks
     Example: Using R, Matlab etc to run mathematic analysis and still use CI to for
     the front end
     Example: Run code on a different server to avoid CPU/disk/memory contention
     with Apache etc.
     Example: Run tools on Windows platforms like .NET components for generating
     word files.
Patterns and Recipes
One to one
  Workers can run in optimized environments for specific tasks
     Example: Using R, Matlab etc to run mathematic analysis and still use CI to for
     the front end
     Example: Run code on a different server to avoid CPU/disk/memory contention
     with Apache etc.
     Example: Run tools on Windows platforms like .NET components for generating
     word files.

One to many
  A single client can part out jobs to multiple workers
     Example: Performing TF*IDF analysis on documents to find keywords
     Example: Handling image manipulations in parallel, resizing 2 or 3 new
     thumbnails at a time.
Patterns and Recipes
Many to one
   Multiple clients utilizing a single worker thread
       Share memory across jobs. Arrays are faster than APC, Memcached, MySQL
       Example: Database write buffering (for non critical data only)
       Example: Perform database writes across shards. MySQL UDF inserts a record into
       gearman that’s then re-written out to appropriate user shards
Patterns and Recipes
Many to one
   Multiple clients utilizing a single worker thread
       Share memory across jobs. Arrays are faster than APC, Memcached, MySQL
       Example: Database write buffering (for non critical data only)
       Example: Perform database writes across shards. MySQL UDF inserts a record into
       gearman that’s then re-written out to appropriate user shards

Optimize front end displays
   Example: Pagination optimization
       User requests the first page of data
       Kick off a background task to pre-cache the next page before it’s requested
   Example: Dashboards
       User logs into your site, you fire off background tasks to generate dashboard information
       that user will need
       Workers begin crunching the data and store the results in a cache
       Meanwhile, the user is served a page with spaces allocated for each widget, which are then
       loaded via AJAX
Patterns and Recipes
Delayed/Deferred Processing
  Use whenever tasks would run long or are potentially unreliable
     Preparing images
     Preparing video
     Remote service calls
         Sending content to Twitter, Facebook, LinkedIn...
         Triggering other remote services faxes, emails etc
     Prefetching data
Other Solutions
Other Solutions
Most alternative solutions have APIs for PHP
   Some interface over other protocols like HTTP(s) or memcache,
   which can ease deploying new servers
Other Solutions
Most alternative solutions have APIs for PHP
   Some interface over other protocols like HTTP(s) or memcache,
   which can ease deploying new servers
Alternatives
   Active MQ
   Amazon’s SQS
   Beanstalkd
   Microsoft Message Queuing
   RabbitMQ
   Others - check for activity before adopting
Some helpful tips
Not everything belongs in a work queue
Some helpful tips
Not everything belongs in a work queue
  Queue it if...
Some helpful tips
Not everything belongs in a work queue
  Queue it if...
  the process is intensive on any subsystem, CPU, RAM etc
Some helpful tips
Not everything belongs in a work queue
  Queue it if...
  the process is intensive on any subsystem, CPU, RAM etc
  the process is slow, taking 1/2 second or longer to run, profile your
  app with CodeIgniter’s built-in profiler.
Some helpful tips
Not everything belongs in a work queue
  Queue it if...
  the process is intensive on any subsystem, CPU, RAM etc
  the process is slow, taking 1/2 second or longer to run, profile your
  app with CodeIgniter’s built-in profiler.
  you want the benefit of running in parallel
Some helpful tips
Not everything belongs in a work queue
  Queue it if...
  the process is intensive on any subsystem, CPU, RAM etc
  the process is slow, taking 1/2 second or longer to run, profile your
  app with CodeIgniter’s built-in profiler.
  you want the benefit of running in parallel
Don’t use your database server as your work queue
Some helpful tips
Not everything belongs in a work queue
  Queue it if...
  the process is intensive on any subsystem, CPU, RAM etc
  the process is slow, taking 1/2 second or longer to run, profile your
  app with CodeIgniter’s built-in profiler.
  you want the benefit of running in parallel
Don’t use your database server as your work queue
  It might work short term, but it’s not scaleable.
Some helpful tips
Not everything belongs in a work queue
   Queue it if...
   the process is intensive on any subsystem, CPU, RAM etc
   the process is slow, taking 1/2 second or longer to run, profile your
   app with CodeIgniter’s built-in profiler.
   you want the benefit of running in parallel
Don’t use your database server as your work queue
   It might work short term, but it’s not scaleable.
Persistence comes with a cost
Some helpful tips
Not everything belongs in a work queue
   Queue it if...
   the process is intensive on any subsystem, CPU, RAM etc
   the process is slow, taking 1/2 second or longer to run, profile your
   app with CodeIgniter’s built-in profiler.
   you want the benefit of running in parallel
Don’t use your database server as your work queue
   It might work short term, but it’s not scaleable.
Persistence comes with a cost
   Writes to the datastore are never free and will slow down the queue
Some helpful tips
Not everything belongs in a work queue
   Queue it if...
   the process is intensive on any subsystem, CPU, RAM etc
   the process is slow, taking 1/2 second or longer to run, profile your
   app with CodeIgniter’s built-in profiler.
   you want the benefit of running in parallel
Don’t use your database server as your work queue
   It might work short term, but it’s not scaleable.
Persistence comes with a cost
   Writes to the datastore are never free and will slow down the queue
   Adds an additional layer of stuff to maintain
Questions?
Thank You!
(this slide intentionally left blank)

More Related Content

Viewers also liked

Distributed Queue System using Gearman
Distributed Queue System using GearmanDistributed Queue System using Gearman
Distributed Queue System using GearmanEric Cho
 
Gearman - Job Queue
Gearman - Job QueueGearman - Job Queue
Gearman - Job QueueDiego Lewin
 
Gearman: A Job Server made for Scale
Gearman: A Job Server made for ScaleGearman: A Job Server made for Scale
Gearman: A Job Server made for ScaleMike Willbanks
 
Defcon 22-blake-self-cisc0ninja-dont-ddos-me-bro
Defcon 22-blake-self-cisc0ninja-dont-ddos-me-broDefcon 22-blake-self-cisc0ninja-dont-ddos-me-bro
Defcon 22-blake-self-cisc0ninja-dont-ddos-me-broPriyanka Aash
 
Learn RabbitMQ with Python in 90mins
Learn RabbitMQ with Python in 90minsLearn RabbitMQ with Python in 90mins
Learn RabbitMQ with Python in 90minsLarry Cai
 
Distributed Applications with Perl & Gearman
Distributed Applications with Perl & GearmanDistributed Applications with Perl & Gearman
Distributed Applications with Perl & GearmanIssac Goldstand
 
Gearman and asynchronous processing in PHP applications
Gearman and asynchronous processing in PHP applicationsGearman and asynchronous processing in PHP applications
Gearman and asynchronous processing in PHP applicationsTeamskunkworks
 
Enchanted Objects: The next wave of the web
Enchanted Objects: The next wave of the webEnchanted Objects: The next wave of the web
Enchanted Objects: The next wave of the webDavid Rose
 
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro frameworkKeeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro frameworkJeremy Kendall
 

Viewers also liked (13)

Distributed Queue System using Gearman
Distributed Queue System using GearmanDistributed Queue System using Gearman
Distributed Queue System using Gearman
 
Gearman - Job Queue
Gearman - Job QueueGearman - Job Queue
Gearman - Job Queue
 
Gearman & PHP
Gearman & PHPGearman & PHP
Gearman & PHP
 
Gearman: A Job Server made for Scale
Gearman: A Job Server made for ScaleGearman: A Job Server made for Scale
Gearman: A Job Server made for Scale
 
Defcon 22-blake-self-cisc0ninja-dont-ddos-me-bro
Defcon 22-blake-self-cisc0ninja-dont-ddos-me-broDefcon 22-blake-self-cisc0ninja-dont-ddos-me-bro
Defcon 22-blake-self-cisc0ninja-dont-ddos-me-bro
 
Rails Servers
Rails ServersRails Servers
Rails Servers
 
Gearman
GearmanGearman
Gearman
 
Learn RabbitMQ with Python in 90mins
Learn RabbitMQ with Python in 90minsLearn RabbitMQ with Python in 90mins
Learn RabbitMQ with Python in 90mins
 
Gearman and Perl
Gearman and PerlGearman and Perl
Gearman and Perl
 
Distributed Applications with Perl & Gearman
Distributed Applications with Perl & GearmanDistributed Applications with Perl & Gearman
Distributed Applications with Perl & Gearman
 
Gearman and asynchronous processing in PHP applications
Gearman and asynchronous processing in PHP applicationsGearman and asynchronous processing in PHP applications
Gearman and asynchronous processing in PHP applications
 
Enchanted Objects: The next wave of the web
Enchanted Objects: The next wave of the webEnchanted Objects: The next wave of the web
Enchanted Objects: The next wave of the web
 
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro frameworkKeeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
 

Similar to Gearman and CodeIgniter

Puppet for Sys Admins
Puppet for Sys AdminsPuppet for Sys Admins
Puppet for Sys AdminsPuppet
 
FireWorks workflow software
FireWorks workflow softwareFireWorks workflow software
FireWorks workflow softwareAnubhav Jain
 
RubyEnRails2007 - Dr Nic Williams - Keynote
RubyEnRails2007 - Dr Nic Williams - KeynoteRubyEnRails2007 - Dr Nic Williams - Keynote
RubyEnRails2007 - Dr Nic Williams - KeynoteDr Nic Williams
 
AI&BigData Lab. Александр Конопко "Celos: оркестрирование и тестирование зада...
AI&BigData Lab. Александр Конопко "Celos: оркестрирование и тестирование зада...AI&BigData Lab. Александр Конопко "Celos: оркестрирование и тестирование зада...
AI&BigData Lab. Александр Конопко "Celos: оркестрирование и тестирование зада...GeeksLab Odessa
 
Continuous Delivery: The Dirty Details
Continuous Delivery: The Dirty DetailsContinuous Delivery: The Dirty Details
Continuous Delivery: The Dirty DetailsMike Brittain
 
Capistrano, Puppet, and Chef
Capistrano, Puppet, and ChefCapistrano, Puppet, and Chef
Capistrano, Puppet, and ChefDavid Benjamin
 
DATABASE AUTOMATION with Thousands of database, monitoring and backup
DATABASE AUTOMATION with Thousands of database, monitoring and backupDATABASE AUTOMATION with Thousands of database, monitoring and backup
DATABASE AUTOMATION with Thousands of database, monitoring and backupSaewoong Lee
 
Puppet for dummies - ZendCon 2011 Edition
Puppet for dummies - ZendCon 2011 EditionPuppet for dummies - ZendCon 2011 Edition
Puppet for dummies - ZendCon 2011 EditionJoshua Thijssen
 
Neo4j Stored Procedure Training Part 1
Neo4j Stored Procedure Training Part 1Neo4j Stored Procedure Training Part 1
Neo4j Stored Procedure Training Part 1Max De Marzi
 
Free The Enterprise With Ruby & Master Your Own Domain
Free The Enterprise With Ruby & Master Your Own DomainFree The Enterprise With Ruby & Master Your Own Domain
Free The Enterprise With Ruby & Master Your Own DomainKen Collins
 
Airflow - Insane power in a Tiny Box
Airflow - Insane power in a Tiny BoxAirflow - Insane power in a Tiny Box
Airflow - Insane power in a Tiny BoxDovy Paukstys
 
Pilot Tech Talk #10 — Practical automation by Kamil Cholewiński
Pilot Tech Talk #10 — Practical automation by Kamil CholewińskiPilot Tech Talk #10 — Practical automation by Kamil Cholewiński
Pilot Tech Talk #10 — Practical automation by Kamil CholewińskiPilot
 
Inside Bokete: Web Application with Mojolicious and others
Inside Bokete:  Web Application with Mojolicious and othersInside Bokete:  Web Application with Mojolicious and others
Inside Bokete: Web Application with Mojolicious and othersYusuke Wada
 
IaC and Immutable Infrastructure with Terraform, Сергей Марченко
IaC and Immutable Infrastructure with Terraform, Сергей МарченкоIaC and Immutable Infrastructure with Terraform, Сергей Марченко
IaC and Immutable Infrastructure with Terraform, Сергей МарченкоSigma Software
 
From Zero to Hadoop: a tutorial for getting started writing Hadoop jobs on Am...
From Zero to Hadoop: a tutorial for getting started writing Hadoop jobs on Am...From Zero to Hadoop: a tutorial for getting started writing Hadoop jobs on Am...
From Zero to Hadoop: a tutorial for getting started writing Hadoop jobs on Am...Alexander Dean
 
Catalyst - refactor large apps with it and have fun!
Catalyst - refactor large apps with it and have fun!Catalyst - refactor large apps with it and have fun!
Catalyst - refactor large apps with it and have fun!mold
 
Consistent Development Environment with Vagrant and Chef
Consistent Development Environment with Vagrant and ChefConsistent Development Environment with Vagrant and Chef
Consistent Development Environment with Vagrant and ChefGerald Villorente
 
What we Learned Implementing Puppet at Backstop
What we Learned Implementing Puppet at BackstopWhat we Learned Implementing Puppet at Backstop
What we Learned Implementing Puppet at BackstopPuppet
 
A Tale of Two Workflows - ChefConf 2014
A Tale of Two Workflows - ChefConf 2014A Tale of Two Workflows - ChefConf 2014
A Tale of Two Workflows - ChefConf 2014Pete Cheslock
 
Systems Monitoring with Prometheus (Devops Ireland April 2015)
Systems Monitoring with Prometheus (Devops Ireland April 2015)Systems Monitoring with Prometheus (Devops Ireland April 2015)
Systems Monitoring with Prometheus (Devops Ireland April 2015)Brian Brazil
 

Similar to Gearman and CodeIgniter (20)

Puppet for Sys Admins
Puppet for Sys AdminsPuppet for Sys Admins
Puppet for Sys Admins
 
FireWorks workflow software
FireWorks workflow softwareFireWorks workflow software
FireWorks workflow software
 
RubyEnRails2007 - Dr Nic Williams - Keynote
RubyEnRails2007 - Dr Nic Williams - KeynoteRubyEnRails2007 - Dr Nic Williams - Keynote
RubyEnRails2007 - Dr Nic Williams - Keynote
 
AI&BigData Lab. Александр Конопко "Celos: оркестрирование и тестирование зада...
AI&BigData Lab. Александр Конопко "Celos: оркестрирование и тестирование зада...AI&BigData Lab. Александр Конопко "Celos: оркестрирование и тестирование зада...
AI&BigData Lab. Александр Конопко "Celos: оркестрирование и тестирование зада...
 
Continuous Delivery: The Dirty Details
Continuous Delivery: The Dirty DetailsContinuous Delivery: The Dirty Details
Continuous Delivery: The Dirty Details
 
Capistrano, Puppet, and Chef
Capistrano, Puppet, and ChefCapistrano, Puppet, and Chef
Capistrano, Puppet, and Chef
 
DATABASE AUTOMATION with Thousands of database, monitoring and backup
DATABASE AUTOMATION with Thousands of database, monitoring and backupDATABASE AUTOMATION with Thousands of database, monitoring and backup
DATABASE AUTOMATION with Thousands of database, monitoring and backup
 
Puppet for dummies - ZendCon 2011 Edition
Puppet for dummies - ZendCon 2011 EditionPuppet for dummies - ZendCon 2011 Edition
Puppet for dummies - ZendCon 2011 Edition
 
Neo4j Stored Procedure Training Part 1
Neo4j Stored Procedure Training Part 1Neo4j Stored Procedure Training Part 1
Neo4j Stored Procedure Training Part 1
 
Free The Enterprise With Ruby & Master Your Own Domain
Free The Enterprise With Ruby & Master Your Own DomainFree The Enterprise With Ruby & Master Your Own Domain
Free The Enterprise With Ruby & Master Your Own Domain
 
Airflow - Insane power in a Tiny Box
Airflow - Insane power in a Tiny BoxAirflow - Insane power in a Tiny Box
Airflow - Insane power in a Tiny Box
 
Pilot Tech Talk #10 — Practical automation by Kamil Cholewiński
Pilot Tech Talk #10 — Practical automation by Kamil CholewińskiPilot Tech Talk #10 — Practical automation by Kamil Cholewiński
Pilot Tech Talk #10 — Practical automation by Kamil Cholewiński
 
Inside Bokete: Web Application with Mojolicious and others
Inside Bokete:  Web Application with Mojolicious and othersInside Bokete:  Web Application with Mojolicious and others
Inside Bokete: Web Application with Mojolicious and others
 
IaC and Immutable Infrastructure with Terraform, Сергей Марченко
IaC and Immutable Infrastructure with Terraform, Сергей МарченкоIaC and Immutable Infrastructure with Terraform, Сергей Марченко
IaC and Immutable Infrastructure with Terraform, Сергей Марченко
 
From Zero to Hadoop: a tutorial for getting started writing Hadoop jobs on Am...
From Zero to Hadoop: a tutorial for getting started writing Hadoop jobs on Am...From Zero to Hadoop: a tutorial for getting started writing Hadoop jobs on Am...
From Zero to Hadoop: a tutorial for getting started writing Hadoop jobs on Am...
 
Catalyst - refactor large apps with it and have fun!
Catalyst - refactor large apps with it and have fun!Catalyst - refactor large apps with it and have fun!
Catalyst - refactor large apps with it and have fun!
 
Consistent Development Environment with Vagrant and Chef
Consistent Development Environment with Vagrant and ChefConsistent Development Environment with Vagrant and Chef
Consistent Development Environment with Vagrant and Chef
 
What we Learned Implementing Puppet at Backstop
What we Learned Implementing Puppet at BackstopWhat we Learned Implementing Puppet at Backstop
What we Learned Implementing Puppet at Backstop
 
A Tale of Two Workflows - ChefConf 2014
A Tale of Two Workflows - ChefConf 2014A Tale of Two Workflows - ChefConf 2014
A Tale of Two Workflows - ChefConf 2014
 
Systems Monitoring with Prometheus (Devops Ireland April 2015)
Systems Monitoring with Prometheus (Devops Ireland April 2015)Systems Monitoring with Prometheus (Devops Ireland April 2015)
Systems Monitoring with Prometheus (Devops Ireland April 2015)
 

Recently uploaded

(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...AliaaTarek5
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Scott Andery
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersRaghuram Pandurangan
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Farhan Tariq
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demoHarshalMandlekar2
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
 

Recently uploaded (20)

(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information Developers
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demo
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
 

Gearman and CodeIgniter

  • 1. Work Queues with Gearman and CodeIgniter CI Conf ’12 - San Francisco Erik Giberti - JD Supra Senior Developer @giberti
  • 3. What’s a Work Queue Anyway?
  • 4. What’s a Work Queue Anyway? “A sequence of stored data or programs awaiting processing.” ~ American Heritage Dictionary
  • 5. What’s a Work Queue Anyway? “A sequence of stored data or programs awaiting processing.” ~ American Heritage Dictionary “[F]or storing messages as they travel between computers.” ~ Amazon SQS site
  • 6. What’s a Work Queue Anyway? “A sequence of stored data or programs awaiting processing.” ~ American Heritage Dictionary “[F]or storing messages as they travel between computers.” ~ Amazon SQS site “[I]t’s the nervous system for how distributed processing communicates” ~ Gearman site
  • 8. You might be using them already...
  • 9. You might be using them already... <?php // filename: do_some_work.php $conn = mysqli_connect($server, $user, $pass, $database); $select = “SELECT * FROM things WHERE status = ‘not done’ ORDER BY timestamp ASC”; $res = $conn->query($select); while($work = $res->fetch_assoc()){ ! // ! // do work ! // $update = “UPDATE things SET status = ‘done’ WHERE id = {$things[‘id’]}”; ! $conn->query($update); }
  • 11. It works! It’s simple to understand Get work -> do work -> done.
  • 12. It works! It’s simple to understand Get work -> do work -> done. Can be implemented in other languages This job/worker could have been created in Python, Java... whatever!
  • 13. It works! It’s simple to understand Get work -> do work -> done. Can be implemented in other languages This job/worker could have been created in Python, Java... whatever! Can be deployed on a different server So long as it can talk to the DB
  • 14. It works! It’s simple to understand Get work -> do work -> done. Can be implemented in other languages This job/worker could have been created in Python, Java... whatever! Can be deployed on a different server So long as it can talk to the DB It’s persistent MySQL is pretty good at keeping data
  • 16. What’s wrong with that? Runs at the frequency that cron fires it off Can only run once a minute
  • 17. What’s wrong with that? Runs at the frequency that cron fires it off Can only run once a minute Single threaded Race condition if you start two overlapping threads Mitigation strategies Have workers kill themselves every minute Use modulus to only do certain jobs in certain threads Create different DB pools for each worker
  • 18. What’s wrong with that? Runs at the frequency that cron fires it off Can only run once a minute Single threaded Race condition if you start two overlapping threads Mitigation strategies Have workers kill themselves every minute Use modulus to only do certain jobs in certain threads Create different DB pools for each worker Hits the database at the predefined frequency Wasting DB resources Hardest tech in most stacks to scale...
  • 20. Worker Take 2 // filename: do_some_work_two.php $conn = mysqli_connect($server, $user, $pass, $database); $select = “SELECT * FROM things WHERE status = ‘not done’ ORDER BY timestamp ASC LIMIT 1”; $done = false; while(!$done){ $res = $conn->query($select); if($res->num_rows == 1){ ! $work = $res->fetch_assoc(); ! // ! // do some stuff ! // $update = “UPDATE things SET status = ‘done’ WHERE id = {$things[‘id’]}”; ! $conn->query($update); } else { ! sleep(1); } }
  • 22. A little better? It’s simple to understand Get work -> do work -> repeat
  • 23. A little better? It’s simple to understand Get work -> do work -> repeat Can be implemented in other languages This job/worker could have been created in Python, Java... whatever!
  • 24. A little better? It’s simple to understand Get work -> do work -> repeat Can be implemented in other languages This job/worker could have been created in Python, Java... whatever! Can be deployed on a different server So long as it can talk to the DB
  • 25. A little better? It’s simple to understand Get work -> do work -> repeat Can be implemented in other languages This job/worker could have been created in Python, Java... whatever! Can be deployed on a different server So long as it can talk to the DB It’s persistent MySQL is pretty good at keeping data
  • 26. A little better? It’s simple to understand Get work -> do work -> repeat Can be implemented in other languages This job/worker could have been created in Python, Java... whatever! Can be deployed on a different server So long as it can talk to the DB It’s persistent MySQL is pretty good at keeping data It’s near real time Maximum delay of 1 second between jobs
  • 28. What’s wrong with that? Runs at the frequency of the sleep() delay 1 second waits are pretty good for offloaded tasks Can tweak the timing delay to our level of tolerance usleep() for finer control of the interval and less than 1 second intervals are possible!
  • 29. What’s wrong with that? Runs at the frequency of the sleep() delay 1 second waits are pretty good for offloaded tasks Can tweak the timing delay to our level of tolerance usleep() for finer control of the interval and less than 1 second intervals are possible! Less likely to hit a race condition Same mitigation strategies apply
  • 30. What’s wrong with that? Runs at the frequency of the sleep() delay 1 second waits are pretty good for offloaded tasks Can tweak the timing delay to our level of tolerance usleep() for finer control of the interval and less than 1 second intervals are possible! Less likely to hit a race condition Same mitigation strategies apply Hits the database even more! MySQL can cache queries pretty well with MyISAM tables... ... but your using InnoDB ... right?
  • 31. - a quick history lesson Originally developed by Danga Interactive to solve specific issues in the building and hosting of LiveJournal.com. It was originally announced in 2005 and was written in Perl.
  • 32. - a quick history lesson Originally developed by Danga Interactive to solve specific issues in the building and hosting of LiveJournal.com. It was originally announced in 2005 and was written in Perl. It was ported to C by a number of big companies, like Google and enjoys wide support from the community; not that much really goes wrong with it.
  • 33. - a quick history lesson Originally developed by Danga Interactive to solve specific issues in the building and hosting of LiveJournal.com. It was originally announced in 2005 and was written in Perl. It was ported to C by a number of big companies, like Google and enjoys wide support from the community; not that much really goes wrong with it. Incidentally, Danga Interactive also created Memcached
  • 34. - a quick history lesson Originally developed by Danga Interactive to solve specific issues in the building and hosting of LiveJournal.com. It was originally announced in 2005 and was written in Perl. It was ported to C by a number of big companies, like Google and enjoys wide support from the community; not that much really goes wrong with it. Incidentally, Danga Interactive also created Memcached Danga Interactive exists no more, it was sold to Six Apart then LiveJournal was sold to SUP. Six Apart was acquired by SAY Media.
  • 35. How Gearman Work Queues Stack Up
  • 36. How Gearman Work Queues Stack Up They’re simple to understand Get work -> do work -> repeat
  • 37. How Gearman Work Queues Stack Up They’re simple to understand Get work -> do work -> repeat They can work across languages Jobs are simple strings, so they can pass whatever you want Additionally, tools exist for things like MySQL to trigger new jobs
  • 38. How Gearman Work Queues Stack Up They’re simple to understand Get work -> do work -> repeat They can work across languages Jobs are simple strings, so they can pass whatever you want Additionally, tools exist for things like MySQL to trigger new jobs They can work across servers Workers don’t need to live where clients do
  • 39. How Gearman Work Queues Stack Up They’re simple to understand Get work -> do work -> repeat They can work across languages Jobs are simple strings, so they can pass whatever you want Additionally, tools exist for things like MySQL to trigger new jobs They can work across servers Workers don’t need to live where clients do Persistent This requires additional configuration
  • 40. How Gearman Work Queues Stack Up They’re simple to understand Get work -> do work -> repeat They can work across languages Jobs are simple strings, so they can pass whatever you want Additionally, tools exist for things like MySQL to trigger new jobs They can work across servers Workers don’t need to live where clients do Persistent This requires additional configuration Real Time
  • 41. How Gearman Work Queues Stack Up They’re simple to understand Get work -> do work -> repeat They can work across languages Jobs are simple strings, so they can pass whatever you want Additionally, tools exist for things like MySQL to trigger new jobs They can work across servers Workers don’t need to live where clients do Persistent This requires additional configuration Real Time Bonus: Can be asynchronous and synchronous!
  • 42. But I don’t have this sort of workload...
  • 43. But I don’t have this sort of workload... O’RLY?
  • 44. Have you seen this pattern? class Upload extends CI_Controller { ! function index(){ ! ! $this->load->helper(array(‘url’)); ! ! $ul_config = array( /* ... */ ); ! ! $this->load->library(‘upload’, $ul_config); ! ! if($this->upload->do_upload()){ ! ! ! $file_info = $this->upload->data(); ! ! ! $img_config = array( /* ... */); ! ! ! $this->load->library(‘image_lib’, $img_config); ! ! ! $this->image_lib->resize(); ! ! ! // watermark too? ! ! ! // write to the database ! ! ! // move to web accessible directory ! ! ! redirect(site_url(‘controller/next’)); ! ! } else { /* error handling code */ } ! } }
  • 46. It Works Reasonably fast in many circumstances
  • 47. It Works Reasonably fast in many circumstances Most modern servers can handle a few of these calls at the same time.
  • 48. But there are limitations...
  • 49. But there are limitations... Cameras take big images The iPhone 4 is a 5 megapixel camera, most files are about 2Mb Entry level DSLR cameras are 14 megapixel with 5Mb files
  • 50. But there are limitations... Cameras take big images The iPhone 4 is a 5 megapixel camera, most files are about 2Mb Entry level DSLR cameras are 14 megapixel with 5Mb files What about multiple uploads Present the form, upload one image, process, repeat? Provide a block of upload fields and hope it’s enough? Use HTML5 / Flash plugin to send multiple files? Hope you have enough CPU & RAM to crunch them in parallel.
  • 51. But there are limitations... Cameras take big images The iPhone 4 is a 5 megapixel camera, most files are about 2Mb Entry level DSLR cameras are 14 megapixel with 5Mb files What about multiple uploads Present the form, upload one image, process, repeat? Provide a block of upload fields and hope it’s enough? Use HTML5 / Flash plugin to send multiple files? Hope you have enough CPU & RAM to crunch them in parallel. Processing may delay the client longer than the default timeout. What happens to your user’s confidence in your product if things are slow?
  • 52. Okay, I’m interested how do I add it?
  • 53. Gearmand runs as another daemon/service in your stack. Can be a different server or run along side everything else
  • 54. Gearmand runs as another daemon/service in your stack. Can be a different server or run along side everything else Gearman’s only job is to facilitate the handling of these messages It can optionally store them in a persistent store to recover from system reboots, service restarts, etc.
  • 55. Gearmand runs as another daemon/service in your stack. Can be a different server or run along side everything else Gearman’s only job is to facilitate the handling of these messages It can optionally store them in a persistent store to recover from system reboots, service restarts, etc. PHP talks to the Gearmand server via an API extension Just like MySQL, Memcached, Postgresql, APC and other tools
  • 56. Gearmand runs as another daemon/service in your stack. Can be a different server or run along side everything else Gearman’s only job is to facilitate the handling of these messages It can optionally store them in a persistent store to recover from system reboots, service restarts, etc. PHP talks to the Gearmand server via an API extension Just like MySQL, Memcached, Postgresql, APC and other tools Your client and worker code pass messages back and forth to Gearman You’ll use a predefined set of PHP function calls to do this
  • 57. Getting Gearmand running - installers for many systems
  • 58. Getting Gearmand running - installers for many systems Linux: apt-get, yum etc sudo apt-get install gearmand sudo yum install gearmand
  • 59. Getting Gearmand running - installers for many systems Linux: apt-get, yum etc sudo apt-get install gearmand sudo yum install gearmand Windows: cygwin ...
  • 60. Getting Gearmand running - installers for many systems Linux: apt-get, yum etc sudo apt-get install gearmand sudo yum install gearmand Windows: cygwin ... OS X: ... Install a package manager: MacPorts, Homebrew sudo port install gearmand brew install gearmand Add a Virtual Machine that has an installer...
  • 61. Getting Gearmand running - compile your own
  • 62. Getting Gearmand running - compile your own Get your dependencies sudo yum install gpp gcc-c++ boost boost-devel libevent libevent-devel libuuid libuuid- devel
  • 63. Getting Gearmand running - compile your own Get your dependencies sudo yum install gpp gcc-c++ boost boost-devel libevent libevent-devel libuuid libuuid- devel Get the latest stable source from gearman.org (Launchpad) wget https://launchpad.net/gearmand/trunk/0.34/+download/gearmand-0.34.tar.gz
  • 64. Getting Gearmand running - compile your own Get your dependencies sudo yum install gpp gcc-c++ boost boost-devel libevent libevent-devel libuuid libuuid- devel Get the latest stable source from gearman.org (Launchpad) wget https://launchpad.net/gearmand/trunk/0.34/+download/gearmand-0.34.tar.gz Unpack, Compile and Install tar -xzf gearmand-0.34.tar.gz cd gearmand-0.34.tar.gz ./configure make sudo make install
  • 65. Getting Gearmand running - compile your own Get your dependencies sudo yum install gpp gcc-c++ boost boost-devel libevent libevent-devel libuuid libuuid- devel Get the latest stable source from gearman.org (Launchpad) wget https://launchpad.net/gearmand/trunk/0.34/+download/gearmand-0.34.tar.gz Unpack, Compile and Install tar -xzf gearmand-0.34.tar.gz cd gearmand-0.34.tar.gz ./configure make sudo make install Add appropriate system hooks to start the service on reboot chkconfig systemctl ?
  • 67. Configuring Gearmand Default install is pretty good Load gearmand as a background service No persistence Listens on all available interfaces at port 4730
  • 68. Configuring Gearmand Default install is pretty good Load gearmand as a background service No persistence Listens on all available interfaces at port 4730 Persistence Easily enabled using MySQL based databases (Drizzle, MySQL, MariaDB etc) Postgresql SQL Lite Memcached Add the appropriate flags to your init script for details on each Docs: http://gearman.org/index.php?id=manual:job_server#persistent_queues Example: MySQL /sbin/gearmand -q libdrizzle --libdrizzle-host=127.0.0.1 --libdrizzle-user=gearman --libdrizzle-password=secret --libdrizzle-db=queue --libdrizzle-table=gearman --libdrizzle-mysql
  • 69. Configuring Gearmand Defaults to single thread (mostly) Some versions default to use more than one... Non-blocking I/O which works very fast with a single thread To give each of the internals a dedicated thread use /sbin/gearmand -d -t 3 Additional threads are then used for client worker connections
  • 70. Configuring Gearmand Defaults to single thread (mostly) Some versions default to use more than one... Non-blocking I/O which works very fast with a single thread To give each of the internals a dedicated thread use /sbin/gearmand -d -t 3 Additional threads are then used for client worker connections Security Lock gearmand to a single IP /sbin/gearmand -d -L 127.0.0.1 Change the port from the default 4730 /sbin/gearmand -d -L 127.0.0.1 -p 7003
  • 71. Configuring Gearmand Defaults to single thread (mostly) Some versions default to use more than one... Non-blocking I/O which works very fast with a single thread To give each of the internals a dedicated thread use /sbin/gearmand -d -t 3 Additional threads are then used for client worker connections Security Lock gearmand to a single IP /sbin/gearmand -d -L 127.0.0.1 Change the port from the default 4730 /sbin/gearmand -d -L 127.0.0.1 -p 7003 HTTP Access Gearmand supports a pluggable interface architecture and can use HTTP for communication. Requests are sent using GET and POST data.
  • 72. Configuring Gearmand for high availability
  • 73. Configuring Gearmand for high availability Gearmand doesn’t replicate data May be a weak point depending on your use case
  • 74. Configuring Gearmand for high availability Gearmand doesn’t replicate data May be a weak point depending on your use case Redundancy without a load balancer In the client logic, add multiple servers and let the driver sort it out Workers register themselves with each gearmand server Done.
  • 75. Configuring Gearmand for high availability Gearmand doesn’t replicate data May be a weak point depending on your use case Redundancy without a load balancer In the client logic, add multiple servers and let the driver sort it out Workers register themselves with each gearmand server Done.
  • 76. Configuring Gearmand for high availability Easy to load balance Put the two servers behind a load balancer Each client connects to the load balancer Workers register themselves with each gearmand server Done.
  • 77. Configuring Gearmand for high availability Easy to load balance Put the two servers behind a load balancer Each client connects to the load balancer Workers register themselves with each gearmand server Done.
  • 79. Adding Gearman API to PHP Package managers to the rescue again! sudo apt-get install php-pecl-gearman sudo yum install php-pecl-gearman
  • 80. Adding Gearman API to PHP Package managers to the rescue again! sudo apt-get install php-pecl-gearman sudo yum install php-pecl-gearman Pecl sudo pecl install gearman sudo echo “extension=gearman.so” > /etc/php.d/gearman.ini
  • 81. Adding Gearman API to PHP Package managers to the rescue again! sudo apt-get install php-pecl-gearman sudo yum install php-pecl-gearman Pecl sudo pecl install gearman sudo echo “extension=gearman.so” > /etc/php.d/gearman.ini Quick test php -i | grep “gearman support” gearman support => enabled
  • 82. Adding Gearman API to PHP Package managers to the rescue again! sudo apt-get install php-pecl-gearman sudo yum install php-pecl-gearman Pecl sudo pecl install gearman sudo echo “extension=gearman.so” > /etc/php.d/gearman.ini Quick test php -i | grep “gearman support” gearman support => enabled Restart any services with PHP resident in memory Apache, Nginx, etc
  • 83. Can we get to the code already?
  • 84. Gearman in PHP - The Client Clients create the jobs and tasks for the workers to do
  • 85. Gearman in PHP - The Client Clients create the jobs and tasks for the workers to do Create a client object $gm = new GearmanClient();
  • 86. Gearman in PHP - The Client Clients create the jobs and tasks for the workers to do Create a client object $gm = new GearmanClient(); Define the server(s) to use $gm->addServer(); // defaults to localhost:4730
  • 87. Gearman in PHP - The Client Clients create the jobs and tasks for the workers to do Create a client object $gm = new GearmanClient(); Define the server(s) to use $gm->addServer(); // defaults to localhost:4730 Create the job and wait for a response $jobdata = “/* any valid string */”; do { $res = $gm->do(‘image_resize’, $jobdata); } while ($gm->returnCode() != GEARMAN_SUCCESS);
  • 88. Gearman in PHP - The Client Clients create the jobs and tasks for the workers to do Create a client object $gm = new GearmanClient(); Define the server(s) to use $gm->addServer(); // defaults to localhost:4730 Create the job and wait for a response $jobdata = “/* any valid string */”; do { $res = $gm->do(‘image_resize’, $jobdata); } while ($gm->returnCode() != GEARMAN_SUCCESS); Or don’t $jobid = $gm->doBackground(‘image_resize’, $jobdata);
  • 89. Gearman in PHP - The Worker Workers do the jobs and tasks the clients request
  • 90. Gearman in PHP - The Worker Workers do the jobs and tasks the clients request Define the callbacks function callback_resize($job){ /* do stuff */ } function callback_watermark($job){ /* do stuff */ }
  • 91. Gearman in PHP - The Worker Workers do the jobs and tasks the clients request Define the callbacks function callback_resize($job){ /* do stuff */ } function callback_watermark($job){ /* do stuff */ } The callbacks will fetch the actual message data and do the work function callback_resize($job){ $data = $job->getWorkload(); /* do stuff */ }
  • 92. Gearman in PHP - The Worker Workers do the jobs and tasks the clients request Define the callbacks function callback_resize($job){ /* do stuff */ } function callback_watermark($job){ /* do stuff */ } The callbacks will fetch the actual message data and do the work function callback_resize($job){ $data = $job->getWorkload(); /* do stuff */ } Create a worker object $gm = new GearmanWorker();
  • 93. Gearman in PHP - The Worker Workers do the jobs and tasks the clients request Define the callbacks function callback_resize($job){ /* do stuff */ } function callback_watermark($job){ /* do stuff */ } The callbacks will fetch the actual message data and do the work function callback_resize($job){ $data = $job->getWorkload(); /* do stuff */ } Create a worker object $gm = new GearmanWorker(); Define the server(s) to respond to $gm->addServer(); // defaults to localhost:4730
  • 94. Gearman in PHP - The Worker Tell the server which callbacks to use for each task $gm->addFunction(‘resize’, ‘callback_resize’); $gm->addFunction(‘watermark’, ‘callback_watermark’);
  • 95. Gearman in PHP - The Worker Tell the server which callbacks to use for each task $gm->addFunction(‘resize’, ‘callback_resize’); $gm->addFunction(‘watermark’, ‘callback_watermark’); Alternately, use an anonymous function $gm->addFunction(‘resize’, function($job){ $data = $job->workload(); /* do stuff */ });
  • 96. Gearman in PHP - The Worker Tell the server which callbacks to use for each task $gm->addFunction(‘resize’, ‘callback_resize’); $gm->addFunction(‘watermark’, ‘callback_watermark’); Alternately, use an anonymous function $gm->addFunction(‘resize’, function($job){ $data = $job->workload(); /* do stuff */ }); Callback functions can post status updates on their progress back to the client function callback_resize($job){ /* do stuff */ $job->sendStatus($numerator, $denominator); }
  • 97. Gearman in PHP - The Worker Tell the server which callbacks to use for each task $gm->addFunction(‘resize’, ‘callback_resize’); $gm->addFunction(‘watermark’, ‘callback_watermark’); Alternately, use an anonymous function $gm->addFunction(‘resize’, function($job){ $data = $job->workload(); /* do stuff */ }); Callback functions can post status updates on their progress back to the client function callback_resize($job){ /* do stuff */ $job->sendStatus($numerator, $denominator); } Wait for work to do while($gm->work());
  • 98. Example Clients in CodeIgniter class Photos extends CI_Model { ! public function resize_sync($filename){ ! ! $gm = new GearmanClient(); ! ! $gm->addServer('127.0.0.1', 4730); ! ! do { ! ! ! $res = $gm->do('image_resize', $filename); ! ! ! switch($gm->returnCode()){ ! ! ! ! case GEARMAN_WORK_FAIL: ! ! ! ! ! return FALSE; ! ! ! ! case GEARMAN_SUCCESS: ! ! ! ! ! return TRUE; ! ! ! } ! ! } while ($gm->returnCode() != GEARMAN_SUCCESS);! ! return TRUE; ! } ! public function resize_async($filename){ ! ! $gm = new GearmanClient(); ! ! $gm->addServer('127.0.0.1', 4730); ! ! $res = $gm->doBackground('image_resize', $filename); if(!$res){ return FALSE; } ! return TRUE; ! } }
  • 99. The Callback Handlers class Photos extends CI_Model { ! public function resize_sync($filename){ /* ... */ } ! public function resize_async($filename){ /* ... */ } ! static public function image_resize($job){ ! ! $filename = $job->workload(); ! ! $CI =& get_instance(); ! ! $config = array( ! ! ! 'source_image' => $filename, ! ! ! 'create_thumbnail' => TRUE, ! ! ! 'maintain_ratio' => TRUE, ! ! ! 'width' => 800, ! ! ! 'height' => 600, ! ! ); ! ! $CI->image_lib->initialize($config); ! ! $CI->image_lib->resize(); ! ! $CI->image_lib->clear(); ! ! return true; ! } ! static public function image_watermark($job){ /* ... */ } }
  • 100. The Worker class Photos extends CI_Model { ! public function resize_sync($filename){ /* ... */ } ! public function resize_async($filename){ /* ... */ } ! static public function image_resize($job){ /* ... */ } ! static public function image_watermark($job){ /* ... */ } ! public function gearman_worker() ! {! ! ! ! $gm = new GearmanWorker(); ! ! $gm->addServer('127.0.0.1', 4730); ! ! $gm->addFunction('image_resize', 'Photos::image_resize'); ! ! $gm->addFunction('image_watermark', 'Photos::image_watermark'); ! ! while($gm->work()); ! } }
  • 101. Bringing it all together class Upload extends CI_Controller { ! function index(){ ! ! $this->load->model('photos'); ! ! $this->load->helper(array(‘url’)); ! ! $ul_config = array( /* ... */ ); ! ! $this->load->library(‘upload’, $ul_config); ! ! if($this->upload->do_upload()){ ! ! ! $file_info = $this->upload->data(); ! ! ! $this->photos->resize_async($file_info['full_path']); ! ! ! redirect(site_url(‘controller/next’)); ! ! } else { /* error handling code */ } ! } ! function worker(){ ! ! $this->load->model('photos'); ! ! $this->photos->gearman_worker(); ! } }
  • 102. Running your workers #!/bin/bash SCRIPT="index.php upload worker"! # this is your CI controller/method WORKDIR=/var/www/html/ ! ! # this is your CI app root MAX_WORKERS=5! ! ! # number of workers PHP=/usr/bin/php! ! ! # location of PHP on your system COUNT=0! ! ! ! # internal use variable for i in `ps -afe | grep "$SCRIPT" | grep -v grep | awk '{print $2}'` do ! COUNT=$((COUNT+1)) done if test $COUNT -lt $MAX_WORKERS then ! cd $WORKDIR ! $PHP $SCRIPT else ! echo There are enough workers running already. fi
  • 103. Demo Time: Image Resizing
  • 104. About the job data Job data is always a string
  • 105. About the job data Job data is always a string You can serialize data to pass more complex objects $data = array( ‘filename’ => $filename, ‘methods’ => array(‘resize’, ‘watermark’), ‘user_id’ => $user_id, ); $jobdata = json_encode($data); $gm->doBackground(‘processor’, $jobdata);
  • 106. About the job data Job data is always a string You can serialize data to pass more complex objects $data = array( ‘filename’ => $filename, ‘methods’ => array(‘resize’, ‘watermark’), ‘user_id’ => $user_id, ); $jobdata = json_encode($data); $gm->doBackground(‘processor’, $jobdata); And then deserialize it in the worker $jobdata = $job->workload(); $data = json_decode($jobdata, true);
  • 107. About the job data In theory, you can pass about 2Gb per message Limited by the server protocol which uses a 32 bit integer to define message size.
  • 108. About the job data In theory, you can pass about 2Gb per message Limited by the server protocol which uses a 32 bit integer to define message size. You can pass binary data by encoding it $binary_base64 = base64_encode($binary);
  • 109. About the job data In theory, you can pass about 2Gb per message Limited by the server protocol which uses a 32 bit integer to define message size. You can pass binary data by encoding it $binary_base64 = base64_encode($binary); But use it sparingly Any data passed is stored in memory and your persistent store (if enabled) and is likely on disk already Base 64 encoded data is roughly 1 1/2 times the size of the source data too Compressing the binary data first can help
  • 110. About the job data Don’t pass 2Gb objects
  • 111. About the job data Don’t pass 2Gb objects Keep your message data small, less than 64K is perfect Amazon’s SQS has a hard limit of 64K
  • 112. About the job data Don’t pass 2Gb objects Keep your message data small, less than 64K is perfect Amazon’s SQS has a hard limit of 64K Pass pointers instead Pass paths and filenames instead of files Pass cache keys instead of complex class objects that won’t deserialize right anyway
  • 113. About the job data Don’t pass 2Gb objects Keep your message data small, less than 64K is perfect Amazon’s SQS has a hard limit of 64K Pass pointers instead Pass paths and filenames instead of files Pass cache keys instead of complex class objects that won’t deserialize right anyway Gearman is not a data store!
  • 115. Analytics: Problem We wanted to provide near realtime analytics to our clients
  • 116. Analytics: Problem We wanted to provide near realtime analytics to our clients We liked the data we could scrape out of Google
  • 117. Analytics: Problem We wanted to provide near realtime analytics to our clients We liked the data we could scrape out of Google Networks Referrers Location
  • 118. Analytics: Problem We wanted to provide near realtime analytics to our clients We liked the data we could scrape out of Google Networks Referrers Location so we did... for a while... and it was good!
  • 119. Analytics: Problem We wanted to provide near realtime analytics to our clients We liked the data we could scrape out of Google Networks Referrers Location so we did... for a while... and it was good! But Google has API limits for getting data out of Analytics
  • 120. Analytics: Problem We wanted to provide near realtime analytics to our clients We liked the data we could scrape out of Google Networks Referrers Location so we did... for a while... and it was good! But Google has API limits for getting data out of Analytics Only a few thousand requests per day
  • 121. Analytics: Problem We wanted to provide near realtime analytics to our clients We liked the data we could scrape out of Google Networks Referrers Location so we did... for a while... and it was good! But Google has API limits for getting data out of Analytics Only a few thousand requests per day Batching requests was good - but not ideal
  • 122. Analytics: Problem We wanted to provide near realtime analytics to our clients We liked the data we could scrape out of Google Networks Referrers Location so we did... for a while... and it was good! But Google has API limits for getting data out of Analytics Only a few thousand requests per day Batching requests was good - but not ideal Data was only monthly, no daily, weekly breakdowns
  • 123. Analytics: Problem We wanted to provide near realtime analytics to our clients We liked the data we could scrape out of Google Networks Referrers Location so we did... for a while... and it was good! But Google has API limits for getting data out of Analytics Only a few thousand requests per day Batching requests was good - but not ideal Data was only monthly, no daily, weekly breakdowns Still ended up taking weeks to gather a full month of data
  • 124. Analytics: Problem We wanted to provide near realtime analytics to our clients We liked the data we could scrape out of Google Networks Referrers Location so we did... for a while... and it was good! But Google has API limits for getting data out of Analytics Only a few thousand requests per day Batching requests was good - but not ideal Data was only monthly, no daily, weekly breakdowns Still ended up taking weeks to gather a full month of data We already had scraped a significant amount of Google data so any future collection would need to play nice with the existing data
  • 125. Analytics: Solution Build our own platform that gathered exactly what we wanted modeled after Google Analytics
  • 126. Analytics: Solution Build our own platform that gathered exactly what we wanted modeled after Google Analytics How we did our tracking pixel
  • 127. Analytics: Solution Build our own platform that gathered exactly what we wanted modeled after Google Analytics How we did our tracking pixel The page has a small javascript file included that
  • 128. Analytics: Solution Build our own platform that gathered exactly what we wanted modeled after Google Analytics How we did our tracking pixel The page has a small javascript file included that captures the current url, user agent, referrer and so on
  • 129. Analytics: Solution Build our own platform that gathered exactly what we wanted modeled after Google Analytics How we did our tracking pixel The page has a small javascript file included that captures the current url, user agent, referrer and so on and embeds it as an image tag with a carefully crafted URL for the 1x1 tracking pixel /statistics/pixel/?ua=Mozilla%2F...
  • 130. Analytics: Solution Build our own platform that gathered exactly what we wanted modeled after Google Analytics How we did our tracking pixel The page has a small javascript file included that captures the current url, user agent, referrer and so on and embeds it as an image tag with a carefully crafted URL for the 1x1 tracking pixel /statistics/pixel/?ua=Mozilla%2F... The pixel request is handled by CodeIgniter, which returns the image,
  • 131. Analytics: Solution Build our own platform that gathered exactly what we wanted modeled after Google Analytics How we did our tracking pixel The page has a small javascript file included that captures the current url, user agent, referrer and so on and embeds it as an image tag with a carefully crafted URL for the 1x1 tracking pixel /statistics/pixel/?ua=Mozilla%2F... The pixel request is handled by CodeIgniter, which returns the image, but not before we lookup the country, state, city of the originating IP and pass that data into Gearman for future processing.
  • 132. Analytics: Solution Build our own platform that gathered exactly what we wanted modeled after Google Analytics How we did our tracking pixel The page has a small javascript file included that captures the current url, user agent, referrer and so on and embeds it as an image tag with a carefully crafted URL for the 1x1 tracking pixel /statistics/pixel/?ua=Mozilla%2F... The pixel request is handled by CodeIgniter, which returns the image, but not before we lookup the country, state, city of the originating IP and pass that data into Gearman for future processing. The Gearman worker then parses and normalizes the data,
  • 133. Analytics: Solution Build our own platform that gathered exactly what we wanted modeled after Google Analytics How we did our tracking pixel The page has a small javascript file included that captures the current url, user agent, referrer and so on and embeds it as an image tag with a carefully crafted URL for the 1x1 tracking pixel /statistics/pixel/?ua=Mozilla%2F... The pixel request is handled by CodeIgniter, which returns the image, but not before we lookup the country, state, city of the originating IP and pass that data into Gearman for future processing. The Gearman worker then parses and normalizes the data, performs a host lookup on the source IP (which is often very slow) all before recording the result in our datastore.
  • 136. Patterns and Recipes One to one Workers can run in optimized environments for specific tasks Example: Using R, Matlab etc to run mathematic analysis and still use CI to for the front end Example: Run code on a different server to avoid CPU/disk/memory contention with Apache etc. Example: Run tools on Windows platforms like .NET components for generating word files.
  • 137. Patterns and Recipes One to one Workers can run in optimized environments for specific tasks Example: Using R, Matlab etc to run mathematic analysis and still use CI to for the front end Example: Run code on a different server to avoid CPU/disk/memory contention with Apache etc. Example: Run tools on Windows platforms like .NET components for generating word files. One to many A single client can part out jobs to multiple workers Example: Performing TF*IDF analysis on documents to find keywords Example: Handling image manipulations in parallel, resizing 2 or 3 new thumbnails at a time.
  • 138. Patterns and Recipes Many to one Multiple clients utilizing a single worker thread Share memory across jobs. Arrays are faster than APC, Memcached, MySQL Example: Database write buffering (for non critical data only) Example: Perform database writes across shards. MySQL UDF inserts a record into gearman that’s then re-written out to appropriate user shards
  • 139. Patterns and Recipes Many to one Multiple clients utilizing a single worker thread Share memory across jobs. Arrays are faster than APC, Memcached, MySQL Example: Database write buffering (for non critical data only) Example: Perform database writes across shards. MySQL UDF inserts a record into gearman that’s then re-written out to appropriate user shards Optimize front end displays Example: Pagination optimization User requests the first page of data Kick off a background task to pre-cache the next page before it’s requested Example: Dashboards User logs into your site, you fire off background tasks to generate dashboard information that user will need Workers begin crunching the data and store the results in a cache Meanwhile, the user is served a page with spaces allocated for each widget, which are then loaded via AJAX
  • 140. Patterns and Recipes Delayed/Deferred Processing Use whenever tasks would run long or are potentially unreliable Preparing images Preparing video Remote service calls Sending content to Twitter, Facebook, LinkedIn... Triggering other remote services faxes, emails etc Prefetching data
  • 142. Other Solutions Most alternative solutions have APIs for PHP Some interface over other protocols like HTTP(s) or memcache, which can ease deploying new servers
  • 143. Other Solutions Most alternative solutions have APIs for PHP Some interface over other protocols like HTTP(s) or memcache, which can ease deploying new servers Alternatives Active MQ Amazon’s SQS Beanstalkd Microsoft Message Queuing RabbitMQ Others - check for activity before adopting
  • 144. Some helpful tips Not everything belongs in a work queue
  • 145. Some helpful tips Not everything belongs in a work queue Queue it if...
  • 146. Some helpful tips Not everything belongs in a work queue Queue it if... the process is intensive on any subsystem, CPU, RAM etc
  • 147. Some helpful tips Not everything belongs in a work queue Queue it if... the process is intensive on any subsystem, CPU, RAM etc the process is slow, taking 1/2 second or longer to run, profile your app with CodeIgniter’s built-in profiler.
  • 148. Some helpful tips Not everything belongs in a work queue Queue it if... the process is intensive on any subsystem, CPU, RAM etc the process is slow, taking 1/2 second or longer to run, profile your app with CodeIgniter’s built-in profiler. you want the benefit of running in parallel
  • 149. Some helpful tips Not everything belongs in a work queue Queue it if... the process is intensive on any subsystem, CPU, RAM etc the process is slow, taking 1/2 second or longer to run, profile your app with CodeIgniter’s built-in profiler. you want the benefit of running in parallel Don’t use your database server as your work queue
  • 150. Some helpful tips Not everything belongs in a work queue Queue it if... the process is intensive on any subsystem, CPU, RAM etc the process is slow, taking 1/2 second or longer to run, profile your app with CodeIgniter’s built-in profiler. you want the benefit of running in parallel Don’t use your database server as your work queue It might work short term, but it’s not scaleable.
  • 151. Some helpful tips Not everything belongs in a work queue Queue it if... the process is intensive on any subsystem, CPU, RAM etc the process is slow, taking 1/2 second or longer to run, profile your app with CodeIgniter’s built-in profiler. you want the benefit of running in parallel Don’t use your database server as your work queue It might work short term, but it’s not scaleable. Persistence comes with a cost
  • 152. Some helpful tips Not everything belongs in a work queue Queue it if... the process is intensive on any subsystem, CPU, RAM etc the process is slow, taking 1/2 second or longer to run, profile your app with CodeIgniter’s built-in profiler. you want the benefit of running in parallel Don’t use your database server as your work queue It might work short term, but it’s not scaleable. Persistence comes with a cost Writes to the datastore are never free and will slow down the queue
  • 153. Some helpful tips Not everything belongs in a work queue Queue it if... the process is intensive on any subsystem, CPU, RAM etc the process is slow, taking 1/2 second or longer to run, profile your app with CodeIgniter’s built-in profiler. you want the benefit of running in parallel Don’t use your database server as your work queue It might work short term, but it’s not scaleable. Persistence comes with a cost Writes to the datastore are never free and will slow down the queue Adds an additional layer of stuff to maintain

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n
  67. \n
  68. \n
  69. \n
  70. \n
  71. \n
  72. \n
  73. \n
  74. \n
  75. \n
  76. \n
  77. \n
  78. \n
  79. \n
  80. \n
  81. \n
  82. \n
  83. \n
  84. \n
  85. \n
  86. \n
  87. \n
  88. \n
  89. \n
  90. \n
  91. \n
  92. \n
  93. \n
  94. \n
  95. \n
  96. \n
  97. \n
  98. \n
  99. \n
  100. \n
  101. \n
  102. \n
  103. \n
  104. \n
  105. \n
  106. \n
  107. \n
  108. \n
  109. \n
  110. \n
  111. \n
  112. \n
  113. \n
  114. \n
  115. \n
  116. \n
  117. \n
  118. \n
  119. \n
  120. \n
  121. \n
  122. \n
  123. \n
  124. \n
  125. \n
  126. \n
  127. \n
  128. \n
  129. \n
  130. \n
  131. \n
  132. \n
  133. \n
  134. \n
  135. \n
  136. \n
  137. \n
  138. \n