Главная > Теория и практика > memcache vs memached - сравниваем клиенты для PHP

memcache vs memached - сравниваем клиенты для PHP

performance

Какой клиент лучше использовать при разработке на PHP - php-memcached или php-memcache? Все зависит от того, какие особенности Вам нужны (неужели?). Давайте сравним в двух аспектах - функциональность и производительность.

Функциональность

Клиентская библиотека php-memcache была разработана еще в 2004 году и сегодня существует уже довольно стабильная версия, которая используется в 99.9% проектах (использующих сервер Memcache). Большим недостатком этой библиотеки является ее ограниченные способности - она реализует только часть протокола мемкеша, и не позволяет использовать его дополнительные возможности (какие именно - чуть ниже).

Библиотека php-memcached была разработана сравнительно недавно, но уже успешно используется на некоторых крупных проектах (например, digg.com - из которого и вышла эта разработка). Самое главное ее преимущество - это полная реализация протокола, в том числе:

  • CAS токены для версионирования ключей
  • Обратные вызовы (callbacks)
  • Метод getDelayed() позволяющий уменьшить время ожидания откладывая фактическое чтение ключей
  • Поддержка бинарного протокола
  • Возможность избежать сериализации используя igbinary

Производительность

Теперь давайте сравним производительность на практике.
Для этого напишем небольшой скрипт, который делает одинаковые операции с обоими клиентами:

<?

$ops = 10000;

$m = new Memcache();
$m->addServer('localhost');

$md = new Memcached();
$md->addServer('localhost', 11211);

echo "Test operations: {$ops}";
echo "<h3>get test</h3>";

$s = microtime(true);
for ( $i = 0; $i < $ops; $i++ ) $m->get( md5(rand(1000, 99999)) );
echo "Memcache: " . ($res['memcache']['set'] = microtime(true) - $s ) . "<br />";

$s = microtime(true);
for ( $i = 0; $i < $ops; $i++ ) $md->get( md5(rand(1000, 99999)) );
echo "Memcached: " . ($res['memcached']['set'] = microtime(true) - $s );

echo "<h3>set test</h3>";

$s = microtime(true);
for ( $i = 0; $i < $ops; $i++ ) $m->set(md5(rand(1000, 99999)), 2);
echo "Memcache: " . ($res['memcache']['get'] = microtime(true) - $s ) . "<br />";

$s = microtime(true);
for ( $i = 0; $i < $ops; $i++ ) $md->set(md5(rand(1000, 99999)), 2);
echo "Memcached: " . ($res['memcached']['get'] = microtime(true) - $s );

echo "<h3>delete test</h3>";

$s = microtime(true);
for ( $i = 0; $i < $ops; $i++ ) $m->delete(md5(rand(1000, 99999)));
echo "Memcache: " . ($res['memcache']['delete'] = microtime(true) - $s ) . "<br />";

$s = microtime(true);
for ( $i = 0; $i < $ops; $i++ ) $md->delete(md5(rand(1000, 99999)));
echo "Memcached: " . ($res['memcached']['delete'] = microtime(true) - $s );

echo "<h3>combined test</h3>";

$s = microtime(true);
for ( $i = 0; $i < $ops; $i++ )
{
	$key = md5(rand(1000, 99999));
	$m->set($key, 2);
	$m->get($key);
	$m->delete($key);
}
echo "Memcache: " . ($res['memcache']['combined'] = microtime(true) - $s ) . "<br />";

$s = microtime(true);
for ( $i = 0; $i < $ops; $i++ )
{
	$key = md5(rand(1000, 99999));
	$md->set($key, 2);
	$md->get($key);
	$md->delete($key);
}
echo "Memcached: " . ($res['memcached']['combined'] = microtime(true) - $s );

Как видно, скрипт просто выполняет основные операции сохранения, чтения и удаления ключей 10 тыс. раз и замерает их время для каждого клиента.

Результаты работы теста

Как видно из графика, производительность клиента php-memcache почти втрое выше, чем php-memcached. Следует учесть, что показатели при работе с бинарным протоколом почти не отличалась по времени от ASCII протокола.

Обновление

Благодаря внимательному читателю этого блога удалось выяснить, что сильные отличия в показателях тестов связаны с конкретными версиями и настройками библиотек. Проверка на других платформах дает отличие в производительности не более 10%.

В качестве вывода следует сказать, что клиент php-memcache лучше использовать, если функционала приложению полностью хватает (лучше, т.к. он быстрее). Если нужны расширенные возможности, то нужно использовать php-memcached. Но в этом случае нужно учесть понижение производительности.

Хотя важно заметить: даже не смотря на трехкратное различие в скорости работы, операции общения с сервером Memcache обычно занимают доли процента от времени исполнения приложения. Различие в скорости работ библиотек может быть заметно только при массовой работе с кешом, или же на огромных объемах данных.

Google Bookmarks Digg I.ua Ru-marks Ruspace Zakladok.net Reddit delicious Technorati Yahoo My Web News2.ru БобрДобр.ru Memori.ru rucity.com

Статьи по теме

  1. Igor Skrynkovskyy
    7 Май 2010 в 18:10 | #1

    Дякую за статтю. Тепер буде стимул і самому розібратися з memcache

  2. 7 Май 2010 в 22:46 | #2

    Я бы добавил еще тест на мультигет

  3. 26 Май 2010 в 18:04 | #3

    Здравствуйте!
    Ваш тест на Ubuntu Netbook Remix:

    Test operations: 10000

    get test
    Memcache: 3.74332213402
    Memcached: 3.32582402229

    set test
    Memcache: 3.64596199989
    Memcached: 2.93430399895

    delete test
    Memcache: 2.82469391823
    Memcached: 3.00117897987

    combined test
    Memcache: 6.8338830471
    Memcached: 7.90108919144

    Разницы в 3 раза не наблюдается.

  4. 26 Май 2010 в 18:07 | #4

    @vasa_c
    Давайте сравним, укажите версии библиотек и самого сервера.

  5. 26 Май 2010 в 18:37 | #5

    @Den Golotyuk
    Ubuntu 9.10
    PHP 5.3.2-dev
    PHP Extension 20090626
    Zend Extension 220090626

    php_memcache version 2.2.5
    php_memcached version 1.0.1
    libmemcached version 0.31

    Memcached 1.2.8

  6. 26 Май 2010 в 18:44 | #6

    memcached 1.4.2
    php-memcache 2.2.5
    php-memacached 1.0.2
    PHP 5.2.11
    libmemcached 0.40

    И того, различия в сервере и версии PHP, что скорее всего не может дать такой разницы. Я попробую провести тесты на других серверах и опубликую результаты.

  7. 26 Май 2010 в 18:46 | #7

    Разве что php-memcached в 1.0.2 значительно ухудшился по сравнению с 1.0.1 :)
    Я тоже постараюсь сегодня проверить на FreeBSD

  8. 26 Май 2010 в 19:01 | #8

    @vasa_c
    Я нашел довольно интересную закономерность. Похоже что результаты тестов сильно искажены внутренней проблемой библиотеки memcached (судя по всему этой конкретной версии). Буду благодарен, если проведете тест на своей сторое: в одном случае соединение устанавливается с IP (127.0.0.1) в другом с доменным именем (localhost).

  9. 26 Май 2010 в 19:33 | #9

    И как меняются ваши результаты в зависимости от этого?
    Я не заметил у себя существенных изменений.

    Кстати, rand() и md5() тяжеловаты, лучше их из тестируемого цикла выкинуть.

    $keys = array();
    for ($i = 0; $i < $ops; $i++) {
    $key = md5(rand(1000, 9999));
    $val = 2;
    $keys[$key] = $val;
    }

    $s = microtime(true);
    #for ( $i = 0; $i set(md5(rand(1000, 99999)), 2);
    foreach ($keys as $key => $val) {
    $m->set($key, $val);
    }
    echo “Memcache: ” . ($res['memcache']['get'] = microtime(true) - $s ) . “”;

    $s = microtime(true);
    #for ( $i = 0; $i set(md5(rand(1000, 99999)), 2);
    foreach ($keys as $key => $val) {
    $md->set($key, $val);
    }
    echo “Memcached: ” . ($res['memcached']['get'] = microtime(true) - $s );

    В этом случае тесты ускоряются практически вдвое.
    Но относительные скорости такие же.

  10. 27 Май 2010 в 10:17 | #10

    FreeBSD 6.3-STABLE
    PHP 5.3.2-dev
    php_memcache 3.0.4
    php_memcached 1.0.1
    libmemcached 0.31
    memcached 1.2.8

    результаты для обоих библиотек снова различаются слабо

  11. 27 Май 2010 в 14:23 | #11

    Извиняюсь за назойливость.
    Написал свой тест - http://blgo.ru/t/blog/090527/mc/

    Memcache Memcached
    set-new 191 174
    set-exists 185 173
    get-exists 177 167
    get-empty 170 159
    delete-exists 182 164
    delete-empty 174 160

    Числа - микросекунды на один запрос.

  12. 27 Май 2010 в 14:27 | #12

    @vasa_c
    Спасибо! Важные результаты, т.к. php-memcached показывает лучшую производительность.

  1. Пока что нет уведомлений.