[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Сравнительный тест систем кэширования пользователь
PandoraBox2007
Содержание.
  • Введение.
  • Краткий обзор.
    • eAccelerator
    • APC
    • XCache
    • Memcache
  • Подготовка к тестам.
  • Тесты.
    • Тест первый. Зверский.
    • Тест второй. Многократное чтение.
    • Тест третий. В погоне за реальностью.
  • Заключение.
Введение.
    Началось все с того, что захотелось уменьшить время отклика страниц. Не разбираясь особо, я поставил на наш клубный сервер eAccelerator. Он умеет кэшировать скомпилированные в байт-код php-файлы, имеет оптимизатор кода и позволяет кэшировать пользовательские данные и данные сессий. Время отклика снизилось на разных сайтах в 2-10 раз, в зависимости от внутренней логики движков: которые попроще - страницы просто вылетают, которые помудренее - немного быстрее стали работать.
    Потом в голове возник вопрос: а правильный ли выбор я сделал. Стал искать сравнительные тесты в интернете и ничего стоящего не нашел. Даже странно стало: оптимизаторы php существуют не первый год, а сравнений никто не проводил. Даже если кто их и делал, то в поисковых системах они погребены под горами мусора.
    Рассмотрев список бесплатно доступных систем, составил следующий список: eAccelerator, APC, XCache и Memcache.
    Первые три умеют кэшировать скомпилированные php-файлы, eAccelerator и APC имеют оптимизаторы кода, Memcache же является отдельным кэширующим сервером и к php имеет отношение только тем, что для работы с ним существует php-модуль.
Краткий обзор.
    http://bart.eaccelerator.net/doc/phpdoc/

    По API больше понравился eAccelerator. API простое - только самое нужное, но есть и такие возможности, которых нет у других - функции блокировки ключа. Документация неудобная, но информация понятна и есть толковые примеры. Он также лучше и удобнее в настройках. Позволяет отдельно управлять хранением ключей, сессий и данных (скомпилированного кода и пользовательских данных). Методы хранения: только в разделяемой памяти, в памяти и на диске одновременно, в памяти с вытеснением на диск и только на диске. Легко и прозрачно можно отделить ключи каждого виртуального сервера в системе, чтобы не было лишних дырок в безопасности и пересечения ключей, установкой уникального значения параметра eaccelerator.name_space для каждого виртуального сервера. Переписал код club.shelek.ru на работу с кэшем: среднее время генерации страницы всего 4-5 мс против 90-120 без кэша. Против ожидания, что нагрузка на процессор и память возрастет, наблюдаю, наоборот, снижение за счет меньшей нагрузки на базу данных. Посмотрим, как он покажет себя при длительной эксплуатации.

    APC
    http://www.php.net/apc

    APC очень обилен в настройках. Пока я предпочел не крутить настройки, а пользоваться значениями по умолчанию. API очень маленькое. Интересная функция - сохранение массива и восстановление его как набора констант. Редкая по нужности функция.

    XCache
    http://xcache.lighttpd.net/wiki/XcacheApi
    После eAccelrator и APC XCache ничем хорошим не удивил. Отвратительная документация по API без единого комментария (я назвал ее "черный квадрат"), хотя для базовых функций даны примеры, и то хорошо. API простое. Из особенностей: возможность выполнять инкремент и декремент числового значения в кэше и функция проверки наличия ключа в кэше без пересылки самого значения. Настроек довольно мало. Удивило то, что кэширование по умолчанию разрешено, но размер используемой памяти и максимальные размеры пользовательских объектов равны нулю, что по документации означает "запрещено".

    Memcache
    http://www.php.net/memcache

    Memcache минималистичен в настройках, так как настройки управления кэшированием находятся на стороне сервера memcached. API у него посложнее, чем у первых трех систем, и поддерживает работу в процедурном и ООП способах. Из особенностей: помимо функции установки значения по ключу есть возможность добавить ключ, только если его еще нет, и перезаписать, только если он уже есть. Может иметь несколько кэширующих серверов: как на том же хосте, так и на других. Как я понял, суть Memcache - в использовании ресурсов других хостов. По моему мнению, это несколько устарело: если ресурсов одного хоста не хватает, то лучше найти другой способ распределить нагрузку, чем коммуникация по TCP с кэширующими серверами на других хостах, что вносит существенную задержку. Тем не менее, Memcache в сети упоминается часто, из чего делаю вывод о его популярности и включаю в список тестируемых систем.
Подготовка к тестам.
    Тестировать все это на живом сервере я не рискнул и использовал виртуальную машину. Все программы, которые могли вызвать неожиданную нагрузку на систему и повлиять на результаты замеров, были остановлены.

    Условия тестов:
    • Хост система: одноядерный P4 2800 ГГц, 1.5 ГБ памяти DDR-400, Windows XP Professional SP2, VMware Workstation 5.5.1.
    • Виртуальная система: 512 МБ, Linux CentOS 5.1, Apache 2.2.3, PHP 5.1.6, gcc 4.1.2.
    Тестируемые программы были собраны на этом виртуальном хосте с дополнительным ключом компиляции -O3. Для компиляции потребовалось скомпилировать и установить программу re2c версии 0.13.5.
    Версии программ:
    • eAccelerator - 0.9.5.3
    • APC - 3.0.19
    • XCache - 1.2.2
    • Memcache - 3.0.1
    • Memcached - 1.2.6
    Всем кэш-системам было выделено по 64 МБ разделяемой памяти. Оптимизация кода была включена. Перед каждым тестом каждой системы исправлялся конфиг php.ini, чтобы загружалась только тестируемая система, и выполнялся рестарт демона httpd.
    Лимит времени работы скрипта был убран, память, выделяемая процессу, - 200МБ (сначала было 16, но об этом чуть позже). Время измерялось php-функцией microtime(true) с точностью до микросекунд.
    Работу с кэш-системами обеспечивал класс, написанный несколькими днями ранее.
PHP
<?php

// © 2008 Veselchak U

class Cache
{
    var $_cache_type = 'auto'; // дефолтное значение
    var $_memcache = null;

    function __constructor($options = null)
    {
    $this->Cache($options);
    }

    function Cache($options = null)
    {
    // Проверка поддержки кеш-систем
    $cache_systems = array();

    if (function_exists('eaccelerator_get'))
        $cache_systems[] = 'eaccelerator';

    if (function_exists('apc_fetch'))
        $cache_systems[] = 'apc';

    if (function_exists('xcache_get'))
        $cache_systems[] = 'xcache';

    if (class_exists('Memcache'))
        $cache_systems[] = 'memcache';

    $required_cache = isset($options['cache']) ? $options['cache'] : $this->_cache_type;

    if (count($cache_systems) && $required_cache != 'none')
    {
        if ($required_cache == 'auto')
        $this->_cache_type = array_shift($cache_systems); // первое значение в списке
        else if (in_array($required_cache, $cache_systems))
        $this->_cache_type = $required_cache;
        else
        $this
->_cache_type = 'none';
    }
    else
        $this
->_cache_type = 'none';

    if ($this->_cache_type == 'memcache')
    {
        $failed = true;

        if (isset($options['memcache']) && is_array($options['memcache']))
        {
        $this->_memcache = new Memcache;

        foreach ($options['memcache'] as $server)
        {
            if (!is_array($server) || !isset($server['host'])) // host должен быть указан
            continue;

            $server['port'] = isset($server['port']) ? (int) $server['port'] : ini_get('memcache.default_port');
            $server['persistent'] = isset($server['persistent']) ? (bool) $server['persistent'] : true;

            if ($this->_memcache->addServer($server['host'], $server['port'], $server['persistent']))
            $failed = false;
        }

        if ($failed)
            $this->_memcache = null;
        }

        if ($failed)
        $this->_cache_type = 'none';
    }
    }

    function get($key)
    {
    $data = null;

    switch ($this->_cache_type)
    {
        case 'none':
        break;
        case 'eaccelerator':
        $data = eaccelerator_get($key);
        break;
        case 'apc':
        $data = apc_fetch($key);
        break;
        case 'xcache':
        $data = xcache_get($key);
        break;
        case 'memcache':
        $data = $this->_memcache->get($key);
        break;
    }

    return $data;
    }

    function put($key, &$data, $ttl)
    {
    switch ($this->_cache_type)
    {
        case 'none':
        break;
        case 'eaccelerator':
        eaccelerator_put($key, $data, $ttl);
        break;
        case 'apc':
        apc_store($key, $data, $ttl);
        break;
        case 'xcache':
        xcache_set($key, $data, $ttl);
        break;
        case 'memcache':
        // Решение set() проблемы с несколькими серверами.
        // http://www.php.net/manual/ru/function.memcache-set.php#84032
        if (!$this->_memcache->replace($key, $data, MEMCACHE_COMPRESSED, $ttl))
            $this->_memcache->set($key, $data, MEMCACHE_COMPRESSED, $ttl);

        break;
    }
    }
}

Для тестов были созданы 4 файла:

Код
Название   Размер
Тест 1     1028299
Тест 2     101600
Тест 3     10081
Тест 4     1010

Содержимое каждого файла представляет собой сериализованный массив, заполненный случайными значениями. Размеры их, как видите, приблизительно равны 1МБ, 100кБ, 10кБ и 1кБ. В каждом тесте каждая система тестировалась с каждым из этих файлов.Тесты.
    Заранее говорю, что тесты искусственные. К реальности приближен только третий тест, но и у него временами были трудности с точностью измерения очень малых промежутков времени. Главное здесь - в сравнении работы четырех подопытных кэш-систем в одинаковых условиях.
    Для большей наглядности я добавил к тестируемым кэш-системам еще и простое чтение файла. В первом тесте их было два:
    • Открытие файла, запись, перемещение позиции на начало, чтение, закрытие.
    • Открытие файла, запись, закрытие и последующее чтение функцией file_get_contents().
    Для остальных тестов использовалось только чтение файла функцией file_get_contents().
Тест первый. Зверский.
    Алгоритм теста такой: в кэш загружается пара ключ-значений и тут же считывается. Операция многократно повторяется. Контрольное время замеряется до и после цикла. Тест повторяется пять раз в течение одного запуска тестового скрипта. Результатом будет среднее значение этих пяти замеров.
    Я подумал, что если размеры тестовых данных уменьшаются в десять раз от файла к файлу, то и число повторов тестовой операции стоит повышать в десять раз при переходе к следующему файлу. Для файла "Тест 1" было выполнено 10 повторов. Соответственно, для файла "Тест 4" - 10000.
    Результаты тестирования представлены в таблице. Время - в секундах.
Код
Система       Тест 1 Тест 2 Тест 3 Тест 4
Файл 1        2.336 2.561 2.191 5.407
Файл 2        2.571 2.128 3.088 8.406
eAccelerator  0.432 0.402 0.338 0.475
APC           9.699 10.036 10.264 13.970
XCache        0.482 0.946 0.928 1.521
Memcache      3.918 3.508 3.650 4.804

В графическом виде это выглядит так:
user posted image
Сначала протестировал работу с файлами, eAccelerator, APC и Memcache, а когда перешел к XCache, то скрипт стал аварийно завершаться. В логах Апача было сообщение о нехватке памяти. Увеличил размер с 16 до 32 МБ и повторил эксперимент: опять падение. 128 МБ - тоже. 192 - опять. На 200 МБ скрипт отработал до конца без ошибок. Вот такой вот он - XCache. Пришлось проводить тест для всех систем заново, с едиными условиями. При этом время работы всех систем, кроме Memcache, серьезно сократилось: в 1.5-2 раза. Видимо, за счет уменьшения работ по сборке мусора.
Поразила скорость APC: в 2-4 раза медленнее, чем работа с файлами. Memcache тоже оказался не на высоте. eAccelerator, похоже, даже не заметил разницу: что 1 МБ, что 1 кБ, что 10 циклов, что 10000.Тест второй. Многократное чтение.
    На следующий день я поискал в интернете впечатления других людей об APC - аутсайдере моего теста и, что интересно, ничего плохого не нашел. Поэтому я решил провести еще один тест, более приближенный к реальности. За основу взял первый тест и изменил алгоритм: считывается тестовый файл, помещается в кэш и в цикле считывается. Время измерялось до функции чтения и после, помещалось в массив, а после цикла производилось усреднение результата. Количество циклов было аналогично первому тесту: от 10 до 10000.
    Результаты представлены в таблице. Время - в секундах.
Код
Система        Тест 1  Тест 2          Тест 3          Тест 4
Файл           0.121911         0.008692        0.001274        0.000242
eAccelerator   0.025335         0.002391        0.000201        0.000025
APC            0.099481         0.008770        0.001281        0.000173
XCache         0.064841         0.006181        0.000710        0.000092
Memcache       0.109873         0.010685        0.002072        0.001027

Графическое представление, к сожалению, менее наглядно - цирфы говорят здесь лучше.
user posted image
На больших объемах хорошо видно, кто первый, а кто отстающий. На малых размерах разница не столь велика. Лидеры, по-прежнему, eAccelerator и XCache, APC и Memcache работают чуть быстрее, чем работа с файлом (надо понимать, что файл считывался не с диска, т.к. Linux кэширует файловые операции).
Что интересно, здесь у XCache тоже были проблемы с нехваткой памяти, поэтому опять было выделено 200 МБ на процесс.Тест третий. В погоне за реальностью.
    Второй тест меня тоже не убедил, и я решил сделать замеры одиночных запросов в кэш (как в реальной работе сайта): всего четыре запроса на один запуск скрипта. Это чтобы ликвидировать возможное кэширование в php или какие-то подобные процессы.
    Для этого сначала запускался скрипт, который считывал все четыре файла и помещал их в кэш с разными ключами. Потом многократно запускался скрипт, который производил считывание из кэша всех четырех блоков данных и замер времени на каждое чтение.
    Точность замеров очень плохая. Порой результат был - ноль. Еще я подметил, что после рестарта Апача первые 5-7 замеров для всех систем были большими, а потом сокращались в 2-3 раза. Чтобы компенсировать этот эффект, результаты первых 10 запусков я отбрасывал, а следующих 10 - записывал и потом усреднял. Все равно результаты приблизительные. Я оцениваю их точность - плюс-минус 10%.
    Результат показан в таблице. Время - в микросекундах.
Код
Система         Тест 1  Тест 2  Тест 3  Тест 4
Файл            76934   26083   2807    721
eAccelerator    90      7       6       6
APC             181     64      57      60
XCache          251     15      14      12
Memcache        167515  27784   3164    1264

Чтобы графическое представление не было таким же неинтересным, как и во втором тесте, убрал полных аутсайдеров: работу с файлами и Memcache.
user posted image
В лидерах, по-прежнему, eAccelerator и XCache. Даже помня о точности замеров, не приходится сомневаться, что APC работает в несколько раз медленнее, чем eAccelerator, а XCache плохо переваривает большие объемы данных.Заключение.
    Как поведут себя эти кэш-системы в реальных условиях, предсказать трудно - ведь эти условия могут быть очень разными и не иметь ничего общего с моими тестами. По крайней мере, тесты подняли на поверхность некоторые недостатки, о которых полезно будет знать.
Источник: http://club.shelek.ru/viewart.php?id=300 :bully:



Спустя 10 дней, 18 часов, 48 минут, 32 секунды (16.04.2009 - 17:00) Kuzya написал(а):
Супер! Большое спасибо! Остались ещё люди способные грамотно анализировать информацию. Статья пришлась очень кстати. Для оптимизации кода недавно выбрал eAccelerator, теперь ещё и убедился в хороших качествах его системы кэширования.

Спустя 9 минут, 47 секунд (16.04.2009 - 17:10) jetistyum написал(а):
Остались ещё люди способные грамотно анализировать тупо копипастить информацию.

Спустя 4 часа, 53 минуты, 56 секунд (16.04.2009 - 22:04) Kuzya написал(а):
Я думал это его родная аналитика. Выложите пожалуйста ссылку откуда скопипастено, а то в таком виде обвинения голословны.

Спустя 2 часа, 27 минут, 12 секунд (17.04.2009 - 00:31) jetistyum написал(а):
Кузя, я не собираюсь никому ничего доказывать smile.gif
найти источник можно за три секунды. гуглить умеешь?

Спустя 10 часов, 1 минута, 36 секунд (17.04.2009 - 10:32) apc написал(а):
а что такого что статья скопирована??? с таким же успехом пусть все матиматику придумывают заново не*рен копировать чужиет труды biggrin.gif

Спустя 2 часа, 23 минуты, 16 секунд (17.04.2009 - 12:56) jetistyum написал(а):
с таким же успехом я начну копипаситить сюда серию самоучителей по программированию, а страницы форума навечно в сапплименты вылетят... ктомуже принято делиться чужой информацией не посредством копипаста, а посредством предоставления ссылки.
на счет математики:
а что, на всех математических форумах копипастятся труды по математике?

Спустя 22 минуты, 23 секунды (17.04.2009 - 13:18) apc написал(а):
вы неврно меня поняли, а спорить на эту тему я ненамерен.

Спустя 44 секунды (17.04.2009 - 13:19) sergeiss написал(а):
Цитата (jetistyum @ 17.04.2009 - 12:56)
с таким же успехом я начну копипаситить сюда серию самоучителей по программированию, а страницы форума навечно в сапплименты вылетят... ктомуже принято делиться чужой информацией не посредством копипаста, а посредством предоставления ссылки.
на счет математики:
а что, на всех математических форумах копипастятся труды по математике?

Согласен целиком и полностью!

Норма - это дать ссылку и к ней краткое описание, либо небольшой кусочек текста из статьи. Чтобы было понятно, о чем идет речь.

Спустя 11 минут, 43 секунды (17.04.2009 - 13:31) apc написал(а):
Цитата (sergeiss @ 17.04.2009 - 10:19)
Цитата (jetistyum @ 17.04.2009 - 12:56)
с таким же успехом я начну копипаситить сюда серию самоучителей по программированию, а страницы форума навечно в сапплименты вылетят... ктомуже принято делиться чужой информацией не посредством копипаста, а посредством предоставления ссылки.
на счет математики:
а что, на всех математических форумах копипастятся труды по математике?

Согласен целиком и полностью!

Норма - это дать ссылку и к ней краткое описание, либо небольшой кусочек текста из статьи. Чтобы было понятно, о чем идет речь.

я понял вас так зацепило именно наличие всей статьи)) ну в принципе можно было одну ссылку оставить....
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.