Целесообразность memcache

Здравствуйте Уважаемое Сообщество!

В первую очередь хочу поделиться положительными эмоциями. Довольно давно я не заходил сюда. Не могу наверняка сказать, по каким причинам, но сейчас я невероятно удивился тому, что увидел на новом сайте сообщества MODx. Тов. @Fi1osof, тов. @Carw и др. участники, кто принимал участие в модернизации этого проекта — Вы просто молодцы. +10 каждому в карму.

Теперь по существу созданной мной темы. Постараюсь сформулировать все четко и понятно. Ибо тяжело сосредоточиться на основной мысли. Вопросов и мыслей накопилось довольно много.



Дано:
Сайт www.kinobin.ru
Около 20 000 документов
Около 500 000 строк в таблице TV параметров
Сервер: Intel Core 2 Quad Q6600 2.40, 8 Гб ОЗУ

— Так получилось, что сайт изначально (около года назад) я начал делать на MODx Evo и переделать его на Revo не было то ли времени, то ли желания. Наверняка сказать не смогу. При малом количестве документов (1000), все было отлично. Сниппет Ditto справлялся со своей задачей. В определенный момент времени, на сайт было добавлено еще 5000 документов. Конечно же начались «тормоза». (тогда еще сервер был слабеньким VPS). Пробовал готовые сниппет (CacheAccelerator и т.п.) До определенного количества посетителей и числа документов все работал НЕстабильно. С этим надо было что то делать. Появилась идея написать свой сниппет вывода документов. Написал. Кеширования в сниппете не было никакого (совсем). В любом случае, он показывал документы так как мне надо и быстрее того же Ditto с его кешированием. Буквально через пару часов решил сделать кеширование. Так как сайт был довольно посещаемый, надо было все делать быстро. Решил на первое время сделать самый обычный файловый кеш.

Вывод содержимого записываем в файл с название md5('название страницы')
Проверяем, создан ли такой файл. Выводим из него контент. Если не создан, создаем. Все просто. Никаких проверок на дату создания, изменения содержимого и т.п.


Сайт стал снова работать прекрасно. 0,0300 сек. загрузка страниц. (могу ошибаться. точно не могу вспомнить)
Само собой, после нескольких суток работы этого сниппета, в папке с кешем скопилось громадное количество файлов и еще много всяких проблем появилось.
Опять начал искать решение. Вспомнил про memcache. Про этот сервис кеширования данных слышал довольно давно. Сам никогда не пользовался (только что устанавливал его на vps в связке с LiveStreet).

Прикручивание к себе.
1. Поставил я себе на сервер memcache
1. Комментировал строки с файловым кешем :) 
2. Добавил класс подключения к memcache. В нем функции сохранения, проверки, получения данных (вывода), удаления.
Далее по тому же принципу, что и файловый кеш работал: 
Вывод (уже со всеми тегами) из БД пишем в кеш (только теперь ставим время жизни кеша 24 часа).
Далее функционал проверки на уже созданный кеш, функционал проверки на изменение данных. Если данные в выводе поменялись, перезаписываем кеш, если нет просто выводим из кеша.


Мои мысли тогда...
Размер одной такой записи в кеш примерно около 20-25 килобайт. Если даже все страницы сайта (вместе с постраничной навигацией закешируются у меня в памяти. а это около 50 000 страниц) то ОЗУ хватит вполне. При 8Гб памяти, выделить под это дело 6Гб. Так что будет возможно сделать около 246000-307200 записей. Ну а на будущее, можно расширить память до 16 ГБ (например на одном сервере).

Сейчас все работает так как мне надо. Скорость загрузки сайта приемлемая.
Очень хочется узнать конструктивное мнение сообщества на эту тему.

19 комментариев

avatar
Как по мне все целесообразно вы выполнели поставленную задачу
а с учетом что все работает как нужно есть ли смысл переносить все на REVO
и тратить на это силы?
avatar
Думаю, пока смысла переносить нет. Тестово пробовал создавать 200 000 документов. Все работает точно также. Никаких тормозов не увидел. Даже при первом обращении к БД, а не к кешу. Единственный минус, это родной кеш MODx Evo. Он то и умер у меня при 200 000 документов в дереве. Так как siteCache.idx.php слишком большой. Я еще с этим не придумал что делать. P.S. Фильмы выводятся нормально, а редактировать средствами родной админ панели при таком количестве невозможно :)
avatar
Вай столько в дерево это жесть
были тут решения как разбить его на несколько файлов
— искать по запросу modx 16000
avatar
Да тут даже не в дереве. Я как то с самого начала практически не использовал админку MODx, но все же иногда кеш чистить приходится… а в случае с 200 000 httpd рухнет
avatar
Dmi3y, я так понял Fi1osof сейчас склоняется к Revo, но у меня сейчас Evo. Так вот вопрос… Вы слышали что нибудь про японскую сборку Evo? Тестировали ли ее?
avatar
Тестировал японскую версию собстнно я ее и переводил на русский

они там много месту улучшили но так же и изменили немного API
тоесть не все равботеат как раньше некоторые вещи отказываются работать и требуют переделки

пока в свою сборку оттуда таскаю плюшки некоторые
avatar
Немного поделюсь своим опытом организации кеширования страниц в Рево.
Начну с того, чтобы посетовать на какие-то минусы в базовой системе кеширования документов в MODX. Лично я вижу проблему в том, что для кешируемых MODX-документов создаются кеш-файлы для КАЖДОГО документа в отдельности. То есть если у вас около 20 000 документов, значит будет 20 000 файлов кеша. Но это не суть сама беда. Сама беда кроется в том, что если мы нативно на уровне шаблонов будем управлять кешированием отдельных элементов документа на базе синтаксиса [[!no_cached]] и [[cached]], то это будет играть роль только на уровне каждого отдельного документа. Что я имею ввиду?
Допустим, у вас есть главное меню. Вы пишите [[Wayfinder]]. То есть предполагается, что после того, как страницу посетят и отработается этот сниппет, и кеш результата будет сохранен, то при повторном посещении данной страницы этот сниппет не будет повторно вызван. Да, это так. Но только на уровне конкретно этого документа. Когда человек перейдет на другую страницу, на которой еще никто не был, и для которой кеш еще не создан, то такой сниппет опять будет вызван на выполнение, а его результат будет сохранен в кеше конкретной страницы. И так все 20 000 страниц… И это в то время, как результат этого сниппета может быть абсолютно идентичен для всех страниц.
Вот почему я в первую очередь не люблю управление кешированием элементов на уровне парсера MODX. (сразу оговорюсь, что речь идет о крупных проектах. Если это визитка на 30 страниц, вообще на все пофигу).
И лично я предпочитаю управление кешем через $modx->cacheManager.
Но это на уровне PHP. И как раз здесь лично для меня вырисовывается еще один базовый минус MODX (опять-таки, пусть никто мне не говорит, что это все можно исправить, создав свой тип ресурсов, расширив базовые, перегрузить класс modRequest и т.п., я тоже знаю много таких способов, мы сейчас говорим о базовом функционале): этот минус — невозможность сразу вызвать php-код. То есть создавая MODX-документ, назначаем мы для него шаблон, или нет, в любом случае у нас идет обработка на уровне разбора HTML-кода на уровне парсера. То есть чтобы выполнился наш php-код, так или иначе все равно приходится вставлять [[snippet]], в котором выполняется наш php-код.
По этой причине большинство моих шаблонов содержат только один сниппет: [[!diz?file=`file`]]
Это сниппет вызывает php-файл из моей папки шаблонов. А там уже реализуется логика шаблона.
Поясню: страница как правило состоит из нескольких частей (шапка, подвал, сайдбары и т.п.). И в зависимости от конкретного сайта это могут быть как полностью статические блоки, так и обновляемые с заданной периодичностью или в риал-тайм. И здесь важно не только создавать или не создавать кеш, но и делать это индивидуально для каждого блока в отдельности.
А все эти блоки потом набивать в конечный чанк шаблона, или в Smarty-шаблон, кому как нравится.
То есть в примере выше я бы поступил так:
// Ключ кеша меню
$menu_key = 'menu';

// Создаем ключ для индивидуального раздела. То есть чтобы был раздельный кеш для разных разделов
$films_key = 'films_'.  implode("_", $params); // Или md5(), как хочется. 

// Получаем меню из кеша
if(!$menu = $modx->cacheManager->get($menu_key)){
	$menu = $modx->runSnippet('Wayfinder', array(
		siteStart => 0,
		level => 1,	// etc.
	));
	// или создаем кеш без ограничения по времени
	$menu = $modx->cacheManager->set($menu_key, $menu, 0);
}

// Получаем фильмы
if(!$films = $modx->cacheManager->get($films_key)){
	$films = $modx->runSnippet('getFilms', array());
	// или создаем кеш без ограничения по времени
	$films = $modx->cacheManager->set($films_key, $menu, 300); // указываем нужный срок жизни кеша
}

// return или print в зависимости от того, как реализован вызов файла и вывод  результата
return $modx->getChunk('base_template', array(
	'menu' => $menu,
	'films'	=> $films
));

По сабжу: не совсем уловил, с использованием memcached реализован ли механизм кеширования отдельных элементов страницы, или все страница кешируется?
avatar
не совсем уловил, с использованием memcached реализован ли механизм кеширования отдельных элементов страницы, или все страница кешируется?

Полное кеширование работает так:
— Шаблон и остальные выводы (меню и т.д.) кеширует сам MODx (в свой кеш).
C этим я думаю проблем нет. У меня один и тот же шаблон для этих страниц. Ничего не меняется.
— Вывод списка фильмов кеширует memcache (надеюсь Вы поняли что я имею ввиду)

То есть я кеширую только выборку.
Сейчас кратко опишу скрипт:
Грубо говоря в сниппете 2 функции filter и content

в content 2 условия
1. выводить фильмы всем списком (с постраничной навигацией)
2. выводить определенные ID (с постраничной навигацией)

filter принимает get
Например хочу вывести фильмы 2012 года
В функции filter запрос к modx_site_tmplvar_contentvalues
return id'шников с этой переменной.
далее в content подставляем эти ID и выводим

Вот этот выход я и кеширую. Вернее кеширую уже обработанный сниппет с плейсхолдерами… но это опустим. не самое важное.

Мне больше хотелось узнать или понять, стоит ли memcache «отдавать» такие тяжелые (20 кб) данные !? Или они не тяжелые !? Опять я запутался… Или Вас не понял.
avatar
Мне больше хотелось узнать или понять, стоит ли memcache «отдавать» такие тяжелые (20 кб) данные !? Или они не тяжелые !? Опять я запутался… Или Вас не понял.
В целом ваш и мой механизм похожи, просто средства где-то разные используем (в частности вас плюс ко всему используется еще и memcached). Но на счет стоит или не стоит что-то отдавать что-то в memcached, хотелось бы услышать мнение экспертов в области memcached. Я таковым не являюсь. Для меня memcached не является явным. При использовании файлового кеша я вижу сколько файлов хранится, какая структура, какой объем информации. Мне легче прогнозировать поведение кеша, где оптимизировать и как, когда и сколько очищать при обновлении той или иной информации. Так как ни разу не сталкивался с тем, чтобы какой-то мой проект тормозил из-за того, что не хватает штатных средств MODX, то не приходилось смотреть по сторонам.
Вероятно, было бы очень хорошо, если бы кто-то написал подробную статью о его опыте работы с memcached, мониторингу процессов и памяти и т.п.
Для меня еще плюс файлов в том, что не происходит накопления информации в памяти, так как после того, как кеш получен и информация выведена, память очищается. В случае же с memcached я вижу только один вариант — memcached restart.
avatar
Понял. Спасибо. Про мнение экспертов memcached согласен на 100%. В любом случае очень рад был выслушать любое мнение. Несколько минут назад на хабре прочитал статью на тему memcached. Пришел к выводу, что в моем случае memcached целесообразен.
Насчет:
Для меня еще плюс файлов в том, что не происходит накопления информации в памяти, так как после того, как кеш получен и информация выведена, память очищается. В случае же с memcached я вижу только один вариант — memcached restart.
Немного Вы не поняли, или опять я Вас не понял. С memcached кеширование аналогично файловому кешу. Есть функция удаления по ключу.
А вообще после 24 часов при любом! обращении к кешу, ключи с expired 24H очищаются. (это я так сделал. можно вообще их не очищать, если не было изменений в БД)

Теперь осталось только перейти на Revo ветку, чтобы кеширование остального контента было «правильным».
avatar
Немного Вы не поняли, или опять я Вас не понял. С memcached кеширование аналогично файловому кешу. Есть функция удаления по ключу.
А вообще после 24 часов при любом! обращении к кешу, ключи с expired 24H очищаются. (это я так сделал. можно вообще их не очищать, если не было изменений в БД)
Вот как раз поэтому писал «Вероятно, было бы очень хорошо, если бы кто-то написал подробную статью о его опыте работы с memcached, мониторингу процессов и памяти и т.п.». Как раз и хотелось бы знать, что есть в кеше, а чего нет. И как реализован механизм по заданию времени кеша, то есть что-то хранить 24 часа, а что-то 5 минут. Я ни в коем случае вам не хочу в чем-то переубедить. Я наоборот говорю, что как раз эта сторона вопроса для меня темная. Может быть есть хорошие средства для мониторинга всего этого дела, и думаю, есть наверняка. Просто из-за отсутствия потребностей не копал в эту сторону.
Кстати, еще один момент: в вашем проекте еще серьезный пласт занимает поиск. А вот здесь хоть я раньше и не работал со Sphinx, я бы покапал именно в эту сторону, потому что одно дело закешировать результат, другое дело выполнить быстрый поиск, так как вариантов поиска у вас очень много.
avatar
Блин, очень приятно общаться и делиться опытом с человеком, который знает о определенных моментах… (эмоции)

Я использовал поиск sphinx. Когда то написал даже пост на эту тему community.modx-cms.ru/blog/tips_and_tricks/7060.html
С того момента много чего добавлено в поиск… Но я не выкладывал. никому было не интересно, я и забил.
Работает система корректировки ошибок (API api.yandex.ru/speller/)
+ memcached кеширование результатов. Вообщем если интересно, могу поделиться.
avatar
Спасибо за лестное слово!:-)
С одной стороны интересно, конечно поделитесь.
С другой стороны подписываюсь под комментом Димы. Если все работает, то не надо ничего переделывать. Первое правило программиста: «Работает — не лезь!». Так как судя по всему все работает, и вполне грамотно. Без лишней надобности не стоит лезть.
Хотя я бы вот такой момент отметил: большинство своих проектов я продумываю так, чтобы проект рос за счет деятельности самих пользователей. В вашем проекте наверняка появятся манагеры, модеры и т.п., а значит появится необходимость вводить настройки прав доступов. Вот в этом плане Эво серьезно проигрывает Рево, так как в Рево можно каждый чих проконтролировать. А новые «классные» процессоры позволяют выполнять те действия, которые требуют проверки прав, без перегрузок пользователей и прочих хаков.
комментарий был удален
комментарий был удален
комментарий был удален
комментарий был удален
комментарий был удален
комментарий был удален
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.