Attention! Helicon Tech Blog has moved to www.helicontech.com/articles/

Showing posts with label caching. Show all posts
Showing posts with label caching. Show all posts

Wednesday, May 12, 2010

Automatic cache cleaning in Helicon Ape

Up to version 3.0.0.39 Helicon Ape cache could be cleaned only manually. Memory-based cache (mod_mem_cache) required recycling of corresponding application and disk-based cache (mod_disk_cache) cleaning implied manual files deletion form the file system. That was slightly inconvenient, to put it mildly.
Helicon Ape 3.0.0.39 (and newer) got support of cache cleaning upon request.
Now, to clean cache just set the cache-clear environment variable. This will cause cache cleaning corresponding to the current request (context).

Setting cache-clear variable using SetEnvIf directive provides flexibility of conditions that will lead to cache cleaning.

For example, to trigger cache cleaning by requesting specific URL:
SetEnvIf request_uri ^/system/cache/clear/$ cache-clear=1
To trigger cache cleaning by appending specific query string value:
SetEnvIf Query_String clear_cache_request cache-clear=1
For security purposes it may be necessary to clean cache only from definite IP address:
SetEnvIf (Query_String clear_cache_request) and (Remote_Addr 11\.22\.33\.44) cache-clear=1
Cache cleaning may take some time, so be ready.

When cache cleaning is over, the error.log (with info or higher verbosity level) will display the number of deleted records.

Best regards,
Ruslan, Anton - Helicon Tech Team

Friday, July 3, 2009

Disk-based caching for IIS7

We have already shed some light on the question of web caching and its benefits in our «Web Caching: what is it?» article. We've also explained how web caching is realized in Helicon Ape in «How mod_cache works?» article. Back then mod_cache could only store requests in the memory, but now, after Helicon Ape 1.2.0.21 release, there's mod_disk_cache module that enables cashing to the hard drive.

Enabling mod_disk_cache

To make mod_disk_cache working one should perform the following simple steps:
  • Create disk cache folder. Say, c:\inetpub\cache.
  • Grant Read & Write permisions for that folder to users running Application Pools on your IIS. By default it's IIS_IUSRS group.
  • Point to that folder in httpd.conf using CacheRoot directive:
    CacheRoot c:\inetpub\cache
  • Enable caching for requests to /app/ for example. To do that, specify in httpd.conf:
    CacheEnable disk /app/
    or in .htaccess inside /app/ folder:
    CacheEnable disk
That's the minimum configuration needed to have something cached. Now all requests containing expiration time (e.g. Cache-Control header) will be cashed on disk.

mod_disk_cache saves cached requests into hierarchical folder structure inside CacheRoot. Length of names and levels of these folders are defined by CacheDirLength and CacheDirLevels directives. Caching gives out even better effect when used together with mod_gzip module which compresses response before caching and sending it to the client.

Pros and cons of disk caching

The tests we've conducted showed that the speed of mem-based and disk-based cache is roughly equal.

The main advantage of disk cache is that cached data is stored on disk and does not depend on applications recycling, IIS and hardware reset, in contrast to memory cache that is stored until the first application recycling or IIS reset.

The shortage of disk cache lies in absense of intrenal recycling mechanism for the expired records that are not used any more. But that's not that critical:) The workaround may be: configure sheduled recycling of all cache once a day, i.e. remove all subfolders (or aged records only) and their content from CacheRoot.

Wednesday, January 21, 2009

Guide: Example of mod_cache application

In the previous articles we told you what cache is and how it works in Helicon Ape. Now it’s time to use obtained knowledge in practice. Today we gonna apply caching for PHP application called qdig that helps organize images web-gallery. Read how to register PHP on IIS7 in our article about WordPress.

Creating online photo album

Let’s create photos folder in site root and fill it with our photos. Now we are downloading qdig. To make it simpler we’ll extract only one index.php file and put it into the same directory.


The gallery is already working: http://localhost/photos/index.php

Measuring performance

To measure request rate we’ll use ab.exe application:
ab.exe -n 200 -c 2 "http://localhost/photos/index.php?Qwd=.&Qif=DSC00410.JPG&Qiv=name&Qis=M"
The result is a bit more than 16 requests per second.

Switching on mod_cache and mod_expires

To enable necessary modules, let’s uncomment the following lines in Helicon Ape httpd.conf file:
LoadModule expires_module    modules/mod_expires.so
LoadModule cache_module modules/mod_cache.so

Analyzing cached request

To make mod_cache cache not all requests but only unique ones, let’s figure out what qdig request parameters mean and how request uniqueness depends on them:
  • Qwd - folder where image files reside - AFFECTS request uniqueness;
  • Qif - file name - AFFECTS request uniqueness;
  • Qiv - mode of file names representation - AFFECTS request uniqueness;
  • Qis - image size - DOESN’T AFFECT request uniqueness;
  • Qtmp - representation mode - DOESN’T AFFECT request uniqueness;
Thus, cache key will use only Qwd, Qif and Qiv parameters.
The piece of config for mod_cache will look like:
<Files index.php>
CacheEnable mem
CacheVaryByParams Qwd Qif Qiv
</Files>

Expiration time

index.php script does not set Cache-Control and Expires headers, but, as we already know, they are really important for successful caching. So we’ll set these headers by ourselves. And for that purpose we’ll use mod_expires functionality:
ExpiresActive On
ExpiresByType text/html "access 1 hour"
Above directives set expiration time to 1 hour.
The resulting .htaccess is as follows:

Measuring performance once again

ab.exe -n 200 -c 2 "http://localhost/photos/index.php?Qwd=.&Qif=DSC00410.JPG&Qiv=name&Qis=M"
And now the result is about 94 requests per second!

That’s all you need to do to achieve sixfold performance growth.
This example clearly demonstrates the ease and efficiency of Helicon Ape caching feature.

Monday, January 12, 2009

How mod_cache works?

Helicon Ape release (coming very-very soon) will contain mod_cache module. And as we promised in our previous article we are now giving you more thorough description of mod_cache operation.

mod_cache starts working

After authentication/authorization events but prior to request handler execution mod_cache comes out on the scene. At this stage the module performs the following:
  • checks whether it's possible to use cached response for the current request
  • if yes, generates a key and searches cached response using this key
  • if the response is found in cache, the module gives it back to the client and request processing is over — request handler is not invoked.

Cacheable or not cacheable: request check


Response may be cached if request meets the following requirements:
  • request method is GET
  • request does not contain Authorization header
  • Cache-Control request header must not be no-cache. This condition is ignored if CacheIgnoreCacheControl On is used
  • Pragma request header must not be no-cache. This condition is ignored if CacheIgnoreCacheControl On is used

mod_cache attempts to save response

When request handler has completed its job and all defined filters have been applied to response, mod_cache starts to operate. At this stage the module performs the following:
  • estimates the capability of response caching
  • checks if CacheEnable is set for this request
  • generates cache key
  • defines the period of time to store response in cache (absolute expiration time)
  • saves response in cache according to the key

Cacheable or not cacheable: response check


The following conditions are considered when deciding whether response is cacheable (all must be met at a time):
  • request method is GET
  • response status is 200 (200, 203, 300, 301 or 410 in Apache)
  • Expires response header contains valid "future" date
  • responses containing expiration time (i.e. Expires or Cache-Control: max-age=XX headers), Etag header or Last-Modified header. This condition is ignored if CacheIgnoreNoLastMod is used

    • if request has a QueryString, only those responses containing expiration time are cached (i.e. Expires or Cache-Control: max-age=XX headers). This condition is ignored if CacheIgnoreQueryString On is used
  • Cache-Control request header must not be no-cache. This condition is ignored if CacheStoreNoStore On is used
  • Cache-Control request header must not be private. This condition is ignored if CacheStorePrivate On is used
  • request does not contain Authorization header (for Apache: if Cache-Control contains s-maxage, must-revalidate or public)
  • Vary response header does not contain "*".

Cache key generation

Response is saved in cache according to the key. This key includes:
  • normalized (canonical) request URI without QueryString or, in case of proxy request, normalized proxy request URL;
  • all QueryString parameters and their values in alphabetical order (default behavior)

    • CacheIgnoreQueryString On directive cancels addition of request parameters to the cache key
    • CacheVaryByParams param1 param2 ... directive defines parameters to be included into cache key
  • all request headers specified in CacheVaryByHeaders header1 header2 ... directive. Headers are not included to the cache key by default.
  • If response contains Vary header, all request headers specified in it are included into cache key.

When cached response dies

HTTP response is stored in cache for a specific period of time that is computed in the following way:
  • If response contains Expires header and its value is valid and does not refer to the past, cached response will be stored till the time specified in it.
  • If response contains Cache-Control header with either max-age=X or s-maxage=X, cached response will be stored in cache for X seconds.
  • If response contains Last-Modified header, cached response will be stored in cache until: expiry date = date + min((date - lastmod) * factor, maxexpire), where date - current date, lastmod - value of Last-Modified header, factor - float value set via CacheLastModifiedFactor directive (default value = 0,1), maxexpire - value set via CacheMaxExpire directive (default value = 86400 seconds = 1 day).
  • If mod_cache was unable to calculate expiration date using one of aforementioned methods (this is possible if response doesn't have Expires, Cache-Control, Last-Modified headers BUT has Etag header), it (date) is equated to default value of 1 hour that may be reset using CacheDefaultExpire directive.
This load of text might look a little unclear for you at a glance, but in reality this is a well-composed and highly efficient scheme. And our upcoming article will convince you in this.

Friday, January 9, 2009

Web Caching: what is it?

What is that and what’s it for?

Web cache is a vital instrument to build lightning-fast web apps. Web cache stores HTTP responses that may be provided to the user without making a request to the server, i.e. no ASP/PHP scripts execution and database queries are necessary. And that’s cool!
Web-caching allows to substantially reduce response time — time the server needs to give the response — as reading from cache is much faster than processing request with PHP handler.
Web-caching minimizes traffic — if one uses intermediate caches (gateway or proxy cache), request won’t reach the origin server — response will be given back by an intermediate caching server.

Cache breeds

Server cache

This cache works on the origin server. Applications and server itself use it to store parts of responses (e.g. web pages) or complete responses. Server cache may be used on application (e.g. memcached + php or HttpRuntime.Cache + ASP.NET) or HTTP server level (e.g. mod_cache in Apache, OutputCache in IIS7).

Proxy cache

It lives between clients and origin servers and may only store public representations that do not require authorization (unlike private representations). Proxy cache is widely used by providers to reduce traffic.

Browser cache

It lives in browser and is capable of storing private data. Browser cache is used for example for Back button operation.

How does Server Cache work?

Cacheless configuration

Cacheless configuration forces server to process each incoming request and generate new response even if the same resource is requested several times running. That is senseless time- and resources-consuming operation that puts excessive load on the server.

First request to cache-enabled server

When the specific resource is requested from the server for the first time caching system checks if it’s possible to cache the response, then it looks for response in cache and fails to find it. Request moves further along the server pipeline triggering necessary handlers and filters. When the response is ready caching system saves it to cache before sending to the client.

Subsequent requests to cache-enabled server

Upon further requests to this resource caching system checks if it’s possible to cache the response, then it looks for response in cache and this time finds it! Then the response is retrieved from cache and sent to the client. And that’s it! No server handlers and filters are executed.
Responses are stored in cache for a certain period of time. When this time elapses cached response is labeled as not valid and is removed from cache. Next request to that same resource is processed as if it is requested from the server for the first time (see “First request to cache-enabled server’).

Conclusion

As you could see, Server Cache favors lower server load and faster response time. In the next article concerning cache we’ll give more thorough explanation of this process and illustrate it with examples.