开发者

Aggressive caching of generated contents while maintaining auth info

I'm using a Symfony 2 to generate my pages from data in a MySQL database. For most content, users have to be authenticated but the content itself does not change often and does not need to be customized for the users. So what's a good caching strategy for avoiding database calls while s开发者_如何学Pythontill maintaining the auth check?


Simply put, use Memcache to cache the SQL result-set for extended period of time.


Maybe this be too huge change, but the following scheme may be useful in the case:

Create several sets of pages, one for not-yet-authed users (let's put in the site root), and others for authenticated users that should see the same content (say, it two or more should see the same content when they are authenticated, then we'll create only one set for all of them), and put it into directory under root. Then form simple .htaccess/.htpasswd files for each of such 'for-authed-only' directory and then it'll be webserver's problem not your script.

Hope you got the idea. It is fuzzy to say, but will be easy to implement.

Example: say you care to allow only authenticated users to see page '/topsecret.html' on the site. Create dir (/authed), establish HTTP-auth on it, and put your topsecret.html into the dir (so it'll be '/authed/topsecret.html'). Now edit '/topsecret.html' and simple replace it's main content with 'sorry, please authenticate yourself' link that'll point to '/authed/topsecret.html'.


If you use Symfony2, you are using Doctrine2 if you use Doctrine2, caching should be enabled by default.

Choose your cache driver for your purposes and there should be no problem. You might also be specifically interested in query result caching.

Do not use Doctrine without a metadata and query cache! Doctrine is highly optimized for working with caches. The main parts in Doctrine that are optimized for caching are the metadata mapping information with the metadata cache and the DQL to SQL conversions with the query cache. These 2 caches require only an absolute minimum of memory yet they heavily improve the runtime performance of Doctrine. The recommended cache driver to use with Doctrine is APC. APC provides you with an opcode-cache (which is highly recommended anyway) and a very fast in-memory cache storage that you can use for the metadata and query caches


I solved this by using Zend_Cache inside the cacheable actions to store the rendered template result. I then create a new Response object from the cached content. If the cache is empty, I generate the content.

I thought of creating a plugin that checks for an annotation and stores the Response output automatically but it turned out that I only have 3-4 display actions that are cacheable and have very complex cache ID creation rules, so I put the caching logic directly into the controller code.


It appears that you have a lot of options for caching with symfony http://www.symfony-project.org/book/1_2/12-Caching (not for 2 but my guess is not a lot has changed).

You could put your heavy sql statements in its own script and turn caching on for that script

list:
  enabled:     on
  with_layout: false   # Default value
  lifetime:    86400   # Default value

Further if you are sure that the generated tag won't change for a while you could use symfony to tell the user's browser not even to bother your server for the content which will cause the page to load nearly instananeously for the user.

$this->getResponse()->addCacheControlHttpHeader('max_age=1200'); // in seconds - less than 1 year seconds

Just make sure your max age is small enough that when something changes (say a code update) that the user doesn't get stuck with old page since there is no way to force them to request that page again short of changing the url.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜