Comments 60
я использую своего рода pull технологию – то бишь VIEW говорит контроллеру «вах, у меня тут кое-что кажется не из кеша – давай ка обновим»... правда в этом меня спасает кеш-блоки смарти, где в шаблоне можно указать какие блоки стоит кешировать а какие нет (и как долго). Например те же облака тегов и прочую лабуду я пересчитываю не чаще чем раз в час.
Я сейчас занимаюсь поддержкой уже готового проекта (крупный региональный портал с кучей сервисов и поддоменов), а тамошняя архитектура не позволяет так запросто использовать кэширование смарти, хотя я нашел выход, написав блок делающий обратное - кэширующий на определенное время... но к сожалению, в моем случае, это капля в море, именно поэтому хотел узнать может есть еще какие-то хитрости.
Я возможно плохо разбираюсь в серверном программировании, но по моему вам нужен memcache.
Ошибаетесь, memcached не использует форк. Он использует threads. Его главное приемущество в том что на нем можно построить распределенную систему кэширования -> на нескольких серверах. Тоесть если есть предположения что проект будет расти, то это подходящая технология.
Вобще советую вам более пристально глянуть. После того как facebook стал использовать memcached они очень хорошо его оптимизировали.
Вобще советую вам более пристально глянуть. После того как facebook стал использовать memcached они очень хорошо его оптимизировали.
На 5 шаге и нужно кэшировать данные — «Создать и записать html в файл».
Но! Если у Вас модульная система, то необходимо кэшировать каждый модуль в отдельности, так как вся информация одновременно вряд ли поменяется, а информация в отдельных модулях может меняться с разной периодичностью.
Но! Если у Вас модульная система, то необходимо кэшировать каждый модуль в отдельности, так как вся информация одновременно вряд ли поменяется, а информация в отдельных модулях может меняться с разной периодичностью.
я бы посмотрел исходники mvc-фрэймворков, там точно есть
В моем случае информация обновляется через 1-2 минуты, но с выводом можно подождать до 10 минут, так что мне хватает по времени.
Кстати, отслеживание обновления информации можно повесить на триггеры БД, если вдруг интересно.
А вот по поводу многих моделей - да, это выход, но мне кажется это уже какой-то странный мвц выходит... Конечно, две головы лучше, но мне кажется пропадает весь смысл... Хотя вам может и виднее
Кстати, отслеживание обновления информации можно повесить на триггеры БД, если вдруг интересно.
А вот по поводу многих моделей - да, это выход, но мне кажется это уже какой-то странный мвц выходит... Конечно, две головы лучше, но мне кажется пропадает весь смысл... Хотя вам может и виднее
Шитов в свое время подумал на эту тему: http://www.artlebedev.ru/tools/technogre… . И Золотухин приложился: http://www.artlebedev.ru/tools/technogre…
Например, джанга к делу кеширования подходит так: http://www.djangoproject.com/documentati…
Нужно смотреть код, как они кэшируют именно в приложении к MVC.
В статье просто описаны возможности системы по кэшированию.
Моя основаня проблема в данном вопросе состоит в том, что я не могу переписать весь код существующей системы, но могу писать дополнительные обертки для уже готового функционала. Именно поэтому я пытаюсь найти неординарные подходы.
За ссылку спасибо, уже кое-что подсмотрел для своих будущих проектов.
В статье просто описаны возможности системы по кэшированию.
Моя основаня проблема в данном вопросе состоит в том, что я не могу переписать весь код существующей системы, но могу писать дополнительные обертки для уже готового функционала. Именно поэтому я пытаюсь найти неординарные подходы.
За ссылку спасибо, уже кое-что подсмотрел для своих будущих проектов.
В Джанге бы это решилось так: есть у неё сигналы на PyDispatcher, и есть такой сигнальчик post_save который срабатывает при сохранении модели. Я вешаю на такие сигналы свою функцию, которая смотрит что за модель сохранили и обновляет её кеш.
Это штука обзывается еще каким-то паттерном, но я забыл название.
Думаю в вашем случае может пригодится :)
Это штука обзывается еще каким-то паттерном, но я забыл название.
Думаю в вашем случае может пригодится :)
Палю свое решение:
HTML-страница представляет собой иерархию объектов конкретных HTML-блоков. (Верхний объект инкапсулирует объекты вложенных блоков). Объекты HTML-блоков умеют сами себя кешировать. Метод getContent() возвращает HTML, при этом проверяется кеш. Если попадание - вернуть HTML, промах - отрендерить HTML, запросив модель, сохранить в кеше и вернуть HTML.
Кеширование реализовано многоуровневое - ускоряется рендеринг верхних блоков, так как нижние могут быть взяты из кеша.
Все очень быстро и довольно просто. Проверено в нескольких проектах.
HTML-страница представляет собой иерархию объектов конкретных HTML-блоков. (Верхний объект инкапсулирует объекты вложенных блоков). Объекты HTML-блоков умеют сами себя кешировать. Метод getContent() возвращает HTML, при этом проверяется кеш. Если попадание - вернуть HTML, промах - отрендерить HTML, запросив модель, сохранить в кеше и вернуть HTML.
Кеширование реализовано многоуровневое - ускоряется рендеринг верхних блоков, так как нижние могут быть взяты из кеша.
Все очень быстро и довольно просто. Проверено в нескольких проектах.
При переходе на рельсы увидел кеширование, но пока не разобрался с ним.
Весьма просто и доступно нашел тут:
http://www.railsenvy.com/2007/2/28/rails…
http://www.railsenvy.com/2007/3/20/ruby-…
С выходом rails2 появилось еще больше возможностей - как, например, кеширование sql-запросов, роутов.
Весьма просто и доступно нашел тут:
http://www.railsenvy.com/2007/2/28/rails…
http://www.railsenvy.com/2007/3/20/ruby-…
С выходом rails2 появилось еще больше возможностей - как, например, кеширование sql-запросов, роутов.
А Вам действительно именно нужно навесить кэширование ? Просто кэширование, особенно "неординарные пути" - техническая задача. А окончательный итог обычно - решение пользовательской проблемы. Вы точно уверены что пользовательскую проблему решит именно кэширование html кода ? Может задачу а-ля "у нас сайт тормозит, нужно ускорить" позволит решить более быстрая кодогенерация html, генерация более компактного html (например, буквально недавно "решали" задачу - сайт выдавал среднюю страницу на 2мб, кодогенерация в asp.net все-таки далека от "вменяемо оптимальной", уменьшили до 800 кб - стало гораздо комфортнее (работа идет по LAN) ) или опять же кэширование данных? Просто мне кажется не так тривиально к MVC прикрутить кэширование именно html, учитывая что сам паттерн предполагает при изменении модели - изменять вью, а вы будете выдавать его из кэша...
Например мы в проекте реализуем MVP, а не классический MVC. В этом случае все данные идут всегда от презентера (нету связи View-Model). На данный момент у нас основной упор по производительности - извлечение данных из БД (много и разных, по разным правилам) - в таком случае основное место кэширования - DAL слой, т.е. классы, которые извлекают непосредственно данные из БД. Кэшировать HTML из-за большого количества подгружаемых вещей (ajax) и сложного UI с состояниями особо не имеет смысла. К тому же у пользователей совершенно разные страницы - у каждого свой набор данных
Например мы в проекте реализуем MVP, а не классический MVC. В этом случае все данные идут всегда от презентера (нету связи View-Model). На данный момент у нас основной упор по производительности - извлечение данных из БД (много и разных, по разным правилам) - в таком случае основное место кэширования - DAL слой, т.е. классы, которые извлекают непосредственно данные из БД. Кэшировать HTML из-за большого количества подгружаемых вещей (ajax) и сложного UI с состояниями особо не имеет смысла. К тому же у пользователей совершенно разные страницы - у каждого свой набор данных
Я уже сделал:
- верстка блочная, ничего лишнего
- запросы к БД оптимизированы, как по качеству, так и по количеству
- кэш промежуточных вычислений и данных
Осталось кэшировать именно html.
Вот именно, в этом и проблема :)
- верстка блочная, ничего лишнего
- запросы к БД оптимизированы, как по качеству, так и по количеству
- кэш промежуточных вычислений и данных
Осталось кэшировать именно html.
Просто мне кажется не так тривиально к MVC прикрутить кэширование именно html, учитывая что сам паттерн предполагает при изменении модели - изменять вью, а вы будете выдавать его из кэша...
Вот именно, в этом и проблема :)
Есть одна идея, которая очень хорошо будет кэшировать, но довольно сложна в реализации:
Допустим есть такой урл: http://www.example.com/product/list.html
Понятно, что это экшн list контроллера product.
Самое сложное - правильно записать зависимости, чтобы обновлялись только те файлы, который действительно должны измениться. Ведь зависимость может быть не только от одного какого-нибудь экземпляра модели, но и от какого-нибудь набора, который может измениться, например, в зависимости от текущего времени.
Надеюсь, понятно изложил. Не знаю, насколько это Вам подойдёт.
Допустим есть такой урл: http://www.example.com/product/list.html
Понятно, что это экшн list контроллера product.
- Когда мы первый раз обращаемся по этому урлу, то работает скрипт, и по мере формирования страницы нужно каким-то образом сохранить все зависимости для данного урла. Результат работы вьюхи записываем в файл /product/list.html в корне веб-сервера.
- В следующий раз, когда произойдёт обращение по этому урлу, то веб-сервер просто отдасть этот статический файл, и не будет даже запускать скрипт.
- В метод save() у модели нужно внедрить некий код, который будет удалять все файлы, которые зависят от этой модели (зависимости были записаны раньше)
- При очередном обращении к урлу, когда веб-сервер не найдёт файл, нужно навесить на обработчик 404-ошибки запуск скриптов
Самое сложное - правильно записать зависимости, чтобы обновлялись только те файлы, который действительно должны измениться. Ведь зависимость может быть не только от одного какого-нибудь экземпляра модели, но и от какого-нибудь набора, который может измениться, например, в зависимости от текущего времени.
Надеюсь, понятно изложил. Не знаю, насколько это Вам подойдёт.
true.. а теперь как сделать dynamic? Твой /product/list.html и мой /product/list.html будут разные, например User_Id разный.. Под Каждый Юзернейм делать кеш? (я так думаю)
Ну да, по этой схеме получается так. Юзер в данном случае является зависимостью.
Но если отличия несущественные, то можно схитрить: сначала загрузить всю страницу, а потом по ajax'у загрузить отличающийся кусок. Например: имеем дело с интернет-магазином, в котором юзер ещё не залогинился, но может набирать корзину. На каждой странице показывается примерно следующее: "в вашей корзине X товаров на XXXXX рублей", а всё остальное - для всех одинаково. Грузим сначала статическую страницу из кэша, а на document.ready загружаем данные из сессии (сколько и сумма) и показываем.
Но если отличия несущественные, то можно схитрить: сначала загрузить всю страницу, а потом по ajax'у загрузить отличающийся кусок. Например: имеем дело с интернет-магазином, в котором юзер ещё не залогинился, но может набирать корзину. На каждой странице показывается примерно следующее: "в вашей корзине X товаров на XXXXX рублей", а всё остальное - для всех одинаково. Грузим сначала статическую страницу из кэша, а на document.ready загружаем данные из сессии (сколько и сумма) и показываем.
У меня кэширование идет на уровне модели, и кэшируются непосредственно данные.
Кэшировать html- хлопотно, так как он может различаться от пользователя к пользователю, кроме того у меня одни и те-же данные могут отдаваться в html и xml и в json- а узкое место именно доступ к бд.
Актуальность кэша- либо по времени жизни, либо через принудительное разрушение при обновлении (http://wiki.toukmanov.ru/dbSelect - тут подробнее, если интересно)
На каких-нибудь очень нагруженных страницах- вешаю тупой кэш html, отдаваемого модулем.
Кэшировать html- хлопотно, так как он может различаться от пользователя к пользователю, кроме того у меня одни и те-же данные могут отдаваться в html и xml и в json- а узкое место именно доступ к бд.
Актуальность кэша- либо по времени жизни, либо через принудительное разрушение при обновлении (http://wiki.toukmanov.ru/dbSelect - тут подробнее, если интересно)
На каких-нибудь очень нагруженных страницах- вешаю тупой кэш html, отдаваемого модулем.
Народ не въехал в топик.
Вот мысль кешировать MVC, но это только для static. В конце action добавляется элемент в массив с ключем URI а значение уже сам придумай.. Перед тем как инициализировать MVC надо посмотреть в массив.
Сейчас думаю как сделать для всего остального
Вот мысль кешировать MVC, но это только для static. В конце action добавляется элемент в массив с ключем URI а значение уже сам придумай.. Перед тем как инициализировать MVC надо посмотреть в массив.
Сейчас думаю как сделать для всего остального
как по мне решается так:
это пример...
Проще Zend_Cache
class CachePage{
protected _cache = true;
function __construct(){
ob_start()
}
function Run(){
$this->_cache = $this->_isCache();
if ( $this->_cache){
echo $this->getCache();
}else{
include 'index1.php'; // old index.php
}
}
function _isCache{
return ... { $GET['cache'] != true }
}
function __destract(){
$cont = ob_get_content();
$this->setCache($cont);
}
это пример...
Проще Zend_Cache
Очень рекомендую посмотреть, как кэширование логически реализовано в Django (http://www.djangoproject.com/documentati…).
Вкратце - там есть API как для низкоуровневого кэширования (любых объектов, задавая их имя), так и для кэширования отдельных Django views. А вот уже для каждого view, в Джанго выбирается, на какой срок он кэшируется; ну, и другие нюансы реализации, наподобие "The cache middleware caches every page that doesn’t have GET or POST parameters", и т.д.
Вкратце - там есть API как для низкоуровневого кэширования (любых объектов, задавая их имя), так и для кэширования отдельных Django views. А вот уже для каждого view, в Джанго выбирается, на какой срок он кэшируется; ну, и другие нюансы реализации, наподобие "The cache middleware caches every page that doesn’t have GET or POST parameters", и т.д.
"Красивый" способ реализовать частичное кеширование из представления только один pull-подход. Иначе придется в модель пихать проверки на наличие кеша. В принципе и это не страшно, если вы используете view, как valueObject, и кешируете именно его.
Но в таком кешировании практически нет необходимости, если вы используете адекватный шаблонизатор, с быстрой фазой execute. В вашем случае гораздо проще, ИМХО, кешировать данные.
ЗЫ: Честно говоря не очень понимаю, откуда в смарти взялся pull. Пойду копать ;)
Но в таком кешировании практически нет необходимости, если вы используете адекватный шаблонизатор, с быстрой фазой execute. В вашем случае гораздо проще, ИМХО, кешировать данные.
ЗЫ: Честно говоря не очень понимаю, откуда в смарти взялся pull. Пойду копать ;)
По идее кеширование должно быть двухуровневое - и в модели, и во view
Модель кладет в кеш свою последнюю версию в сериализованном виде. При использовании сначала извлекается версия из кеша, проверяется ее актуальность и используется либо она, либо создается новая из БД (и обновляется в кеше).
Кеширование view осмысленно делать прямо в HTML-виде с коротким временем хранения без валидации как таковой - это на случай частых запросов одного и того-же
Модель кладет в кеш свою последнюю версию в сериализованном виде. При использовании сначала извлекается версия из кеша, проверяется ее актуальность и используется либо она, либо создается новая из БД (и обновляется в кеше).
Кеширование view осмысленно делать прямо в HTML-виде с коротким временем хранения без валидации как таковой - это на случай частых запросов одного и того-же
А вы уверены, что кэширование блоков html даст вам ощутимый прирост производительности? Как я понял, вы сейчас используете файлы для кэширования данных, а ведь часто на веб-серверах именно диск является узким местом.
Мне кажется действительно лучше посмотреть на APC и eAccelerator и с их помощью хранить кэш данных в памяти. Плюс это, по идее, должно ускорить генерацию html, за счет кэширования опкода. Короче, будет красиво и точно быстрее, чем сейчас.
Если этого будет мало, можно еще посмотреть, может какие-то страницы можно эффективно кэшировать целиком - это вроде проще положить на MVC красиво.
Мне кажется действительно лучше посмотреть на APC и eAccelerator и с их помощью хранить кэш данных в памяти. Плюс это, по идее, должно ускорить генерацию html, за счет кэширования опкода. Короче, будет красиво и точно быстрее, чем сейчас.
Если этого будет мало, можно еще посмотреть, может какие-то страницы можно эффективно кэшировать целиком - это вроде проще положить на MVC красиво.
А попробуйте дополнительно кэшировать на стороне клиента. Я думаю это неплохая идея.
Прочитать все комменты - не осилил...времени нет - пишу cmf (95% выполнено, уже даже работают сайты на cmf (скорее cmf чем cms? потому как сущность я переложил на плечи сис админов а не программеров и в довольно легкой, понятливой форме)
и mvc как обычно рулит...
Всё конечно зависит от архитектуры, если архитектура унифицирована (не в коем случае не путать с нормализированными данными, потому как данные скорее денормализированные...но они Унифицированы (мода такая если кто железо знает вспомнит про блоки шейдеров в видеокартах)) и есть иерархическая БД, отделенная от иерархии (во сложил :) ), данных и описаний (указателей) на обьекты, то можно сделать так.
Так как унификация рулит, то кешировать поблочно. Соотвественно контроллер должен обрабатывать блок и вызывать модули обработки - отсюда - кешируем попросту строку "запроса"... т.е. при такой архитектуре... есть модуль подготовки запроса... переводим подготовленный запрос в md5 потом результат запроса в хранилище кеша с блоком / номером id контроллера / md5 имя файла - сериализованный результат...
Что выигрываем ... при изменении даже прав доступа (при иерархии это легко и в запросе делать) будет изменяться строка запроса, соотвественно браться только нужный результат.
Сумбурно конечно написал, если кому интересно могу поподробнее... про новую (как я считаю) технологию разработки cmf php & mysql
Вообще-то посоветовали написать статью про унифицированные иерархические БД... напишу обязательно, когда закончу проект.
Кстати кто хочет присоединиться к проекту очень было бы неплохо.
В 2 словах Drupal и Joomla (тем более) уже по архитектуре отдыхают, получилась очень гибкая, быстрая и равномерно нагружающая сервер система.
и mvc как обычно рулит...
Всё конечно зависит от архитектуры, если архитектура унифицирована (не в коем случае не путать с нормализированными данными, потому как данные скорее денормализированные...но они Унифицированы (мода такая если кто железо знает вспомнит про блоки шейдеров в видеокартах)) и есть иерархическая БД, отделенная от иерархии (во сложил :) ), данных и описаний (указателей) на обьекты, то можно сделать так.
Так как унификация рулит, то кешировать поблочно. Соотвественно контроллер должен обрабатывать блок и вызывать модули обработки - отсюда - кешируем попросту строку "запроса"... т.е. при такой архитектуре... есть модуль подготовки запроса... переводим подготовленный запрос в md5 потом результат запроса в хранилище кеша с блоком / номером id контроллера / md5 имя файла - сериализованный результат...
Что выигрываем ... при изменении даже прав доступа (при иерархии это легко и в запросе делать) будет изменяться строка запроса, соотвественно браться только нужный результат.
Сумбурно конечно написал, если кому интересно могу поподробнее... про новую (как я считаю) технологию разработки cmf php & mysql
Вообще-то посоветовали написать статью про унифицированные иерархические БД... напишу обязательно, когда закончу проект.
Кстати кто хочет присоединиться к проекту очень было бы неплохо.
В 2 словах Drupal и Joomla (тем более) уже по архитектуре отдыхают, получилась очень гибкая, быстрая и равномерно нагружающая сервер система.
Да, я вас понял. Подобный способ я применяю для редко меняющихся тяжеловесных структур данных, связанных с большими затратами на выборку и обработку (обычно бинарные деревья).
open source? коды не дадите посмотреть? ;)
Отличное получилось обсуждение. С интересными идеями. Спасибо. Но...
Цитата:
> (крупный региональный портал), код которого переписать
> полностью нет возможности (по множеству причин).
> Необходимо на уже готовый функционал навесить
> возможность кэширования.
Насколько я понимаю, у портала проблемы с нагрузкой на сервак.
на мой взгляд, проще и быстрее (а, возможно, и финансово выгоднее) будет поменять железо на серваке.
Увы, но идеальных систем не бывает =/
Цитата:
> (крупный региональный портал), код которого переписать
> полностью нет возможности (по множеству причин).
> Необходимо на уже готовый функционал навесить
> возможность кэширования.
Насколько я понимаю, у портала проблемы с нагрузкой на сервак.
на мой взгляд, проще и быстрее (а, возможно, и финансово выгоднее) будет поменять железо на серваке.
Увы, но идеальных систем не бывает =/
Куплен новый сервак, очень так нифиговый. Скоро ожидается переезд, но с таким ростом кол-ва посещний думаю не надолго поможет... У меня уже есть хорошая идея по кэшированию, но ее реализация связана с достаточным количеством модификаций кода. Надеюсь, что скоро руководство портала все-таки примет решение о модернизации движка, работающего аж на PHP4 :)
Использую этот класс (Переписал совсем чуть чуть): http://larin.in/archives/21
Даволен как слон, закэшировал всё что только можно :)
Даволен как слон, закэшировал всё что только можно :)
Поставлю-ка я здесь ссылку на свою статью: Фрагментарное кэширование в MVC веб-фреймворках
Sign up to leave a comment.
MVC и кэширование