Как реализовать кэш PHP / HTML

Я прочитал несколько руководств по внедрению системы php cache (мой сайт настраивается на заказ, довольно сложный запрос и растет), включая этот: http://www.snipe.net/2009/03/quick-and-dirty-php -caching /

Я их полностью понимаю, но есть некоторые части страницы, которые я не могу кэшировать, что лучший способ сделать это?

Related of "Как реализовать кэш PHP / HTML"

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

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

что ты можешь сделать:

  1. очищать весь свой кеш каждый раз, когда обновляются соответствующие части базы данных
    это действительно возможно, если ваша база данных редко обновляется – ежечасно, ежедневно, еженедельно. но это бесполезно, если изменения происходят постоянно. так обстоит дело с большинством веб-проектов.

  2. очистить кешированные предметы после того, как что-то произойдет
    это работает только в том случае, если изменения не обязательно должны отображаться мгновенно (например, не имеет значения, есть ли некорректные данные в течение некоторого времени). в этом случае вы просто можете очистить кеш для определенного элемента, если он старше X минут или больше, чем Y просмотров страниц.

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

большинство likley – это вариант 3: вы должны это выяснить. поэтому, в качестве примера, давайте рассмотрим классический случай веб-журнала, состоящий из главной страницы, страниц архива и подробной страницы для каждой записи.

изменения вносятся: административной панелью (crud для записей) и комментариями

если запись будет отредактирована или удалена, вам необходимо очистить кеш для:

  • на главной странице, если запись была новой
  • на соответствующей странице архива, если запись была старой
  • подробная страница для записи

если кто-то комментирует, вам просто нужно очистить страницу подробностей, но только если количество комментариев не отображается в индексе или архиве. в противном случае, так же, как вход-crud.

если что-то изменилось, весь кеш должен быть очищен (плохо!)

теперь давайте подумаем о входной ошибке и архиве. если архив имеет тип «одна страница в месяц», затем очистите месяц, к которому принадлежит запись. но если в архиве вид ввода 1-10, 11-20, 21-30, … наиболее похоже, весь архив-кеш должен быть перестроен.

и так далее …

некоторые из проблем:

  • если вы не идентифицируете все затронутые части правильно, это может привести к устаревшим данным и / или (не) мертвым ссылкам.

  • если обновления происходят слишком часто, создание кеша – это дополнительная работа, потому что, когда происходит следующее просмотрение страницы, кеш, скорее всего, снова устарел и должен быть перестроен в любом случае.

  • некоторые части страницы непригодны для кеширования, например (пользовательская) функция поиска. если кеш работает в другом месте, все быстро и отлично, но поиск все еще ужасно медленный.

  • это может быть проблематично, если вам нужно очистить весь кеш, пока происходит много запросов. он может затормозить ваш сервер, потому что кэш-промах обычно дороже, чем если бы страница не была кеширована в первую очередь. еще хуже, если приходит 3 запроса, и первый запрос не может кэшировать страницу до того, как будут обработаны остальные два, кеш будет запрашиваться 3 раза, а не один раз.

Мой совет:

  • оптимизируйте свою базу данных. ключи и конфиги нормально? возможно, он работает без кеширования.

  • оптимизируйте свои запросы. «объясните выбор»!

  • только кешировать части страницы – дорогие. заполнить небольшие, дешевые изменения с помощью str_replace и заполнителей

  • если все работает, используйте apc или memcached вместо файлов (файлы обычно работают отлично, но apc / memc быстрее). вы также можете использовать свою базу данных для кэширования своей базы данных, часто это отлично работает!

  • вы строите ленивую или нетерпеливую систему кеширования? lazy означает: создайте кеш, когда запрашивается первая страница, нетерпеливо означает: сразу после обновления.

meh, у меня нет никаких реальных советов для вас. слишком сильно зависит от проблемы 🙂

Обновить

theres запрос для записи блога с ключом 256. он показывает запись в блоге, комментарии и кто в настоящее время входит в систему. Очень дорого запрашивать запись и комментарии, а также форматировать весь текст и все такое. текущий пользователь вошел в сеанс.

во-первых, создайте уникальный ключ для части, которую вы хотите кэшировать. в этом случае ключ кэш, вероятно, является идентификатором базы данных записи (с некоторым префиксом и постфиксным кодом).

поэтому кешированный файл должен иметь имя cache/blogentry_256.tmp . проверьте, существует ли этот файл.

  1. если он не существует, выполните все дорогостоящие запросы и форматирование, оставьте местозаполнитель (например, {username}), где должно быть имя текущего пользователя, и сохраните результат в cache/blogentry_256.tmp . будьте осторожны, чтобы не записывать какие-либо данные в этот файл, которые не должны отображаться для всех или изменения для каждого запроса.

  2. теперь прочитайте файл (или повторно используйте данные из 1) и str_replace имя пользователя в заполнителе. echo результат.

если запись изменена или кто-то комментирует, вам нужно удалить кэш-файл с идентификатором записи.

это ленивое кэширование – кеш построен только в том случае, если пользователь запрашивает страницу. будьте осторожны – если пользователь вводит {username} в комментарий, он тоже вставлен! это означает, что вам нужно избегать кэшированных данных и отменить их после str_replacing. эта техника работает также с memcached или apc.

проблемы: вы должны создать свой дизайн вокруг этого кэширования. например, если вы хотите отобразить «комментарий, опубликованный 5 минут назад» вместо «добавлено комментарий добавлено 6 мая, 15:42», то у вас проблемы.

Почему вы не можете их кэшировать? Если это происходит из-за того, что они меняются очень быстро, тогда вам, вероятно, лучше будет пытаться уменьшить извлечения и накладные расходы.

Если содержимое зависит от пользователя, вы можете предлагать разные кешированные версии для каждого пользователя. Например, если вы используете кеш объекта, укажите идентификатор пользователя или другое уникальное значение в кеше. Если вы используете более общий кеш-уровень HTTP, такой как Squid, тогда вы можете установить заголовок Vary , например, Vary: Cookie , что заставит прокси-сервер дважды проверять, кому он служит.

Вы все равно должны указывать кэшам и прокси-серверам, чтобы они не хранили какую-либо конфиденциальную информацию в общедоступных кешах.

Помните, что кэширование – это не одно решение – ваше приложение может иметь кеширование на разных уровнях в зависимости от области переменных. В рамках одного запроса у вас может быть карта идентификации для предотвращения дополнительных запросов для одних и тех же данных. Вы можете использовать memcached для кэширования данных по запросам. Сама база данных имеет кэш запросов, а также другие типы кэшей более низкого уровня. Ваш механизм рендеринга также может кэшироваться на разных уровнях – целая страница, отдельные части страницы и т. Д. Вам нужно выяснить, что вы можете кэшировать и разработать для этого стратегию.

Кроме того, как и при любой оптимизации, убедитесь, что вы измеряете, прежде чем настраивать что-либо. Это гарантирует, что 1) вы действительно улучшаете вещи, а не делаете их хуже, и 2) вы сосредотачиваетесь на том, что важно, а не на всем остальном.

Вот мой совет: создайте либо объект, либо функцию, которая позволяет кэшировать «раздел» на основе его имени. Таким образом, вы можете кэшировать часть своей страницы и включать секцию рендеринга в блоке if. То, что я сделал, было хэш-входящим текстом и использовало его как имя файла в './cache' и возвращало логическое значение необходимости регенерации; для этого вам, очевидно, понадобится буферизация вывода.

Это даст вам структуру кеша,

 if(Cache::cached('index-recent-articles', 5 /* minutes */)) { Cache::start(); echo 'stuff here'; Cache::stop('index-recent-articles'); } // And if Cache::cached could echo the cached HTML when the result is false... // then this is a tidy else-less bit of code. 

Я не знаю, оптимально ли это, решение на базе сервера, такое как memcache, было бы лучше, но концепция должна помочь вам. Очевидно, что вы управляете кешем, будь то файлы или базы данных или расширения, зависит от вас.

Редактировать:

Если вы хотите использовать кеширование на основе файлов, то эта простая система может быть все, что вам нужно. Очевидно, я не тестировал его на ваших ботинках, и это в основном просто вытягивается из затылка, но, поскольку это стоит, это достойный старт для того, что вы можете пожелать.

 abstract class Cache { const path = 'cache/'; static function start() { ob_start(); } static function end($id, $text = null) { $filename = sprintf('%s%u', Cache::path, crc32($id)); file_put_contents($filename, $text === null ? ob_get_clean() : $text); } static function cached($id, $minutes = 5) { $filename = sprintf('%s%u', Cache::path, crc32($id)); $time = $minutes * 60; if(time() - filemtime($filename) > $time) { return true; } else { echo file_get_contents($filename); return false; } } }