如何实现PHP / HTML缓存 [英] How To Implement A PHP/HTML Cache

查看:81
本文介绍了如何实现PHP / HTML缓存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经阅读了几个关于实现php缓存系统的指南(我的网站是自定义编码的,查询量很大并且越来越多),包括这个: http://www.snipe.net/2009/03/quick-and-dirty-php-caching/



我完全理解它们,但是页面的某些部分无法缓存,请问这样做最好的方法是什么?

解决方案

如果您执行大量读取但很少更新,则缓存很有用。数据库中的数据越频繁地变化,缓存系统变得越有问题。缓存确实为您的代码库增加了一定的复杂性,这可能是一个很难处理的问题。它甚至可以在最糟糕的情况下减缓您的网站。



最重要的问题是:

何时你必须使你的缓存无效?它什么时候变得陈旧?在大多数情况下,如果数据库查询返回的是不同于您缓存该页面的行。但你怎么知道的?你不(可能有办法,但我想不出任何atm),因为要检查,你可能不得不查询结果进行比较。



你可以做什么:


  1. 每次清除所有缓存数据库的相关部分被更新

    如果你的数据库很少被更新 - 每小时,每天,每周,这确实是可能的。但如果变化持续不断,那就没用了。这是大多数Web项目的情况。

  2. 只有当变更不必反映立即(例如,如果有一段时间有不正确的数据不重要)。在这种情况下,如果某个项目的时间超过了X分钟,或者发生了超过Y次浏览量,则只需清除某个项目的缓存即可。 仅清除相关作品

    在这里你必须弄清楚当你更新数据库时缓存的哪些部分会受到影响。如果做得对,变化会在性能提升的同时立即反映出来。




最可能是选项3:你必须找出。所以,举个例子,让我们看看博客的经典案例,包括首页,存档页面和每个条目的详细信息页面。



更改由:管理面板(crud for entries)和评论

如果条目被修改或删除,您必须清除缓存:




  • 首页,如果条目是新的

  • 相关的存档页面,如果条目已旧

  • 条目的详细信息页面



如果有人注释,您只需清除详细信息页面,但仅限于评论数量不会显示在索引或存档中。

如果网站范围发生变化,整个缓存必须清除(坏!)
$ b现在$ b

,让我们考虑一下入门crud和档案。如果存档的类型为每月一页,则清除该条目所属的月份。但是如果档案类型为1-10,11-20,21-30 ......,则最有可能的是整个档案缓存必须被重建。



等等......



一些问题:


  • 如果您没有正确识别所有受影响的作品,可能会导致陈旧的数据和/或(un-)死链接。

  • >

    如果更新频繁发生,构建缓存是额外的工作,因为当下一次浏览量发生时,缓存很可能再次变旧,并且必须重新构建。

  • 页面的某些部分不适合缓存,例如(自定义)搜索功能。如果缓存在其他地方工作,一切都很快,很好,但搜索仍然非常缓慢。

  • 的请求正在发生。它可能会阻塞你的服务器,因为一个cache-miss通常比页面没有被缓存的开销更大。更糟糕的是,如果有3个请求进入,并且第一个请求无法在处理其他两个请求之前缓存该页面,则缓存将被请求3次而不是一次。


我的建议:


  • 优化您的数据库。键和配置好吗?也许它在没有缓存的情况下工作。


  • 优化您的查询。 解释选择!


  • 只缓存页面的部分内容 - 昂贵的部分。用str_replace和占位符填充小的廉价变化如果一切正常,使用apc或memcached而不是文件(文件通常工作得很好,但apc / memc是更快)。你也可以使用你的数据库来缓存你的数据库,通常这很好!

  • 你正在构建一个懒惰或急切的缓存系统吗?懒惰的意思是:在页面第一次请求时建立缓存,渴望的意思是:在更新之后。




meh,i对你没有任何真正的建议。取决于这个问题:)

update



这是一个请求带有键256的博客条目它显示博客条目,评论和当前登录的人员,查询条目和评论以及格式化所有文本和所有内容都很昂贵。当前登录的用户驻留在会话中。首先,为要缓存的部分创建一个唯一的密钥。 在这种情况下,缓存键可能是条目的数据库ID(带有一些前缀和后缀)。



因此,缓存的文件应该具有高速缓存/ blogentry_256.tmp 。检查,如果该文件存在。


  1. 如果它不存在,请执行所有昂贵的查询和格式设置, (例如{用户名}),当前用户的名称应该是,并将结果保存到 cache / blogentry_256.tmp 。注意不要将任何数据写入这个文件中,这些文件不应该显示给每个人或者每个请求的改变。

  2. 现在,读取文件(或者重新使用来自1)的数据并将用户名str_replace放入占位符中。 echo 结果。


有人说,你必须删除缓存文件的条目id。



这是懒惰的缓存 - 只有当用户请求页面时才构建缓存。要小心 - 如果用户在注释中键入{username},它也会插入到注释中!这意味着,您必须在str_replacing之后转义您的缓存数据并将其忽略。这种技术也适用于memcached或apc。



问题:您必须围绕该缓存设计构建您的设计。例如如果你想显示5分钟前发布的评论,而不是评论添加5月6日,下午3:42,那么你有麻烦。


I've read several guides on implementing a php cache system (my site is custom coded, fairly query heavy and growing) including this one: http://www.snipe.net/2009/03/quick-and-dirty-php-caching/

I understand them fully but there are certain parts of the page that I can't cache, what's the best way to go about doing that?

解决方案

caching is useful if you do a lot of reads but seldom update. the more often the data in the database changes, the more problematic a caching system becomes. caching does add a certain complexity to your codebase, which can be a pain to handle. and it can even slow your site down in the worst case.

the most important question is:
when do you have to invalidate your cache? when does it become stale? in most of the cases, if the database-query returns different rows than at the time you cached that page. but how do you know that? you don't (maybe there is a way, but i can't think of any atm), because to check that, you probably have to query the result to compare.

what you can do:

  1. clear all your cache everytime the relevant parts of the database are updated
    this is indeed possible if your database only rarely gets updated - hourly, daily, weekly. but it's useless if changes are coming in continually. that's the case with most web projects.

  2. clear cached items after something happens
    this only works if changes do not have to be reflected instantly (e.g. doesn't matter if there's incorrect data for some time). in this case you simply could clear the cache for a certain item if it's older than X minutes, or more than Y pageviews happened.

  3. clear only the relevant pieces
    here you have to figure out which parts of the cache are affected when you're updating the database. if done right, changes are reflected instantly while performance improves.

most likley is option 3: you have to find out. so, as an example, lets take the classic case of a weblog, consisting of a frontpage, archive pages and a detail-page for every entry.

changes are introduced by: the admin-panel (crud for entries) and comments

if an entry gets edited or deleted, you have to clear the cache for:

  • frontpage, if the entry was new
  • the relevant archive page, if the entry was old
  • the detail-page for the entry

if someone commentes you just have to clear the detail-page, but only if the number of comments is not displayed in the index or archive. otherwise, same as entry-crud.

if something sitewide is changed, the whole cache has to be cleared (bad!)

now, lets think about entry-crud and the archive. if the archive is of the type "one page per month", then clear the month the entry belongs to. but if the archive is kind of entry 1-10, 11-20, 21-30, ... most likley the whole archive-cache has to be rebuild.

and so on ...

some of the problems:

  • if you don't identify all the affected pieces correctly, it can lead to stale data and/or (un-)dead links.

  • if updates happen too often, building the cache is additional work, because when the next pageview happens, the cache is most probably stale again and has to be rebuild anyway.

  • some parts of the page are unfit for caching, e.g. the (custom) search function. if the cache works elsewhere everything is fast and great, but searching is still awfully slow.

  • it can be problematic if you have to clear the whole cache while lots of requests are happening. it then can choke your server, because a cache-miss is normally more expensive than if the page's not cached in the first place. even worse, if 3 request are coming in, and the first request can't cache the page before the other two are handled, the cache gets requested 3 times instead of once.

my advice:

  • optimize your database. keys and config ok? maybe it works without caching.

  • optimize your queries. "explain select"!

  • only cache parts of the page - the expensive ones. fill in small, cheap changes with str_replace and placeholders

  • if everything works, use apc or memcached instead of files (files usually work great, but apc/memc are faster). you can also use your database to cache your database, often that works great!

  • are you building a lazy or an eager caching system? lazy means: build the cache when the page's first requested, eager means: right after the update.

meh, i don't have any real advice for you. depends too much on the problem :)

update

theres a request for the blog-entry with key 256. it shows the blog-entry, the comments and who is currently logged in. it's expensive to query the entry and the comments, and format all the text and everything. the currently logged in user resides in the session.

first, create a unique key for the part you want to cache. in this case, the cache-key probably is the database id of the entry (with some prefix and postfix).

so, the cached file should have the name cache/blogentry_256.tmp. check, if that file exists.

  1. if it doesn't exist, do all the expensive querying and formatting, leave a placeholder (e.g. {username}) where the name of the current user should be and save the result to cache/blogentry_256.tmp. be careful not to write any data into this file that shouldn't be displayed for everyone or changes on every request.

  2. now, read the file (or reuse the data from 1) and str_replace the username into the placeholder. echo the result.

if an entry gets changed or someone comments, you have to delete the cache-file with the entries id.

this is lazy caching - the cache is built only if the user request the page. be careful - if a user types {username} into a comment, it's inserted there too! that means, you have to escape your cached data and unescape it after str_replacing. this technique works with memcached or apc too.

problems: you have to build your design around that caching desicion. e.g. if you want to display "comment posted 5 minutes ago" instead of "commented added May 6th, 3:42pm", then you're in trouble.

这篇关于如何实现PHP / HTML缓存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆