SlideShare a Scribd company logo
1 of 44
Scaling PHP Applications with Redis
Josh Butts
Zendcon 2011

http://joind.in/3783
About Me

• Director of Development at Vertive, LLC


• Zend Certified in PHP 5 and ZF


• Organizer of AustinPHP


• Find me online:


  • Twitter: @jimbojsb


  • Github: jimbojsb
Agenda

• Redis Overview


• Types of keys


• PHP Strategies
What is Redis?

• Redis is an “Advanced” key-value store database


• Backed by VMWare


• Redis works like memcached, but better:


  • Atomic commands & transactions


  • Server-side data structures


  • In-memory + disk persistence
Redis in an in-memory database

• You need as much RAM as you have data


• There are no plans to improve support for “virtual” memory


• Disk persistence is exactly that


• Customize disk writes interval to suit your pain threshold


• Something interesting happens when you run out of memory
How to get Redis

• http://redis.io


• Doesn’t run (well) on Windows


   • There are a few ports out there


• Has virtually no compile dependencies


• Most distros have a package


• Make sure you’re running at least 2.2


   • 2.4.1 became stable 10/17/11
How to explore

• There aren’t any good GUI tools out there


• redis-cli is your friend
A bit about organization

• Redis can have multiple databases


  • Analogous to a MySQL database within a server instance


  • Theoretically, over 1000 databases per server


  • One data file on disk per instance


• Within a database, namespace your keys


  • Ex: myapp:mykey


  • Keep them concise but useful. Keys take memory too!
Types of Keys
String Keys             http://redis.io/commands#string

• Simple key-value


• Memcache equivalent


• Common Commands


  • SET


  • GET


  • INCR


  • STRLEN
Hash Keys                     http://redis.io/commands#hash

• Key + multiple fields / values                  • Common commands

• Like an associative array in PHP                  • HSET

• mykey => [field1 => value1, field2 => value2]     • HGET

• No nesting (unlike PHP)                           • HGETALL


                                                    • HDEL


                                                    • HVALS


                                                    • HKEYS
Hash Keys
Set Keys                            http://redis.io/commands#set

• key + unordered list of strings


• myset => [item2, item5, item1,]


• Common Commands


   • SADD


   • SMEMBERS


   • SISMEMBER


   • SREM
Set Keys
List Keys                        http://redis.io/commands#list

• Like sets, except insertion order matters


• Build queues or stacks


• Optional blocking


• Common commands


  • [B]LPUSH


  • [B]LPOP


  • LLEN
List Keys
Sorted Set Keys

• Like sets, but sorted by a user-provided score value


• Extremely fast access by score or range of scores, because it’s sorted in
  storage


• Common commands


  • ZADD


  • ZRANGE


  • ZREVRANGE
Sorted Set Keys
Other commands that work on all keys

• DEL - delete a key, regardless of type


• KEYS - search for keys (usually with a wildcard)


• EXPIRE / PERSIST - change expiration values for keys
Connecting from PHP
Connecting from PHP

• Several libraries out there


   • Rediska (http://rediska.geometria-lab.net/)


      • PHP 5.2 / ZF 1.x friendly


   • Predis (https://github.com/nrk/predis)


      • The best in my experience


      • Requires PHP 5.3
Predis

• All the examples here assume you’re using Predis


• Connect to a localhost redis: $p = new PredisClient();


• Redis commands implemented as magic methods on Client();


• $p->set($key, $val);


• $val = $p->get($key);
Attribute Display Logic

                                             items_attributes
                         items
                                                id INT(11)

                       id INT(11)             item_id INT(11)

                                          attr_name VARCHAR(32)
                   name VARCHAR(32)
                                          attr_value VARCHAR(32)



                   10k rows               100k rows
• An item, a Dell Latitude Laptop, has:


  • Free Shipping, Financing Available, Expires Soon, etc
Attribute Display Logic

   • Display “Free Shipping” graphic on the item if it has a free
     shipping attribute row




                        50 items per page
Attribute Display - Traditional

  class Item
  {
     public function hasAttribute($name)
     {
       $sql = "SELECT 1
             FROM items_attributes
             WHERE item_id = $this->id
             AND attr_name='$name'
             LIMIT 1";
       $result = $this->pdo->execute($sql);
       return $result != false;
     }
  }
Denormalize data from MySQL to Redis

• Smart caching


• Define a consistent way to represent a relational object in Redis


  • I prefer [object class]:[object id]:[attribute]


  • ex: product:13445:num_comments


  • This prevents data collisions, and makes it easy to work with data on
    the command line
Attribute Display - Redis


class Item
{
   public function hasAttribute($name)
   {
     return $this->redis->sismember(“item:$this->id:attributes”, $name);
   }

    public function addAttribute($name, $value)
    {
      //traditional mysql stuff here still
      $this->redis->sadd('item:45:attributes', $name);
    }
}
Advantages

• The more items you have, the less MySQL will scale this solution for you on
  it’s own


• Frequently updating your items kills the MySQL query cache


• Checking existence of a set member is O(1) time


• On a laptop, I can check roughly 10,000 attributes per second
Session Clustering



      WEB - 1             WEB - 2         WEB - 3

      PHP Sessions       PHP Sessions     PHP Sessions




                     Inconsistent state
Session Clustering



       WEB - 1        WEB - 2        WEB - 3




                       DB - 1

                     PHP Sessions


Slow with many users (never cached), replication lag
Session Clustering



      WEB - 1              WEB - 2        WEB - 3




           REDIS - 1                 DB - 1

            PHP Sessions



   Constant time lookups, in-memory sessions
Job Queues

• Redis lists make great job queues


• Offload your intensive workloads to some other process


• Blocking I/O allows you to easily build long-running daemons
Job Queues

class Queue
{
   protected $name;
   protected $predis;

    public function push(Array $job)
    {
      $this->predis->lpush($this->name, json_encode($job));
    }

    public function pop($block = false)
    {
      $job = null;
      if ($block) {
          $data = $this->predis->brpop($this->name, 0);
          $job = $data[1];
      } else {
          $job = $this->predis->rpop($this->name);
      }
      if ($job) {
          return json_decode($job);
      }
    }
}
Queuing Jobs

$q = new Queue('test_queue');
$form = new My_Zend_Form();
if ($form->isValid($_POST)) {

    $q->push($form->getValues());
    $message = “Thanks for your submission”;

} else {

    $message = “Error - something went wrong”;

}

echo “<h1>$message</h1>”;
Processing Jobs - Crontab style

 function processJob(Array $job)
 {
    //...something really cool here
    // throw an exception on error
 }

 // process all pending jobs
 $q = new Queue(‘test_queue’);
 while ($job = $q->pop()) {
    try {
            processJob($job);
        } catch (Exception $e) {
           Echo “error processing job”;
           $q = new Queue(‘errors’);
           $q->push($job);
        }
 }
Processing Jobs - Worker style

function processJob(Array $job)
{
   //...something really cool here
   // throw an exception on error
}

// keep processing jobs as they become available
$q = new Queue(‘test_queue’);
while ($job = $q->pop(true)) {
   try {
           processJob($job);
       } catch (Exception $e) {
          Echo “error processing job”;
          $q = new Queue(‘errors’);
          $q->push($job);
       }
}
MVC Routing

• Example:


  • Offers.com has about 3900 stores


  • Store pages live at /[store]/
Old Store Routing


 class Store_Route
 {
    public function route($url)
    {
      $sql = “SELECT id, type
                        FROM stores
                        WHERE url=’$url’”;
      $store = $this->pdo->execute($sql);
      //... do logic to determine what action to use based on type ...//
            return array(“module”     => “core”,
                             “controller” => “store”,
                             “action”    => $action);
    }
 }




• And then there’s offers.com/[holiday]/....
New Routing


class Redis_Route
{
   public function route($url)
   {
     $p = $this->predis;
     if ($p->exists($url)) {

          list($module, $controller, $action) = $this->redis->hVals($url);
          return array(“module”    => $module,
                   “controller” => $controller,
                   “action”    => $action);
        }
        return false;
    }
}
Filling in the Redis keys




 class Store
 {
    public function create(Array $data)
    {
           // ... traditional SQL stuff to put store in the database ... //
         $route = array(“module” => “core”,
                           “controller” => “store”,
                           “action” => $data[“type”]);
           $this->predis->hmset($data[“url”], $route);
    }
 }
Advantages

• I can now create offers.com/[anything]/ and route it to the right place, in
  O(1) time


• I’m only adding a few lines of code to my existing models
Questions?
http://joind.in/3783
Vertive is Hiring

• We help people save money


• We’re looking for engineers in Austin, TX to work on:

More Related Content

What's hot

Speed up your Symfony2 application and build awesome features with Redis
Speed up your Symfony2 application and build awesome features with RedisSpeed up your Symfony2 application and build awesome features with Redis
Speed up your Symfony2 application and build awesome features with RedisRicard Clau
 
Introduction to redis - version 2
Introduction to redis - version 2Introduction to redis - version 2
Introduction to redis - version 2Dvir Volk
 
Redis Use Patterns (DevconTLV June 2014)
Redis Use Patterns (DevconTLV June 2014)Redis Use Patterns (DevconTLV June 2014)
Redis Use Patterns (DevconTLV June 2014)Itamar Haber
 
Redis memcached pdf
Redis memcached pdfRedis memcached pdf
Redis memcached pdfErin O'Neill
 
Redis in Practice
Redis in PracticeRedis in Practice
Redis in PracticeNoah Davis
 
An Introduction to REDIS NoSQL database
An Introduction to REDIS NoSQL databaseAn Introduction to REDIS NoSQL database
An Introduction to REDIS NoSQL databaseAli MasudianPour
 
Redis/Lessons learned
Redis/Lessons learnedRedis/Lessons learned
Redis/Lessons learnedTit Petric
 
Boosting Machine Learning with Redis Modules and Spark
Boosting Machine Learning with Redis Modules and SparkBoosting Machine Learning with Redis Modules and Spark
Boosting Machine Learning with Redis Modules and SparkDvir Volk
 
Extend Redis with Modules
Extend Redis with ModulesExtend Redis with Modules
Extend Redis with ModulesItamar Haber
 
Kicking ass with redis
Kicking ass with redisKicking ass with redis
Kicking ass with redisDvir Volk
 
Redis and its many use cases
Redis and its many use casesRedis and its many use cases
Redis and its many use casesChristian Joudrey
 
Nodejs - Should Ruby Developers Care?
Nodejs - Should Ruby Developers Care?Nodejs - Should Ruby Developers Care?
Nodejs - Should Ruby Developers Care?Felix Geisendörfer
 

What's hot (20)

Redis and it's data types
Redis and it's data typesRedis and it's data types
Redis and it's data types
 
Speed up your Symfony2 application and build awesome features with Redis
Speed up your Symfony2 application and build awesome features with RedisSpeed up your Symfony2 application and build awesome features with Redis
Speed up your Symfony2 application and build awesome features with Redis
 
Introduction to redis - version 2
Introduction to redis - version 2Introduction to redis - version 2
Introduction to redis - version 2
 
Redis Use Patterns (DevconTLV June 2014)
Redis Use Patterns (DevconTLV June 2014)Redis Use Patterns (DevconTLV June 2014)
Redis Use Patterns (DevconTLV June 2014)
 
Redis memcached pdf
Redis memcached pdfRedis memcached pdf
Redis memcached pdf
 
Redis introduction
Redis introductionRedis introduction
Redis introduction
 
Redis in Practice
Redis in PracticeRedis in Practice
Redis in Practice
 
An Introduction to REDIS NoSQL database
An Introduction to REDIS NoSQL databaseAn Introduction to REDIS NoSQL database
An Introduction to REDIS NoSQL database
 
Redis/Lessons learned
Redis/Lessons learnedRedis/Lessons learned
Redis/Lessons learned
 
Boosting Machine Learning with Redis Modules and Spark
Boosting Machine Learning with Redis Modules and SparkBoosting Machine Learning with Redis Modules and Spark
Boosting Machine Learning with Redis Modules and Spark
 
Extend Redis with Modules
Extend Redis with ModulesExtend Redis with Modules
Extend Redis with Modules
 
Introduction to Redis
Introduction to RedisIntroduction to Redis
Introduction to Redis
 
Redis basics
Redis basicsRedis basics
Redis basics
 
Kicking ass with redis
Kicking ass with redisKicking ass with redis
Kicking ass with redis
 
Nodejs - A quick tour (v5)
Nodejs - A quick tour (v5)Nodejs - A quick tour (v5)
Nodejs - A quick tour (v5)
 
Redis and its many use cases
Redis and its many use casesRedis and its many use cases
Redis and its many use cases
 
Nodejs - A quick tour (v4)
Nodejs - A quick tour (v4)Nodejs - A quick tour (v4)
Nodejs - A quick tour (v4)
 
Introduction to Redis
Introduction to RedisIntroduction to Redis
Introduction to Redis
 
Nodejs - Should Ruby Developers Care?
Nodejs - Should Ruby Developers Care?Nodejs - Should Ruby Developers Care?
Nodejs - Should Ruby Developers Care?
 
Nodejs - A-quick-tour-v3
Nodejs - A-quick-tour-v3Nodejs - A-quick-tour-v3
Nodejs - A-quick-tour-v3
 

Viewers also liked

How to scale PHP applications
How to scale PHP applicationsHow to scale PHP applications
How to scale PHP applicationsEnrico Zimuel
 
PHP High Availability High Performance
PHP High Availability High PerformancePHP High Availability High Performance
PHP High Availability High PerformanceAmazee Labs
 
(micro)services avec Symfony et Tolerance
(micro)services avec Symfony et Tolerance(micro)services avec Symfony et Tolerance
(micro)services avec Symfony et ToleranceSamuel ROZE
 
Architechture of a social network for 30M users
Architechture of a social network for 30M usersArchitechture of a social network for 30M users
Architechture of a social network for 30M usersFotostrana
 
Slide Seminar PHP Indonesia - NoSQL Redis
Slide Seminar PHP Indonesia - NoSQL RedisSlide Seminar PHP Indonesia - NoSQL Redis
Slide Seminar PHP Indonesia - NoSQL Redisrifqi alfian
 
Creating a Smooth Development Workflow for High-Quality Modular Open-Source P...
Creating a Smooth Development Workflow for High-Quality Modular Open-Source P...Creating a Smooth Development Workflow for High-Quality Modular Open-Source P...
Creating a Smooth Development Workflow for High-Quality Modular Open-Source P...Pantheon
 
Redis Everywhere - Sunshine PHP
Redis Everywhere - Sunshine PHPRedis Everywhere - Sunshine PHP
Redis Everywhere - Sunshine PHPRicard Clau
 
NoSQL in MySQL
NoSQL in MySQLNoSQL in MySQL
NoSQL in MySQLUlf Wendel
 
Beyond relational database - Building high performance websites using Redis a...
Beyond relational database - Building high performance websites using Redis a...Beyond relational database - Building high performance websites using Redis a...
Beyond relational database - Building high performance websites using Redis a...Dinh Pham
 
MOSC2012 - Building High-Performance Web-Application with PHP & MongoDB
MOSC2012 - Building High-Performance Web-Application with PHP & MongoDBMOSC2012 - Building High-Performance Web-Application with PHP & MongoDB
MOSC2012 - Building High-Performance Web-Application with PHP & MongoDBr1dotmy
 
Docker deploy
Docker deployDocker deploy
Docker deployEric Ahn
 
Building Multi-Tenant and SaaS products in PHP - CloudConf 2015
Building Multi-Tenant and SaaS products in PHP - CloudConf 2015Building Multi-Tenant and SaaS products in PHP - CloudConf 2015
Building Multi-Tenant and SaaS products in PHP - CloudConf 2015Innomatic Platform
 
Frontera: open source, large scale web crawling framework
Frontera: open source, large scale web crawling frameworkFrontera: open source, large scale web crawling framework
Frontera: open source, large scale web crawling frameworkScrapinghub
 
Scaling PHP to 40 Million Uniques
Scaling PHP to 40 Million UniquesScaling PHP to 40 Million Uniques
Scaling PHP to 40 Million UniquesJonathan Klein
 
RestMQ - HTTP/Redis based Message Queue
RestMQ - HTTP/Redis based Message QueueRestMQ - HTTP/Redis based Message Queue
RestMQ - HTTP/Redis based Message QueueGleicon Moraes
 
PHP with Service BUS (RabbitMQ/Redis/MongoDB) - IMasters PHP Experience 2016
PHP with Service BUS (RabbitMQ/Redis/MongoDB) - IMasters PHP Experience 2016PHP with Service BUS (RabbitMQ/Redis/MongoDB) - IMasters PHP Experience 2016
PHP with Service BUS (RabbitMQ/Redis/MongoDB) - IMasters PHP Experience 2016Alexandre Brandão Lustosa
 
Redis everywhere - PHP London
Redis everywhere - PHP LondonRedis everywhere - PHP London
Redis everywhere - PHP LondonRicard Clau
 
Magento scalability from the trenches (Meet Magento Sweden 2016)
Magento scalability from the trenches (Meet Magento Sweden 2016)Magento scalability from the trenches (Meet Magento Sweden 2016)
Magento scalability from the trenches (Meet Magento Sweden 2016)Divante
 
Authentication: Cookies vs JWTs and why you’re doing it wrong
Authentication: Cookies vs JWTs and why you’re doing it wrongAuthentication: Cookies vs JWTs and why you’re doing it wrong
Authentication: Cookies vs JWTs and why you’re doing it wrongDerek Perkins
 

Viewers also liked (20)

How to scale PHP applications
How to scale PHP applicationsHow to scale PHP applications
How to scale PHP applications
 
PHP High Availability High Performance
PHP High Availability High PerformancePHP High Availability High Performance
PHP High Availability High Performance
 
(micro)services avec Symfony et Tolerance
(micro)services avec Symfony et Tolerance(micro)services avec Symfony et Tolerance
(micro)services avec Symfony et Tolerance
 
Architechture of a social network for 30M users
Architechture of a social network for 30M usersArchitechture of a social network for 30M users
Architechture of a social network for 30M users
 
Slide Seminar PHP Indonesia - NoSQL Redis
Slide Seminar PHP Indonesia - NoSQL RedisSlide Seminar PHP Indonesia - NoSQL Redis
Slide Seminar PHP Indonesia - NoSQL Redis
 
Creating a Smooth Development Workflow for High-Quality Modular Open-Source P...
Creating a Smooth Development Workflow for High-Quality Modular Open-Source P...Creating a Smooth Development Workflow for High-Quality Modular Open-Source P...
Creating a Smooth Development Workflow for High-Quality Modular Open-Source P...
 
Redis Everywhere - Sunshine PHP
Redis Everywhere - Sunshine PHPRedis Everywhere - Sunshine PHP
Redis Everywhere - Sunshine PHP
 
NoSQL in MySQL
NoSQL in MySQLNoSQL in MySQL
NoSQL in MySQL
 
Beyond relational database - Building high performance websites using Redis a...
Beyond relational database - Building high performance websites using Redis a...Beyond relational database - Building high performance websites using Redis a...
Beyond relational database - Building high performance websites using Redis a...
 
MOSC2012 - Building High-Performance Web-Application with PHP & MongoDB
MOSC2012 - Building High-Performance Web-Application with PHP & MongoDBMOSC2012 - Building High-Performance Web-Application with PHP & MongoDB
MOSC2012 - Building High-Performance Web-Application with PHP & MongoDB
 
Scaling symfony apps
Scaling symfony appsScaling symfony apps
Scaling symfony apps
 
Docker deploy
Docker deployDocker deploy
Docker deploy
 
Building Multi-Tenant and SaaS products in PHP - CloudConf 2015
Building Multi-Tenant and SaaS products in PHP - CloudConf 2015Building Multi-Tenant and SaaS products in PHP - CloudConf 2015
Building Multi-Tenant and SaaS products in PHP - CloudConf 2015
 
Frontera: open source, large scale web crawling framework
Frontera: open source, large scale web crawling frameworkFrontera: open source, large scale web crawling framework
Frontera: open source, large scale web crawling framework
 
Scaling PHP to 40 Million Uniques
Scaling PHP to 40 Million UniquesScaling PHP to 40 Million Uniques
Scaling PHP to 40 Million Uniques
 
RestMQ - HTTP/Redis based Message Queue
RestMQ - HTTP/Redis based Message QueueRestMQ - HTTP/Redis based Message Queue
RestMQ - HTTP/Redis based Message Queue
 
PHP with Service BUS (RabbitMQ/Redis/MongoDB) - IMasters PHP Experience 2016
PHP with Service BUS (RabbitMQ/Redis/MongoDB) - IMasters PHP Experience 2016PHP with Service BUS (RabbitMQ/Redis/MongoDB) - IMasters PHP Experience 2016
PHP with Service BUS (RabbitMQ/Redis/MongoDB) - IMasters PHP Experience 2016
 
Redis everywhere - PHP London
Redis everywhere - PHP LondonRedis everywhere - PHP London
Redis everywhere - PHP London
 
Magento scalability from the trenches (Meet Magento Sweden 2016)
Magento scalability from the trenches (Meet Magento Sweden 2016)Magento scalability from the trenches (Meet Magento Sweden 2016)
Magento scalability from the trenches (Meet Magento Sweden 2016)
 
Authentication: Cookies vs JWTs and why you’re doing it wrong
Authentication: Cookies vs JWTs and why you’re doing it wrongAuthentication: Cookies vs JWTs and why you’re doing it wrong
Authentication: Cookies vs JWTs and why you’re doing it wrong
 

Similar to Scaling php applications with redis

PHP Basics and Demo HackU
PHP Basics and Demo HackUPHP Basics and Demo HackU
PHP Basics and Demo HackUAnshu Prateek
 
Advanced Php - Macq Electronique 2010
Advanced Php - Macq Electronique 2010Advanced Php - Macq Electronique 2010
Advanced Php - Macq Electronique 2010Michelangelo van Dam
 
Redis the better NoSQL
Redis the better NoSQLRedis the better NoSQL
Redis the better NoSQLOpenFest team
 
Supercharging WordPress Development in 2018
Supercharging WordPress Development in 2018Supercharging WordPress Development in 2018
Supercharging WordPress Development in 2018Adam Tomat
 
Performance tuning with zend framework
Performance tuning with zend frameworkPerformance tuning with zend framework
Performance tuning with zend frameworkAlan Seiden
 
Working with databases in Perl
Working with databases in PerlWorking with databases in Perl
Working with databases in PerlLaurent Dami
 
Introducing PHP Data Objects
Introducing PHP Data ObjectsIntroducing PHP Data Objects
Introducing PHP Data Objectswebhostingguy
 
Building Testable PHP Applications
Building Testable PHP ApplicationsBuilding Testable PHP Applications
Building Testable PHP Applicationschartjes
 
Drupal II: The SQL
Drupal II: The SQLDrupal II: The SQL
Drupal II: The SQLddiers
 
Zend Framework 1 + Doctrine 2
Zend Framework 1 + Doctrine 2Zend Framework 1 + Doctrine 2
Zend Framework 1 + Doctrine 2Ralph Schindler
 
Php course-in-navimumbai
Php course-in-navimumbaiPhp course-in-navimumbai
Php course-in-navimumbaivibrantuser
 
Postgres & Redis Sitting in a Tree- Rimas Silkaitis, Heroku
Postgres & Redis Sitting in a Tree- Rimas Silkaitis, HerokuPostgres & Redis Sitting in a Tree- Rimas Silkaitis, Heroku
Postgres & Redis Sitting in a Tree- Rimas Silkaitis, HerokuRedis Labs
 
PHP from soup to nuts Course Deck
PHP from soup to nuts Course DeckPHP from soup to nuts Course Deck
PHP from soup to nuts Course DeckrICh morrow
 
MIND sweeping introduction to PHP
MIND sweeping introduction to PHPMIND sweeping introduction to PHP
MIND sweeping introduction to PHPBUDNET
 

Similar to Scaling php applications with redis (20)

PHP Basics and Demo HackU
PHP Basics and Demo HackUPHP Basics and Demo HackU
PHP Basics and Demo HackU
 
Fatc
FatcFatc
Fatc
 
Advanced Php - Macq Electronique 2010
Advanced Php - Macq Electronique 2010Advanced Php - Macq Electronique 2010
Advanced Php - Macq Electronique 2010
 
Php summary
Php summaryPhp summary
Php summary
 
Redis the better NoSQL
Redis the better NoSQLRedis the better NoSQL
Redis the better NoSQL
 
Php
PhpPhp
Php
 
Supercharging WordPress Development in 2018
Supercharging WordPress Development in 2018Supercharging WordPress Development in 2018
Supercharging WordPress Development in 2018
 
Performance tuning with zend framework
Performance tuning with zend frameworkPerformance tuning with zend framework
Performance tuning with zend framework
 
Working with databases in Perl
Working with databases in PerlWorking with databases in Perl
Working with databases in Perl
 
Top ten-list
Top ten-listTop ten-list
Top ten-list
 
Spl Not A Bridge Too Far phpNW09
Spl Not A Bridge Too Far phpNW09Spl Not A Bridge Too Far phpNW09
Spl Not A Bridge Too Far phpNW09
 
Introducing PHP Data Objects
Introducing PHP Data ObjectsIntroducing PHP Data Objects
Introducing PHP Data Objects
 
Building Testable PHP Applications
Building Testable PHP ApplicationsBuilding Testable PHP Applications
Building Testable PHP Applications
 
Modern php
Modern phpModern php
Modern php
 
Drupal II: The SQL
Drupal II: The SQLDrupal II: The SQL
Drupal II: The SQL
 
Zend Framework 1 + Doctrine 2
Zend Framework 1 + Doctrine 2Zend Framework 1 + Doctrine 2
Zend Framework 1 + Doctrine 2
 
Php course-in-navimumbai
Php course-in-navimumbaiPhp course-in-navimumbai
Php course-in-navimumbai
 
Postgres & Redis Sitting in a Tree- Rimas Silkaitis, Heroku
Postgres & Redis Sitting in a Tree- Rimas Silkaitis, HerokuPostgres & Redis Sitting in a Tree- Rimas Silkaitis, Heroku
Postgres & Redis Sitting in a Tree- Rimas Silkaitis, Heroku
 
PHP from soup to nuts Course Deck
PHP from soup to nuts Course DeckPHP from soup to nuts Course Deck
PHP from soup to nuts Course Deck
 
MIND sweeping introduction to PHP
MIND sweeping introduction to PHPMIND sweeping introduction to PHP
MIND sweeping introduction to PHP
 

More from jimbojsb

Fall 2011 PHP Class - Session 2
Fall 2011 PHP Class - Session 2Fall 2011 PHP Class - Session 2
Fall 2011 PHP Class - Session 2jimbojsb
 
Fall 2011 PHP Class - Session 1
Fall 2011 PHP Class - Session 1Fall 2011 PHP Class - Session 1
Fall 2011 PHP Class - Session 1jimbojsb
 
Austin NoSQL 2011-07-06
Austin NoSQL 2011-07-06Austin NoSQL 2011-07-06
Austin NoSQL 2011-07-06jimbojsb
 
GeekAustin PHP Class - Session 7
GeekAustin PHP Class - Session 7GeekAustin PHP Class - Session 7
GeekAustin PHP Class - Session 7jimbojsb
 
GeekAustin PHP Class - Session 6
GeekAustin PHP Class - Session 6GeekAustin PHP Class - Session 6
GeekAustin PHP Class - Session 6jimbojsb
 
Geek Austin PHP Class - Session 4
Geek Austin PHP Class - Session 4Geek Austin PHP Class - Session 4
Geek Austin PHP Class - Session 4jimbojsb
 
Geek Austin PHP Class - Session 3
Geek Austin PHP Class - Session 3Geek Austin PHP Class - Session 3
Geek Austin PHP Class - Session 3jimbojsb
 
Geek Austin PHP Class - Session 2
Geek Austin PHP Class - Session 2Geek Austin PHP Class - Session 2
Geek Austin PHP Class - Session 2jimbojsb
 
Geek Austin PHP Class - Session 1
Geek Austin PHP Class - Session 1Geek Austin PHP Class - Session 1
Geek Austin PHP Class - Session 1jimbojsb
 

More from jimbojsb (9)

Fall 2011 PHP Class - Session 2
Fall 2011 PHP Class - Session 2Fall 2011 PHP Class - Session 2
Fall 2011 PHP Class - Session 2
 
Fall 2011 PHP Class - Session 1
Fall 2011 PHP Class - Session 1Fall 2011 PHP Class - Session 1
Fall 2011 PHP Class - Session 1
 
Austin NoSQL 2011-07-06
Austin NoSQL 2011-07-06Austin NoSQL 2011-07-06
Austin NoSQL 2011-07-06
 
GeekAustin PHP Class - Session 7
GeekAustin PHP Class - Session 7GeekAustin PHP Class - Session 7
GeekAustin PHP Class - Session 7
 
GeekAustin PHP Class - Session 6
GeekAustin PHP Class - Session 6GeekAustin PHP Class - Session 6
GeekAustin PHP Class - Session 6
 
Geek Austin PHP Class - Session 4
Geek Austin PHP Class - Session 4Geek Austin PHP Class - Session 4
Geek Austin PHP Class - Session 4
 
Geek Austin PHP Class - Session 3
Geek Austin PHP Class - Session 3Geek Austin PHP Class - Session 3
Geek Austin PHP Class - Session 3
 
Geek Austin PHP Class - Session 2
Geek Austin PHP Class - Session 2Geek Austin PHP Class - Session 2
Geek Austin PHP Class - Session 2
 
Geek Austin PHP Class - Session 1
Geek Austin PHP Class - Session 1Geek Austin PHP Class - Session 1
Geek Austin PHP Class - Session 1
 

Recently uploaded

ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Zilliz
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MIND CTI
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businesspanagenda
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdfSandro Moreira
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsNanddeep Nachan
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...apidays
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Bhuvaneswari Subramani
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...Zilliz
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...apidays
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfOrbitshub
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesrafiqahmad00786416
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontologyjohnbeverley2021
 

Recently uploaded (20)

ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 

Scaling php applications with redis

  • 1. Scaling PHP Applications with Redis Josh Butts Zendcon 2011 http://joind.in/3783
  • 2. About Me • Director of Development at Vertive, LLC • Zend Certified in PHP 5 and ZF • Organizer of AustinPHP • Find me online: • Twitter: @jimbojsb • Github: jimbojsb
  • 3. Agenda • Redis Overview • Types of keys • PHP Strategies
  • 4. What is Redis? • Redis is an “Advanced” key-value store database • Backed by VMWare • Redis works like memcached, but better: • Atomic commands & transactions • Server-side data structures • In-memory + disk persistence
  • 5. Redis in an in-memory database • You need as much RAM as you have data • There are no plans to improve support for “virtual” memory • Disk persistence is exactly that • Customize disk writes interval to suit your pain threshold • Something interesting happens when you run out of memory
  • 6. How to get Redis • http://redis.io • Doesn’t run (well) on Windows • There are a few ports out there • Has virtually no compile dependencies • Most distros have a package • Make sure you’re running at least 2.2 • 2.4.1 became stable 10/17/11
  • 7. How to explore • There aren’t any good GUI tools out there • redis-cli is your friend
  • 8. A bit about organization • Redis can have multiple databases • Analogous to a MySQL database within a server instance • Theoretically, over 1000 databases per server • One data file on disk per instance • Within a database, namespace your keys • Ex: myapp:mykey • Keep them concise but useful. Keys take memory too!
  • 10. String Keys http://redis.io/commands#string • Simple key-value • Memcache equivalent • Common Commands • SET • GET • INCR • STRLEN
  • 11. Hash Keys http://redis.io/commands#hash • Key + multiple fields / values • Common commands • Like an associative array in PHP • HSET • mykey => [field1 => value1, field2 => value2] • HGET • No nesting (unlike PHP) • HGETALL • HDEL • HVALS • HKEYS
  • 13. Set Keys http://redis.io/commands#set • key + unordered list of strings • myset => [item2, item5, item1,] • Common Commands • SADD • SMEMBERS • SISMEMBER • SREM
  • 15. List Keys http://redis.io/commands#list • Like sets, except insertion order matters • Build queues or stacks • Optional blocking • Common commands • [B]LPUSH • [B]LPOP • LLEN
  • 17. Sorted Set Keys • Like sets, but sorted by a user-provided score value • Extremely fast access by score or range of scores, because it’s sorted in storage • Common commands • ZADD • ZRANGE • ZREVRANGE
  • 19. Other commands that work on all keys • DEL - delete a key, regardless of type • KEYS - search for keys (usually with a wildcard) • EXPIRE / PERSIST - change expiration values for keys
  • 21. Connecting from PHP • Several libraries out there • Rediska (http://rediska.geometria-lab.net/) • PHP 5.2 / ZF 1.x friendly • Predis (https://github.com/nrk/predis) • The best in my experience • Requires PHP 5.3
  • 22. Predis • All the examples here assume you’re using Predis • Connect to a localhost redis: $p = new PredisClient(); • Redis commands implemented as magic methods on Client(); • $p->set($key, $val); • $val = $p->get($key);
  • 23. Attribute Display Logic items_attributes items id INT(11) id INT(11) item_id INT(11) attr_name VARCHAR(32) name VARCHAR(32) attr_value VARCHAR(32) 10k rows 100k rows • An item, a Dell Latitude Laptop, has: • Free Shipping, Financing Available, Expires Soon, etc
  • 24. Attribute Display Logic • Display “Free Shipping” graphic on the item if it has a free shipping attribute row 50 items per page
  • 25. Attribute Display - Traditional class Item { public function hasAttribute($name) { $sql = "SELECT 1 FROM items_attributes WHERE item_id = $this->id AND attr_name='$name' LIMIT 1"; $result = $this->pdo->execute($sql); return $result != false; } }
  • 26. Denormalize data from MySQL to Redis • Smart caching • Define a consistent way to represent a relational object in Redis • I prefer [object class]:[object id]:[attribute] • ex: product:13445:num_comments • This prevents data collisions, and makes it easy to work with data on the command line
  • 27. Attribute Display - Redis class Item { public function hasAttribute($name) { return $this->redis->sismember(“item:$this->id:attributes”, $name); } public function addAttribute($name, $value) { //traditional mysql stuff here still $this->redis->sadd('item:45:attributes', $name); } }
  • 28. Advantages • The more items you have, the less MySQL will scale this solution for you on it’s own • Frequently updating your items kills the MySQL query cache • Checking existence of a set member is O(1) time • On a laptop, I can check roughly 10,000 attributes per second
  • 29. Session Clustering WEB - 1 WEB - 2 WEB - 3 PHP Sessions PHP Sessions PHP Sessions Inconsistent state
  • 30. Session Clustering WEB - 1 WEB - 2 WEB - 3 DB - 1 PHP Sessions Slow with many users (never cached), replication lag
  • 31. Session Clustering WEB - 1 WEB - 2 WEB - 3 REDIS - 1 DB - 1 PHP Sessions Constant time lookups, in-memory sessions
  • 32. Job Queues • Redis lists make great job queues • Offload your intensive workloads to some other process • Blocking I/O allows you to easily build long-running daemons
  • 33. Job Queues class Queue { protected $name; protected $predis; public function push(Array $job) { $this->predis->lpush($this->name, json_encode($job)); } public function pop($block = false) { $job = null; if ($block) { $data = $this->predis->brpop($this->name, 0); $job = $data[1]; } else { $job = $this->predis->rpop($this->name); } if ($job) { return json_decode($job); } } }
  • 34. Queuing Jobs $q = new Queue('test_queue'); $form = new My_Zend_Form(); if ($form->isValid($_POST)) { $q->push($form->getValues()); $message = “Thanks for your submission”; } else { $message = “Error - something went wrong”; } echo “<h1>$message</h1>”;
  • 35. Processing Jobs - Crontab style function processJob(Array $job) { //...something really cool here // throw an exception on error } // process all pending jobs $q = new Queue(‘test_queue’); while ($job = $q->pop()) { try { processJob($job); } catch (Exception $e) { Echo “error processing job”; $q = new Queue(‘errors’); $q->push($job); } }
  • 36. Processing Jobs - Worker style function processJob(Array $job) { //...something really cool here // throw an exception on error } // keep processing jobs as they become available $q = new Queue(‘test_queue’); while ($job = $q->pop(true)) { try { processJob($job); } catch (Exception $e) { Echo “error processing job”; $q = new Queue(‘errors’); $q->push($job); } }
  • 37. MVC Routing • Example: • Offers.com has about 3900 stores • Store pages live at /[store]/
  • 38. Old Store Routing class Store_Route { public function route($url) { $sql = “SELECT id, type FROM stores WHERE url=’$url’”; $store = $this->pdo->execute($sql); //... do logic to determine what action to use based on type ...// return array(“module” => “core”, “controller” => “store”, “action” => $action); } } • And then there’s offers.com/[holiday]/....
  • 39. New Routing class Redis_Route { public function route($url) { $p = $this->predis; if ($p->exists($url)) { list($module, $controller, $action) = $this->redis->hVals($url); return array(“module” => $module, “controller” => $controller, “action” => $action); } return false; } }
  • 40. Filling in the Redis keys class Store { public function create(Array $data) { // ... traditional SQL stuff to put store in the database ... // $route = array(“module” => “core”, “controller” => “store”, “action” => $data[“type”]); $this->predis->hmset($data[“url”], $route); } }
  • 41. Advantages • I can now create offers.com/[anything]/ and route it to the right place, in O(1) time • I’m only adding a few lines of code to my existing models
  • 44. Vertive is Hiring • We help people save money • We’re looking for engineers in Austin, TX to work on:

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. Can do increment, etc on individual fields\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