Skip to content

Instantly share code, notes, and snippets.

@php-cpm
Last active July 30, 2018 02:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save php-cpm/ac7fd10c84894320e364e7e54ccc93b6 to your computer and use it in GitHub Desktop.
Save php-cpm/ac7fd10c84894320e364e7e54ccc93b6 to your computer and use it in GitHub Desktop.
first benchmark is redis
<?php
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
for ($i = 0; $i < 100; $i++) {
$start = microtime(true);
for ($j = 0; $j < 10000; $j++) {
$key = sprintf("key:%05d", $j);
$redis->pipeline();
/* GET or SET */
if (rand() % 2 == 0) {
$redis->set($key, rand());
} else {
$redis->get($key);
}
}
$time = microtime(true)-$start;
printf("%6d req/sec\n", $j/$time);
}
@php-cpm
Copy link
Author

php-cpm commented Jul 24, 2018

i only got 14940 req/sec using pipeline

@php-cpm
Copy link
Author

php-cpm commented Jul 24, 2018

using non-pipeline mode I got result

9733 req/sec

<?php
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
for ($i = 0; $i < 100; $i++) {
  $start = microtime(true);
  for ($j = 0; $j < 10000; $j++) {
    $key = sprintf("key:%05d", $j);
    /* GET or SET */
    if (rand() % 2 == 0) {
      $redis->set($key, rand());
    } else {
      $redis->get($key);
    }
  }
  $time = microtime(true)-$start;
  printf("%6d req/sec\n", $j/$time);
}

@php-cpm
Copy link
Author

php-cpm commented Jul 24, 2018

redis extension info

Redis Support => enabled
Redis Version => 3.1.4
Available serializers => php, igbinary

@php-cpm
Copy link
Author

php-cpm commented Jul 24, 2018

ALL MY MISTAKE!

I used php 7.1.19 + opcache + xdebug opened

after I comment out xdebug extension I ran again and got

25707 req/sec compare to 9733 req/sec

1456659 req/sec compare to 14940 req/sec

@php-cpm
Copy link
Author

php-cpm commented Jul 24, 2018

benchmark using predis
pipeline 765286 req/sec 52.5%
non-pipeline 20015 req/sec 77.8%

$ composer require predis/predis

<?php
require 'vendor/autoload.php';
$redis = new Predis\Client();
$redis->connect('127.0.0.1', 6379);
for ($i = 0; $i < 100; $i++) {
  $redis->pipeline(function ($redis) {
  $start = microtime(true);
  for ($j = 0; $j < 10000; $j++) {
    $key = sprintf("key:%05d", $j);
    /* GET or SET */
    if (rand() % 2 == 0) {
      $redis->set($key, rand());
    } else {
      $redis->get($key);
    }
  }
  $time = microtime(true)-$start;
  printf("%6d req/sec\n", $j/$time);
  });
}

@php-cpm
Copy link
Author

php-cpm commented Jul 24, 2018

after install hiredis && phpiredis

pipeline 876277 req/sec
non-pipeline 24854 req/sec

HOW TO

brew install hiredis
brew tap php-cpm/php
brew install php71-phpiredis

@php-cpm
Copy link
Author

php-cpm commented Jul 27, 2018

memcache vs memcached

<?php
$m = new Memcached();
$m->addServer('localhost', 11211);
for ($i = 0; $i < 100; $i++) {
  $start = microtime(true);
  for ($j = 0; $j < 10000; $j++) {
    $key = sprintf("key:%05d", $j);
    /* GET or SET */
    if (rand() % 2 == 0) {
      $m->set($key, rand(), 3600);
    } else {
      $m->get($key);
    }
  }
  $time = microtime(true)-$start;
  printf("%6d req/sec\n", $j/$time);
}

30733 req/sec

<?php
$avg = [];
$m = new Memcache();
$m->addServer('localhost', 11211);
for ($i = 0; $i < 20; $i++) {
  $start = microtime(true);
  for ($j = 0; $j < 10000; $j++) {
    $key = sprintf("key:%05d", $j);
    /* GET or SET */
    if (rand() % 2 == 0) {
      $m->set($key, (object)[rand()], 0, 3600);
    } else {
      $m->get($key);
    }
  }
  $time = microtime(true)-$start;
$avg[] =  intval($j/$time);
  printf("%6d req/sec\n", $j/$time);
}
echo array_sum($avg) / count($avg) . " req/sec avg";

23784 req/sec

php-memcached is 29% faster than php-memcache

@php-cpm
Copy link
Author

php-cpm commented Jul 27, 2018

apcu

<?php
for ($i = 0; $i < 100; $i++) {
  $start = microtime(true);
  for ($j = 0; $j < 10000; $j++) {
    $key = sprintf("key:%05d", $j);
    /* GET or SET */
    if (rand() % 2 == 0) {
      apcu_store($key, rand(), 3600);
    } else {
      apcu_fetch($key);
    }
  }
  $time = microtime(true)-$start;
  printf("%6d req/sec\n", $j/$time);
}

without socket connection apcu cache always faster than redis or memcached

1747710 req/sec

@php-cpm
Copy link
Author

php-cpm commented Jul 27, 2018

tmp file benchmark

<?php
// modify code from https://medium.com/@dylanwenzlau/500x-faster-caching-than-redis-memcache-apc-in-php-hhvm-dcd26e8447ad
function cache_set($key, $val) {
   $val = var_export($val, true);
   // HHVM fails at __set_state, so just use object cast for now
   $val = str_replace('stdClass::__set_state', '(object)', $val);
   // Write to temp file first to ensure atomicity
   $tmp = "/tmp/cache/$key." . uniqid('', true) . '.tmp';
   file_put_contents($tmp, '<?php $val = ' . $val . ';', LOCK_EX);
   rename($tmp, "/tmp/cache/$key");
}
function cache_get($key) {
    @include "/tmp/cache/$key";
    return isset($val) ? $val : false;
}
$avg = [];
for ($i = 0; $i < 100; $i++) {
  $start = microtime(true);
  for ($j = 0; $j < 10000; $j++) {
    $key = sprintf("key:%05d", $j);
    /* GET or SET */
    if (rand() % 2 == 0) {
      cache_set($key, rand());
    } else {
      cache_get($key);
    }
  }
  $time = microtime(true)-$start;
$avg[] = intval($j/$time);
  printf("%6d req/sec\n", $j/$time);
}

8476 req/sec

@php-cpm
Copy link
Author

php-cpm commented Jul 27, 2018

check for avg

  • use same program

  • change cache type

  • change cache data

    1. object data (object)[rand()]
    2. array data [rand()]
    3. string data rand()
  • run benchmark again and again

<?php
$avg = [];
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
for ($i = 0; $i < 100; $i++) {
  $start = microtime(true);
  for ($j = 0; $j < 10000; $j++) {
    $key = sprintf("key:%05d", $j);
    $redis->pipeline();
    /* GET or SET */
    if (rand() % 2 == 0) {
      $redis->set($key, (object)[rand()]);
    } else {
      $redis->get($key);
    }
  }
  $time = microtime(true)-$start;
  $avg[] = intval($j/$time);
  printf("%6d req/sec\n", $j/$time);
}
echo array_sum($avg) / count($avg) . " req/sec avg";
<?php
/* 
 * using unix socket server make connection 2x faster
 * server redis.conf edit:
 *  unixsocket /tmp/redis.sock
 *  unixsocketperm 777
 */
$avg = [];
$redis = new Redis();
$redis->connect('/tmp/redis.sock');
for ($i = 0; $i < 100; $i++) {
  $start = microtime(true);
  for ($j = 0; $j < 10000; $j++) {
    $key = sprintf("key:%05d", $j);
    /* GET or SET */
    if (rand() % 2 == 0) {
      $redis->set($key, (object)[rand()]);
    } else {
      $redis->get($key);
    }
  }
  $time = microtime(true)-$start;
$avg[] = intval($j/$time);
  printf("%6d req/sec\n", $j/$time);
}
echo array_sum($avg) / count($avg) . " req/sec avg";
cache object array string
php-ext-apcu 797465 1102939.18 1722482.74
php-ext-redis pipeline 1621555.16 1787449.6 1740069.4
predis+php-ext-phpiredis pipeline 133997.95 125891.63 137244.45
php-ext-redis non-pipeline 24788.3 25784.4 25462.75
php-ext-redis non-pipeline unix socket 43581.2 44764.79 44441.15
predis+php-ext-phpiredis non-pipeline
(json_encode/serialize)
23838.1 24831.65 24202.25
php-ext-memcached 28619.35 28633.25 29881.5
php-ext-memcache 25440.25 24316.9 26490.4

based on this report we suggest people use

  • php-ext-memcached as cache driver and memcached as cache server
  • use php-ext-redis if you want to use pipeline, predis is too slow here
  • choose either predis or php-ext-redis is ok for normal cache use
  • php-ext-apcu is far more speedy, it's a good point to use it as cache to boost your program

even more hard sence

<?php
$avg = [];
for ($i = 0; $i < 100; $i++) {
  $start = microtime(true);
  for ($j = 0; $j < 10000; $j++) {
    $redis = new Redis();
    $redis->pconnect('127.0.0.1', 6379, 1, 'x');
    $key = sprintf("key:%05d", $j);
    $redis->pipeline();
    /* GET or SET */
    if (rand() % 2 == 0) {
      $redis->set($key, (object)[rand()]);
    } else {
      $redis->get($key);
    }
    $redis->close();
  }
  $time = microtime(true)-$start;
  $avg[] = intval($j/$time);
  printf("%6d req/sec\n", $j/$time);
}
echo array_sum($avg) / count($avg) . " req/sec avg";

redis pconnect reuse 21710.55

@php-cpm
Copy link
Author

php-cpm commented Jul 30, 2018

use strace to analise sys call sudo dtruss -c php redis.php

predis

CALL                                        COUNT
bsdthread_register                              1
connect                                         1
fchmod                                          1
ftruncate                                       1
getentropy                                      1
getpid                                          1
getrlimit                                       1
getsockopt                                      1
getuid                                          1
shm_open                                        1
sigprocmask                                     1
thread_selfid                                   1
write                                           1
csops                                           2
fstatat64                                       2
fstatfs64                                       2
getegid                                         2
gettid                                          2
issetugid                                       2
openat_nocancel                                 2
unlink                                          2
geteuid                                         3
socket                                          3
getdirentries64                                 4
sysctl                                          4
fcntl_nocancel                                  6
madvise                                         6
pread                                          12
mprotect                                       17
readlink                                       17
read_nocancel                                  19
access                                         28
lseek                                          41
open                                           42
close                                          45
sigaction                                      45
close_nocancel                                 49
open_nocancel                                  52
lstat64                                        54
munmap                                         64
ioctl                                          73
fcntl                                          74
stat64                                         86
mmap                                          104
getattrlist                                   132
fstat64                                       146
recvfrom                                     8390
sendto                                       8390
poll                                         8391

predis calls more recvfrom sendto so it's a little slower than others

php-ext-redis

bsdthread_register                              1
connect                                         1
fchmod                                          1
ftruncate                                       1
getentropy                                      1
getpid                                          1
getrlimit                                       1
getsockopt                                      1
getuid                                          1
shm_open                                        1
sigprocmask                                     1
thread_selfid                                   1
csops                                           2
fstatat64                                       2
fstatfs64                                       2
getegid                                         2
gettid                                          2
issetugid                                       2
openat_nocancel                                 2
unlink                                          2
access                                          3
geteuid                                         3
socket                                          3
getdirentries64                                 4
sysctl                                          4
fcntl_nocancel                                  5
madvise                                         6
pread                                          12
lstat64                                        13
open                                           13
close                                          16
fcntl                                          16
mprotect                                       17
readlink                                       17
read_nocancel                                  19
munmap                                         35
lseek                                          41
sigaction                                      45
close_nocancel                                 48
open_nocancel                                  51
stat64                                         56
fstat64                                        58
ioctl                                          73
mmap                                           75
getattrlist                                   132
sendto                                       1596
setsockopt                                   1597
recvfrom                                     1598
poll                                         6382

php-ext-memcached

bsdthread_register                              1
connect                                         1
fchmod                                          1
ftruncate                                       1
getentropy                                      1
getpid                                          1
getrlimit                                       1
getsockopt                                      1
getuid                                          1
setsockopt                                      1
shm_open                                        1
sigprocmask                                     1
thread_selfid                                   1
write                                           1
csops                                           2
fstatat64                                       2
fstatfs64                                       2
getegid                                         2
gettid                                          2
issetugid                                       2
openat_nocancel                                 2
socket                                          2
unlink                                          2
access                                          3
geteuid                                         3
getdirentries64                                 4
sysctl                                          4
fcntl_nocancel                                  5
madvise                                         6
pread                                          12
lstat64                                        13
open                                           13
close                                          15
fcntl                                          17
mprotect                                       17
readlink                                       17
read_nocancel                                  19
munmap                                         35
lseek                                          41
sigaction                                      45
close_nocancel                                 48
open_nocancel                                  51
stat64                                         56
fstat64                                        58
ioctl                                          73
mmap                                           75
getattrlist                                   132
poll                                         2550
sendto                                       2552
recvfrom                                     5103

php connect to redis using a lot of poll when memcached using recvform code recvfrom(0x4, 0x7FC86509E2B8, 0x2004) = -1 Err#35 which means Resource deadlock avoided

php-ext-apcu

CALL                                        COUNT
bsdthread_register                              1
exit                                            1
fchmod                                          1
ftruncate                                       1
getentropy                                      1
getpid                                          1
getrlimit                                       1
getuid                                          1
shm_open                                        1
sigprocmask                                     1
socket                                          1
thread_selfid                                   1
csops                                           2
fstatat64                                       2
fstatfs64                                       2
getegid                                         2
gettid                                          2
issetugid                                       2
openat_nocancel                                 2
unlink                                          2
access                                          3
geteuid                                         3
getdirentries64                                 4
sysctl                                          4
fcntl_nocancel                                  5
pread                                          12
lstat64                                        13
open                                           13
fcntl                                          14
close                                          16
mprotect                                       17
readlink                                       17
read_nocancel                                  19
lseek                                          41
sigaction                                      45
open_nocancel                                  50
close_nocancel                                 51
stat64                                         56
fstat64                                        58
ioctl                                          73
mmap                                           75
write                                         101
getattrlist                                   132
munmap                                        140
madvise                                       232

apcu memory operation calling madvise, munmap, etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment