Работа с кэшерами в Revolution
Не все знают, что MODX Revolution умеет работать с разными системами кэширования, для чего применяет следующие классы:
Установка
Рассказывать буду про php-apc, ибо мне он нравится больше всего. Его легко установить и запустить. К тому же, он может войти в ядро php6. К тому же, про установку memcached я уже рассказывал.
Еще особенность: php-apc кэширует скомпилированный php код, а не только пользовательские данные. Это сильно экономит память и повышает отзывчивость.
Ставим на нашу обычную Ubuntu:

Опции cache_prefix нет, по умолчанию, ее нужно создать. Это опция контекста, и если у вас на сайте их более одного — нужно писать в настройки контекстов. Также это необходимо, если вы хостите более одного сайта, пускай и с одним контекстом у каждого.
Иначе, все данные будут кэшироваться без уникального префикса, и на одном сайте вылезет кэш от другого. Будет не круто, уверяю.
Использование
Вот тут самое сладкое — ничего. делать не нужно. Вы указали класс-обработчик для кэша, префикс для ключей и дальше MODX работает за нас, как обычно.
Волшебство!
Мы можем использовать специальные директивы глобально в apc.ini. Обратите особое внимание на apc.shm_size — это объем памяти для apc.
Некоторые параметры, типа apc.cache_by_default, можно использовать в конфиге определенного сайта php5-fpm.
Еще в комплекте идет полезный скрипт — он находится в /usr/share/doc/php-apc/apc.php.gz. Можете скопировать его в секретную директорию на сайте и разглядывать статистику. Если в файле задать пароль для авторизованного юзера, то можно видеть более подробную информацию и чистить кэш.

Результаты
Сразу после установки php-apc все php скрипты начинают работать быстрее. Но лично я столкнулся с разными глюками при работе с сессией в miniShop — она кэшировались. Поэтому долгое время не пользовался этим прекрасным кэшером, во избежание.
Разгадка крылась в том, что я не включал нужный обработчик, а пользовался стандартным на файлах (xPDOFileCache). Отсюда был глюк — от моей невнимательности.
Сейчас на modx-minishop.ru php-apc включен, и никаких проблем с корзиной нет.
Поэтому, если на сервере установлен php-apc — или отключайте его у сайта (через .htaccess, конфиг php), или включите правильный обработчик.
Помимо прочего, ваши сайты будут кушать меньше оперативки, быстрее отзываться и держать гораздо большую нагрузку.
Советую прочитать вот эту заметку, учитывая, что там есть неточность — данные хранятся не в файлах, а в памяти. Там очень хорошо описан сам принцип opcode-кэшеров.
На MODX Cloud, насколько я знаю, php-apc установлен по умолчанию.
- xPDOFileCache — стандартный обработчик по умолчанию, хранит кэш в файлах.
- cache.xPDOAPCCache — обработчик для расширения php-apc
- cache.xPDOMemCached — обработчик для memcached. Есть заметка про него
- cache.xPDOMemCache — обработчик для memcache.
- cache.xPDOWinCache — обработчик для wincache. Это для windows хостингов, на IIS.
Установка
Рассказывать буду про php-apc, ибо мне он нравится больше всего. Его легко установить и запустить. К тому же, он может войти в ядро php6. К тому же, про установку memcached я уже рассказывал.
Еще особенность: php-apc кэширует скомпилированный php код, а не только пользовательские данные. Это сильно экономит память и повышает отзывчивость.
Ставим на нашу обычную Ubuntu:
sudo apt-get install php-apc && sudo service php5-fpm restartАктивируем в настройках MODX:
Опции cache_prefix нет, по умолчанию, ее нужно создать. Это опция контекста, и если у вас на сайте их более одного — нужно писать в настройки контекстов. Также это необходимо, если вы хостите более одного сайта, пускай и с одним контекстом у каждого.
Иначе, все данные будут кэшироваться без уникального префикса, и на одном сайте вылезет кэш от другого. Будет не круто, уверяю.
Использование
Вот тут самое сладкое — ничего. делать не нужно. Вы указали класс-обработчик для кэша, префикс для ключей и дальше MODX работает за нас, как обычно.
Волшебство!
Мы можем использовать специальные директивы глобально в apc.ini. Обратите особое внимание на apc.shm_size — это объем памяти для apc.
Некоторые параметры, типа apc.cache_by_default, можно использовать в конфиге определенного сайта php5-fpm.
Еще в комплекте идет полезный скрипт — он находится в /usr/share/doc/php-apc/apc.php.gz. Можете скопировать его в секретную директорию на сайте и разглядывать статистику. Если в файле задать пароль для авторизованного юзера, то можно видеть более подробную информацию и чистить кэш.

Результаты
Сразу после установки php-apc все php скрипты начинают работать быстрее. Но лично я столкнулся с разными глюками при работе с сессией в miniShop — она кэшировались. Поэтому долгое время не пользовался этим прекрасным кэшером, во избежание.
Разгадка крылась в том, что я не включал нужный обработчик, а пользовался стандартным на файлах (xPDOFileCache). Отсюда был глюк — от моей невнимательности.
Сейчас на modx-minishop.ru php-apc включен, и никаких проблем с корзиной нет.
Поэтому, если на сервере установлен php-apc — или отключайте его у сайта (через .htaccess, конфиг php), или включите правильный обработчик.
Помимо прочего, ваши сайты будут кушать меньше оперативки, быстрее отзываться и держать гораздо большую нагрузку.
Советую прочитать вот эту заметку, учитывая, что там есть неточность — данные хранятся не в файлах, а в памяти. Там очень хорошо описан сам принцип opcode-кэшеров.
На MODX Cloud, насколько я знаю, php-apc установлен по умолчанию.
Обновлено 17.12.2014
Важное уточнение по поводу инициализации настроек кэширования — в комментарии ниже.Комментарии: 167
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
Наслышенна тема, но я с ней сталкнулся только на локалке. у меня стоит локальный веб сервер MAMP и в нём по дефолу 3 вида кэша (XCache, eAccelerator и Alternative PHP Cache (APC)) и поигравшись сними я прозрел от APC. После чего дал идею тебе попробовать в живую (хитёр я!!!!, нет просто у меня и так кэшами был апач загручен, а сейчас перенёс всё на nginx и уже после того, как ты подтвердил — всё класс!, установил и себе).
Может, php-apc уже был установлен?
Может, php-apc уже был установлен?
Итог: Было ~12Мб на главной странице, сейчас 5,34Мб
И все запросы и блоки отрендеренные писать также в оперативку?
По htop разницы в потреблении памяти не заметил. Объем выделенной памяти можно настроить в apc.ini. По умолчанию — 32M.
Редко используемые данные не обязательно вообще в кэше хранить.
Для меня самообучение дает больший эффект чем поспрашивать))) Это просто для общей информации спросил
Имею ввиду вот такие
Пишем в кэш /core/cache/my_cache_dir
$modx->cacheManager->set($id, $collection, 86400, array(xPDO::OPT_CACHE_KEY => 'my_cache_dir'))
Получаем данные из кэша /core/cache/my_cache_dir
$collection = $modx->cacheManager->get($id, array(xPDO::OPT_CACHE_KEY => 'my_cache_dir'))
Методы set, get и прочие — расширены. Смотри исходники по ссылке в начале.
Есть разные обработчики кэша. Если ты включаешь cache.xPDOAPCCache — то все методы работают с ним. Хочешь файлов — гоняй стандартный xPDOFileCache.
Хочешь и то и то — пиши свой обработчик или при кэшировании юзай функции нужного кэшера.
Короче, напрягай фантазию — возможно все.
Методы writeFile написаны для xPDOFileCache, и их никто не мешает использовать. Только зачем?
Система и так умно хранит в файлах настрjйки менеджера, системы и еще по мелочи.
В общем, я заметку написал — а ты развлекайся =)
Вот статья для ознакомления modx.com/blog/2012/09/24/using-memcached-for-modx-caching/ Там, как видно, Jason Coward кэширует разные элементы в разные истансы memcached, точно также можно и разные классы прописать.
$modx->cacheManager->set($id, $collection, 86400, array(xPDO::OPT_CACHE_KEY => 'my_cache_dir'));
Если ты создашь настройку my_cache_dir_cache_handler=xPDOFileCache
То он будет кэшировать в файлах, остальное куда указывает cache_handler
$modx->cacheManager->set('key123', $str, 3600, array(
xPDO::OPT_CACHE_KEY => 'blablabla',
xPDO::OPE_CACHE_HANDLER => 'xPDOFileCache')
);
Сохранит в файлах
$modx->cacheManager->set('key123', $str, 3600, array(
xPDO::OPT_CACHE_KEY => 'blablabla',
xPDO::OPE_CACHE_HANDLER => 'cache.xPDOMemCache',
'blablabla_memcached_server' => 'localhost:11211'
)
);
Сохранит в memcached
Хотя это все насколько я помню, нужно все перепроверять.
$modx->cacheManager->set('key123', $str, 3600, array(
xPDO::OPT_CACHE_KEY => 'my_cache_key',
xPDO::OPT_CACHE_PATH => 'my/cache/path'
)
);
И в настройках cache_handler указать my_cache_key_cache_handler = xPDOFileCache
Fi1osofclass xPDOAPCCache extends xPDOCache
Внутри все методы cacheManager, переопределенные для работы с APC.
https://github.com/modxcms/revolution/blob/develop/core/xpdo/cache/xpdoapccache.class.php
Как это оно работать не будет, когда оно для того и придумано?!
i45.fastpic.ru/big/2012/1015/cf/85d1d5879647384e1047a49e54d709cf.png
Нравится мне синтаксис Питона.
Из PHP фреймов щас щупаю FuelPHP
Сначала глубоко поучил PHP, потом стало скучно — полез читать про другое. Но значительных прелестей не обнаружил и пока забросил.
Как встречу что-то, чего не могу (но должен) сделать на PHP — вернусь к обучению.
Пока все силы предпочитаю тратить на работу с PHP в целом, и MODX Revolution, в частности — так каждый день открытия.
P.S. А кто такой Valikras?
Fi1osofЕсли тебе нужен именно файловый кеш-манагер (мне такое часто надо, не смотря на то, что используется мем-кешер, просто для того, чтобы что-то в файлы записывать и не заморачиваться с наличием директорий:)), то ты можешь несколько вариантов использовать.
Самый простой — это просто через $modx->getService() или new $className() (это ты и сам знаешь), но есть более правильный путь — юзать $modx->cacheManager->getProvider(). Просто MODX умеет одновременно работать с несколькими провайдерами. При этом есть вот такой вариант:
Здесь ты работаешь с объектом конкретного кеш-провайдера. Обрати внимание в передаваемых параметрах: ключ провайдера является префиксом для параметра в массиве. file_cacher_key file_cacher_key_cache_handler. Ключ можно любой указывать, но правило соблюдать надо (только обязательно указывать и не default, иначе будет возвращен текущий кеш-провайдер, так как default — это его ключ в массиве провайдеров кеш-манагера).
Но в данном случае не совсем удобно то, что если будет желание еще в каком-то месте с ним поработать, то надо будет опять юзать getCacheProvider(). Вот другой вариант:
Здесь мы уже указываем ключ в методе set() самого кеш-манагера (само собой и в get() можем и т.п.). То есть метод $manager->getCacheProvider() получается своего рода регистратор кеш-провайдера, который можно один раз вызвать где-нибудь в плагине на OnHandlerRequest или типа того, а потом юзать стандарные set() И get(), просто указывая ключ файлового кеш-провайдера (или какой нужен).
После loadimpact.com/load-test/gadgets.lg.ua-68d6d7b1da2561b278d46aa9999e47aa
Загрузка страницы: 8,0703 s
Память: 7,14 Мб
8 сек это очень много
[[!msGetGoodsPlaceholders]], [[msGetGallery]], [[!LikeDislike]], [[getRelated]], [[TvList]], [[getViewed]] и еще несколько чанков. Проблему нашел: msGetGallery увеличивает загрузку на 4сек, getViewed еще где-то на 1.5с и getRelated 1.5с. Выключив всё это, результат 1сек без кэша.
https://loadimpact.com/load-test/gadgets.lg.ua-457ef3ef3a04cf92bdc21062b61c4f4c
После обработки страницы парсер MODX пишет затраченный микротайм в плейсхолдер [^t^] — он и выводится у меня в футере.
[Mon Oct 15 23:55:35 2012] [error] [client 95.28.49.19] PHP Catchable fatal error: Argument 1 passed to xPDOObject::load() must be an instance of xPDO, instance of modX given in /var/www/vhosts/site.ru/httpdocs/core/xpdo/om/xpdoobject.class.php on line 404, referer: www.site.ru/ap/?a=30&id=1
Также при обновлении кэша через админку останавливается на «Очистка основного кэша: mSearch».
А может быть просто надо было изменить класс в натройках Modx? Или это все таки косяк разработчиков? Если да — надо на форме попросить, чтобы они доработали скрипт для работы с php-apc.
Либо класс менять, либо apc отключать — одно из двух.
захожу в настройки MODX, выбираю «Статус сайта»=нет (ID страницы когда сайт недоступен установлен).
Делаю — очистить кэш, перехожу на главную странице (не авторизованным пользователем) — сайт доступен. Очищаю вручную (удаляю все из директории: /core/cache/), захожу на главную страницу — работает.
Ключ для кэша создан, Класс-обработчик системы кэширования: cache.xPDOAPCCache.
Посмотрел папку /core/cache/system_setting/
присутствуют 2 файла:
config.cache.php & [cache_prefix]_config.cache.php (cache_prefix=site19_).
Данные из файлов отличаются:
в config.cache.php 'site_status' => '1'
в [cache_prefix]_config.cache.php 'site_status' => '0'
В настройках системы Статус сайта=Нет.
Кнопку очистить кэш нажимал не один раз, но это не помогает.
Это у всех так или только у меня?
Вы с другого браузера заходите? вернее чтобы сессия не попала ваша если вы находитесь в админке.
Я не проверял с статусом сайта, но после изменения системных настроек, языковых файлов и.т.д., я всегда удаляю папку cache (к стате, самый быстрый способ очистить содержимое папки — в дереве файловой системы, просто удаляем папку core/cache она сразу автоматом создаётся с обновленными системными настройками.)
Вероятно это из-за того что выбран тип cache.xPDOAPCCache.
Еще я пытался «играться с настройками», заходил в контексты и создавал там параметр cache_prefix с (web & mrg — сразу и по отдельности) одинаковыми параметрами, в результате настройки сохраняются и без удаления core/cache, но опять же есть проблема, которая не позволяет это использовать, а именно:
«Иначе, все данные будут кэшироваться без уникального префикса, и на одном сайте вылезет кэш от другого. Будет не круто, уверяю.»
Т.е. у меня на 3 сайтах был 1 и тот же сайт.
На modx.com попадалась статья на англ. языке, из которой, как я понял опять же, эта проблема связана именно с типом кэша.
Если указать у web и mgr один префикс, и он будет уникальным для этого сайта — то должно работать.
А у другого сайта другие префиксы для mgr и web, но между собой одинаковые.
В любом случае, такой кэш надо включать на готовом сайте, во время разработки он только мешает.
А у другого сайта другие префиксы для mgr и web, но между собой одинаковые.»
Именно так и пытался сделать, сначала создается впечатление что все работает, но потом:
«Иначе, все данные будут кэшироваться без уникального префикса, и на одном сайте вылезет кэш от другого. Будет не круто, уверяю.»
Возможно это только у меня так, поэтому спросил у кого есть возможность проверить у себя на сайте, чтобы внести хоть какую-то ясность в это для всех.
Префикс пишу в системные настройки, не в контекст.
Когда заморочки с кэшем — удаляю /core/cache
Дальше разбираться пока времени нет.
Была проблема — кэш из админки не чистился при редактировании шаблонов/чанков, только ручное удаление. С правами всё нормально было, узнал что стоит нативный php-apc. Поставил cache.xPDOAPCCache и его префиск — всё стало отлично работать. Спасибо большое!
Сам сниппет и его плейсхолдер требуют не кэшированного вызова. Однако в параметрах есть настройки для кэширования. Попробовал их включить и вызвать getPage@paramName (paramName — пользователькие настройки).
Время генерации страницы на каталоге MS 1 c выводом 25 наименований упало с 0.7 до 0.18
В любом случае, это вина лежит на взаимодействии MODX с php-apc, ибо сам HA ничего не кэширует, а просто кладёт настройки с сессию обычным способом.
Попробуйте создать плагин на событие OnInitCulture
OnInitCulture конечно не совсем подходящее событие, но оно просто единственное, которое выполняется всегда, даже если MODX в API режиме. По крайней мере на MODXCloud это помогло.
1. Раскомментировал строку 2. Вернул стандартный класс обработчика в настройках xPDOFileCache.
3. Удалил префикс.
4. Почистил все кеши на всякий.
Но в итоге все равно redirect_uri_mismatch. А php-apc не отключается судя по php-info:
Василий, без твоей помощи не обойтись.
В phpinfo() он и не должен отключаться, если только вообще модуль не загружать — но так не надо, будет памяти больше уходить.
Пропиши в /index.php, если оно не там. Если и тогда не поможет — пришли данные от сайта на bezumkin@yandex.ru — погляжу.
Сейчас гоняю на cache.xPDOMemCached. Пока гут. Еще раз спасибо.
1. hybrid работает тока при ini_set('apc.cache_by_default', 0); в индекс файле. это разве не отключает кешер для всего сайта?
2. после регистрации пользователь автоматически не залогинивается и к тому же пароль на почту приходит в закодированном виде.
Не хотелось бы отказываться от этого кешера, т.к. работает шустро и развитие в любом случае будет. Василий, могли бы вы чем-нибудь помочь, подсказать где копнуть? Отключал кеширование БД и сессий (с удалением /core/cache/), но не помогает…
И не отображаются некоторые элементы на самом сайте, которые не кешируются (ну не должны которые) вроде как
Проверь, отпишись.
я быстро нашёл в поиске, что для этого нужно в index.php добавить ini_set('apc.cache_by_default', 'Off'); // Отключение кэширования php-apc
вставил, глюк пропал.
но ведь не может же быть, чтоб HybridAuth не мог в принципе работать с php-apc.
или мы добавив в индекс отключение apc.cache_by_default вырубаем его не для всей cms и по-этому можно юзать этот тип кеширования?
PHP Warning: PHP Startup: Unable to load dynamic library '/usr/lib/php5/20090626+lfs/apc.so' — /usr/lib/php5/20090626+lfs/apc.so: cannot open shared object file: No such file or directory in Unknown on line 0
ни ini_set('apc.cache_by_default', 'Off') в index.php
ни php_flag apc.cache_by_default off в .htaccess
ничего не помогает. Кеширует все наглухо…
если перевести modx с файлового кешера на apc — тоже результатов нет…
что еще можно попробовать?
Ну а если там все-таки php-apc, значит настройки сервера не дают сменить значение настроек скрипту — такое тоже запросто бывает.
Насчет opcache есть вот такие упоминания и все — joxi.ru/lOmuUv3JTJB-L7TmHuA
ОНО?
Так как странички реально морозятся на долгое время, кеш удалил — уже почти два часа прошло, а страницы так и не обновились.
2. Покажи-ка скриншот phpinfo() с параметром apc.cache_by_default?
2. joxi.ru/dO2uUhjKTJDzbqUswjo
Пиши в поддержку, пусть расскажут, что там еще накрутили.
префикс добавил, кэш вроде создается
но при очистки кэша из админки выдает
prntscr.com/55bvcp
что это?
удалить не возможно пока папку не снесешь с cache
вернул в настройки xPDOFileCache, префиксы удалять?
… тут немного предыстории, когда сайт еще только начал собираться для себя, все сниппеты вызывались некэшируемыми, и про это дело я забыл, когда ресурсов накопилось очень много, начал искать корень зла долгой обработки данных ДО 20 сек. и наткнулся на это статью, само собой все сделал как описано выше и поставил cache.xPDOAPCCache…
Вроде бы успокоился, но все-равно не мог успокоится по поводу выборки 3к-5к ресурсов за 1-3 секунды, начал рыть снова и уже основательно.
Поставил debugParser, по большой части данное дополнение всетаки заставило меня отказаться от чанков [[$header]] и [[$footer]] — хотя было очень полезно не лазить в каждый шаблон и править какие либо изменения. Далее debugParser показывал что mFilter2 работает медленно 0.6c (но оно и понятно 5к ресурсов, несколько ТВ-параметров в виде фильтров, getImageList + phpthumbon), следом шли pdoMenu и pdoPage 0.09-0.6c на каждого. В итоге все это дело выливалось в 1.0-1.7с парсинга страницы.
Читал, искал, как же все-таки быть, ведь без всего этого мне не обойтись… Пошел смотреть кэширование и проводить эксперементы.
Проверка при 3к ресурсах. Условия не меняю только меняю Класс-обработчик системы кэширования
А дальше самое интересное
1) xPDOFileCache
— первый запуск страницы
— второй запуск страницы
2) cache.xPDOAPCCache
— первый запуск страницы
— второй запуск страницы
3) cache.xPDOMemCached
— первый запуск страницы
— второй запуск страницы
4) cache.xPDOMemCache
— первый запуск страницы
— второй запуск страницы
5) ПУСТОЕ ПОЛЕ — Класс-обработчик системы кэширования
— первый запуск страницы
— второй запуск страницы
Лучше оптимизировать код, чем полагаться на эти кэшеры. Возможно, изменю своё мнение, если буду делать реальный hi-load проект, но пока что таких не было.
Во многих сниппетах pdoTools есть возможность указывать глубину выборки &depth, а в меню — уровень &level. Чем они меньше, тем быстрее будут работать.
Во многих сниппетах pdoTools есть параметр &showLog, который выводит подробный лог работы с таймингами и итоговым SQL запросом — нужно смотреть в него и думать, как ускорить, какими параметрами.
Где можно вызывать сниппеты кэшированными — обязательно вызывать их именно такими. Например меню, хлебные крошки.
В конце концов, какие-то места можно переписать на своих сниппетах, потому что pdoTools хоть и универсален, но не идеален.
Fi1osofНе знаю писал здесь кто или нет, не прочитал я все ~150 комментов, но есть такой момент, который у тебя в топике не описан: дело в том, что меняя кеш-хэндлер в настройках (и/или кеш-префикс), возникает проблема повторного использования кешера. Проблема эта связана с тем, что при инициализации MODX еще ничего не знает про твои настройки. Он инициализируется, получает дефолтовый файловый кеш-манагер (ведь он еще не прочитал настройки или кеш настроек, где указан иной кеш-провайдер) и только после того, как у него есть инфа по измененным настройкам кешера, он начинает юзать указанный кешер. Чтобы убедиться в этом попробуй через файловый манагер MODX-а удалить папку core/cache/. Если после удаления не увидишь ее или увидишь там только папку registry, то у тебя все ОК. А если увидишь несколько папок, включая system_seettings и context_settings, то тогда то, о чем я сказал.
На мой взгляд идеального управляющего механизма в MODX на этот счет нет и пока лучшее, что я нашел — это дублировать настройки кешера и префикса в конфиг MODX-а core/config/config.inc.php, там для этого специально заведен массив $config_options. Пишем там:
Вот тогда MODX сразу при инициализации уже будет знать какой кеш-провайдер использовать, и не будет юзать стандартный файловый.
Fi1osofДавно не пользуюсь кэшерами, потому что на моих небольших проектах от них больше проблем, чем пользы.
Fi1osofЭтот сайт у нас на хостинге, там нет никаких твиков — только стандартный PHP 5.5.
Fi1osofдобавить переменную, которая подхватывала бы префикс из настройки контекста?
Заранее благодарен за ответ.
Fi1osofFi1osofFi1osofFi1osofFi1osofFi1osof