July 18, 2012 Redis vs Memcache vs Memcached

Redis vs Memcached

I decided to test the performance of two popular cache servers. This is Redis and Memcached. I used phpredis, Memcache and Memcached.

Hardware

I decided to test them on two different PCs for the better results reliability

PC №1:

OSUbuntu 12.04 64bit
CPUIntel Core i5-3570K (4 Cores, 4 Threads, 3.4GHz /6MB)
RAMDDR3 8192Mb(2*4096Mb Kit) PC12800 (1600MHz) Corsair XMS3 Vengeance (CMZ8GX3M2A1600C9)
MBASUS P8Z68-V PRO/GEN3 Z68
Redis server 2.5.10 64 bit
Memcached server1.4.13

PC №2:

OSUbuntu 11.04
CPUIntel Core i3-2100 (2 Cores, 4 Threads, 3.10GHz / 3Mb)
RAMDDR3 4096Mb(2*2048Mb Kit) 1333 MHz
MBASUS P8H61-M LX2
Redis server 2.4.15
Memcached server1.4.5

Tests

Below you can see the script that I wrote for the tests

$records = 100000;
$redis = new Redis();
$redis->connect('localhost', 6379);
$memcache = new Memcache();
$memcache->addServer('localhost');
$memcached = new Memcached();
$memcached->addServer('localhost', 11211);
$startRedis = microtime(true);
for($i=0; $i<$records; $i++)
{
    $value = sha1(mt_rand(10000,20000));
    $redis->set($i, $value);
}
$endRedis = microtime(true) - $startRedis;
$startMemcache = microtime(true);
for($i=0; $i<$records; $i++)
{
    $value = sha1(mt_rand(10000,20000));
    $memcache->set($i, $value);
}
$endMemcache = microtime(true) - $startMemcache;
$startMemcached = microtime(true);
for($i=0; $i<$records; $i++)
{
    $value = sha1(mt_rand(10000,20000));
    $memcached->set($i, $value);
}
$endMemcached = microtime(true) - $startMemcached;
echo 'Redis: '.$endRedis."\r\n";
echo 'Memcache: '.$endMemcache."\r\n";
echo 'Memcached: '.$endMemcached."\r\n";

Script has been changed for multi sets:

$records = 100000;
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$memcached = new Memcached();
$memcached->addServer('127.0.0.1', 11211);
$array = array();
for($i=0; $i<$records; $i++)
{
    $value = sha1(mt_rand(10000,20000));
    $key = "key".$i;
    $array[$key] = $value;
    $arrayKeys[] = $key;
}
//multi set
$startRedis = microtime(true);
$redis->mset($array);
$endRedis = microtime(true) - $startRedis;
$startMemcached = microtime(true);
$memcached->setMulti($array);
$endMemcached = microtime(true) - $startMemcached;
echo 'Redis multi set: '.$endRedis."\r\n";
echo 'Memcached multi set: '.$endMemcached."\r\n";
//multi get
$startRedis = microtime(true);
$result = $redis->mget($arrayKeys);
$endRedis = microtime(true) - $startRedis;
$startMemcached = microtime(true);
$result = $memcached->getMulti($arrayKeys);
$endMemcached = microtime(true) - $startMemcached;
echo 'Redis multi get: '.$endRedis."\r\n";
echo 'Memcached multi get: '.$endMemcached."\r\n";

Test results:

Results for PC №1:

Action Redis (time, msec) Memcache (time, msec) Memcached (time, msec)
set 100 000 records 1.7660238742828 2.0588939189911 1.8064510822296
set 10 000 000 records 176.15660905838 204.24968600273 180.38528609276
get 100 000 existing records 1.5600709915161 1.9006869792938 1.4469799995422
get 100 000 not existing records 1.5191969871521 1.660178899765 1.3355889320374
multi set 100 000 records 0.099898099899292 not supported 1.468493938446
multi get 100 000 records 4.6445689201355 not supported 0.32813692092896
multi set 100 000 records, key in md5() 0.10940098762512 not supported 1.4723839759827
multi get 100 000 records, key in md5() 19.233497858047 not supported 0.84516382217407
multi set 100 000 records, key in rand(1000, 100000) 0.060782909393311 not supported 0.94941711425781
multi get 100 000 records, key in rand(1000, 100000) 4.8860421180725 not supported 0.31907391548157
multi set 1000 records 0.00089097023010254 not supported 0.015062093734741
multi get 1000 records 0.00095605850219727 not supported 0.00080299377441406
multi set 100 records 0.00018501281738281 not supported 0.0020837783813477
multi get 100 records 0.00011515617370605 not supported 0.00011086463928223
delete 100 000 records 1.8367691040039 1.9060909748077 1.5589101314545

Results for PC №2:

Action Redis (time, msec) Memcache (time, msec) Memcached (time, msec)
set 100 000 records 6.2148129940033 6.5432710647583 5.4482190608978
get 100 000 existing records 5.323037147522 5.569030046463 4.5307388305664
get 100 000 not existing records 5.1989290714264 5.0913901329041 4.4651319980621
multi set 100 000 records 0.13565897941589 not supported 4.8275148868561
multi get 100 000 records 33.314270973206 not supported 0.18355584144592
multi set 100 000 records, key in md5() 0.1761519908905 not supported 4.7951271533966
multi get 100 000 records, key in md5() 87.041321992874 not supported 0.17605519294739
multi set 100 000 records, key in rand(1000, 100000) 0.10172891616821 not supported 3.0671350955963
multi get 100 000 records, key in rand(1000, 100000) 32.840623140335 not supported 0.18809008598328
multi set 1000 records 0.0025210380554199 not supported 0.051932096481323
multi get 1000 records 0.0038590431213379 not supported 0.0024211406707764
multi set 100 records 0.0002739429473877 not supported 0.0031120777130127
multi get 100 records 0.00021004676818848 not supported 0.00017499923706055
delete 100 000 records 5.2955071926117 5.2102119922638 4.2873389720917

Conclusions

  • the performance and capabilities of Memcache are poor in comparison with Redis and Memcached. I think we can safely reject it
  • in operations with sets Redis exceed Memcached
  • in operations with gets Redis loses to Memcached
  • Redis is significantly worse to Memcached with multi gets at high volumes that more than 100000. I think you should not use the multi gets in Redis with such volumes
  • the results for a Redis and Memcached are similar on multi gets for small volumes, like 1000 or 100 entries
  • despite the superiority of Memcached, in some cases, I still choose the Redis because of its broader functional and convenient features
Databases