Friday, September 25, 2015

Compare performance Redis | Memcache | 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 server2.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 server2.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:
ActionRedis (time, msec)Memcache (time, msec)Memcached (time, msec)
set 100 000 records1.76602387428282.05889391899111.8064510822296
set 10 000 000 records176.15660905838204.24968600273180.38528609276
get 100 000 existing records1.56007099151611.90068697929381.4469799995422
get 100 000 not existing records1.51919698715211.6601788997651.3355889320374
multi set 100 000 records0.099898099899292not supported1.468493938446
multi get 100 000 records4.6445689201355not supported0.32813692092896
multi set 100 000 records, key in md5()0.10940098762512not supported1.4723839759827
multi get 100 000 records, key in md5()19.233497858047not supported0.84516382217407
multi set 100 000 records, key in rand(1000, 100000)0.060782909393311not supported0.94941711425781
multi get 100 000 records, key in rand(1000, 100000)4.8860421180725not supported0.31907391548157
multi set 1000 records0.00089097023010254not supported0.015062093734741
multi get 1000 records0.00095605850219727not supported0.00080299377441406
multi set 100 records0.00018501281738281not supported0.0020837783813477
multi get 100 records0.00011515617370605not supported0.00011086463928223
delete 100 000 records1.83676910400391.90609097480771.5589101314545
Results for PC №2:
ActionRedis (time, msec)Memcache (time, msec)Memcached (time, msec)
set 100 000 records6.21481299400336.54327106475835.4482190608978
get 100 000 existing records5.3230371475225.5690300464634.5307388305664
get 100 000 not existing records5.19892907142645.09139013290414.4651319980621
multi set 100 000 records0.13565897941589not supported4.8275148868561
multi get 100 000 records33.314270973206not supported0.18355584144592
multi set 100 000 records, key in md5()0.1761519908905not supported4.7951271533966
multi get 100 000 records, key in md5()87.041321992874not supported0.17605519294739
multi set 100 000 records, key in rand(1000, 100000)0.10172891616821not supported3.0671350955963
multi get 100 000 records, key in rand(1000, 100000)32.840623140335not supported0.18809008598328
multi set 1000 records0.0025210380554199not supported0.051932096481323
multi get 1000 records0.0038590431213379not supported0.0024211406707764
multi set 100 records0.0002739429473877not supported0.0031120777130127
multi get 100 records0.00021004676818848not supported0.00017499923706055
delete 100 000 records5.29550719261175.21021199226384.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