18 июля 2012 г. Redis vs Memcache vs Memcached

Redis vs Memcached

Решил проверить производительность двух популярных кеш серверов. Это Redis и Memcached. В качестве PHP клиентов в тесте использовались phpredis, Memcache и Memcached.

Железо

Для достоверности тестов решил провести их на двух разных ПК.

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

Тесты

Ниже приведен скрипт, который я написал для тестов. В зависимости от операции подставлялся set, get, delete.

$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";

В случае с мультисетами скрипт был немного изменен:

$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";

Результаты тестов

Результаты для ПК №1:

Действие Redis (время, msec) Memcache (время, msec) Memcached (время, 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

Результаты для ПК №2:

Действие Redis (время, msec) Memcache (время, msec) Memcached (время, 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

Выводы

  • Memcache проигрывает по производительности и возможностям Redis и Memcached, думаю от него можно смело отказаться
  • на операциях с set-ми Redis превосходит Memcached
  • на операциях с get-ми Redis проигрывает Memcached
  • при мульти get-ах на больших объемах, более 100000, Redis значительно хуже ведетя себя по сравнению с Memcached, думаю не стоит использовать мульти get-ы Redis-а при таких объемах
  • при мульти get-ах на небольшие объемы, 1000 или 100 записей, результаты для Redis-а и Memcached схожи
  • не смотря на превосходства Memcached, в некоторых случаях, я все же выбираю Redis в силу его более широкого и удобного функционала
Базы данных