blog.quehy.com freshmeat squid
What is ModCache
ModCache is a cache accelerator plugin for lighttpd, which works like Squid with similar configuration. However modcache is faster and more effective than Squid because of powerful Lighttpd.
ModCache has following advantages over Squid:
- Simpler. ModCache just sets proper flags between lighttpd request handling stages. Request is handled by mod_staticfile or mod_compress or other modules.
- More Robust. ModCache uses disk file instead of memory as cache. Without use of memory, modcache is far away from memory leaks and memory exhaustion.
- Faster. Lighttpd uses Sendfile syscall to service disk file. Sendfile syscall, which writes file to network interface directly, has the same effecience as Writev syscall which writes memory buffers to network interface.
- More Powerful. ModCache can works with other lighttpd plugins(except mod_deflate). For examples, you can use mod_compress to compress cached files on-fly; or you can use mod_access/mod_trigger_b4_dl to do anti-hot-link; or you can use mod_flv_streaming to do native flv file streaming.
How to use ModCache
ModCache provides following options:
- cache.bases. List of cache directories. For examples: cache.bases = ("/data/cache", "/data2/cache")
- cache.enable. Enable or disable modcache, default to enable.
- cache.domains. List of domains which modcache would try to cache for, without it modcache would cache files of every domains. for examples: cache.domains = ("(^|\.)linux\.com\.cn$") caches *.linux.com.cn. domains.
- cache.support-queries. Try to cache query with '?'. default is 'disable'. When cache.support-queries = "enable" and cache.dynamic-mode = "disable", modcache will treat "/uri?q1" or "/uri?q2" as "/uri" and save them to local cache file of "/uri". When cache.support-queries and cache.dynamic-mode are both enabled, modcache will treat "/uri?q1" and "/uri?q2" as different resource and save them to different local cache files.
- cache.debug. Default to disable debug messages.
- cache.purge-host. pcre regex hosts ip which are allowed to PURGE cache files. for examples: cache.purge-host="^200\.100\.1\." allow 200.100.1.0/24 to purge cache
- cache.refresh-pattern. Key of modcache. See section below for detail.
- cache.ignore-hostname. Includes hostname in saved filename or not. default is "disable".
- cache.dynamic-mode. To support dynamic generated web such as forum/bbs. default is "disable". Note: cache.support-queries needs to be enable.(V1.6.0 feature)
- cache.programs-ext. List of local program extension, such as ".php". modcache will replace them with ".cache.html" to aviod confliction with other modules, such as mod_fastcgi. default is not set (V1.6.0 feature)
- cache.max-memory-size. Number of MBytes which modcache will use to save cached content in memory. default is 256Mbytes. (V1.7.0 feature)
- cache.lru-remove-count. Number of content removed from memory when memory is full. default is 256. (V1.7.0 feature)
Note: make sure that mod_cache is loaded before mod_proxy.
Refresh Patterns
cache.refresh-pattern likes squid's refresh-pattern. cache.refresh-pattern format is "url_pcre_regex" => "minutes options". Note: zero 'minutes' means cache forever and minutes option is mandatory.
Available refresh-pattern options are:
- ignore-reload. Don't update cache when browser sends 'Cache-Control: no-cache' header. It's default behaviour
- update-on-refresh. Update cache when browser sends 'Cache-Control: no-cache' header.
- override-expire. Ignore backend's 'Expire' header while determining whether to cache.
- ignore-cache-control-header. Ignore backend's 'Cache-Control' headers while determining whether to cache.
- ignore-vary. Ignore backend's 'Vary' headers while determining whether to cache.
- no-expire-header. Don't set expires header on matched uri. modcache default to set proper expires header based refresh-pattern rules.
- fetchall-for-range-request. Download all content of file if browser sends 'Range: xxx-yyybytes' header. Useful for multi-thread downloaders(such as flashget).
- flv-streaming. to work with mod_flv_streaming.
- use-memory. use memory to save caches instead of local disk (V1.7.0 feature)
- memory-compress. compress memory-saved content for 'Accept-Encoding: gzip, deflate' requests. Note: use mod_compress to compress local cache files(V1.8.0 feature)
- nocache. Don't cache matched url.
ModCache don't cache urls without refresh-pattern rules matched.
How ModCache works
ModCache implements as below: (use http://host/uri as url example)
Step 1: modcache_uri_handler.
checks cache.domains, cache.refresh-pattern orderly for whether to use cache or not; if OK, then checks file 'cache.bases/host/uri' existness and it's expire time; if OK again, set con->use_cache_file to 1;
Step 2: modcache_docroot_handler.
If con->use_cache_file was 1, set con->physical.doc_root to cache.bases and con->physical.rel_path to '/host/uri'; otherwise just returns.
Step 3: mod_proxy.
If con->use_cache_file was 0, mod_proxy will set con->write_cache_file to 1; otherwise mod_proxy just returns.
Step 4: Actual request handle. request handled by mod_staticfile mod_compress or mod_proxy depend on lighttpd configuration.
Step 5: modcache_handle_response.
If con->write_cache_file was 1, modcache will try to save response content to 'cache.bases/host/uri', some useful response's headers to 'cache.bases/host/uri.cachehd'; otherwise modcache fills current response headers with cached headers.
Step 6: modcache_cleanup.
If con->write_cache_file was 1 and everything went ok, modcache closes fd of cached file.
Config example for lighttpd 1.4 series
FOR STATIC WEB PAGE SERVER:
server.modules = (
# ...., other modules
"mod_cache", # make sure mod_cache loaded before mod_proxy
"mod_proxy"
)
cache.support-queries = "enable" #ignore '?' in url
cache.bases = ("/data/cache") #write cached files in /data/cache directory
cache.refresh-pattern = (
"\.(?i)(flv)$" => "0 fetchall-for-range-request flv-streaming", # to work with mod_flv_streaming for flv files
"\.(?i)(js|css|xml)$" => "240", # update js/css/xml every 4 hours and on refresh requests
"\.(?i)(htm|html|shtml)$" => "30", # update html/htm/shtml every 30 minutes and on refresh requests
"\.(?i)(jpg|bmp|jpeg|gif|png)$" => "2880", # update graphics files every 2 days
"\.(?i)(rar|zip|wmv|avi|mp3|ape|rm|mpeg|mpg|wma|asf|rmvb|flv)$" => "0 fetchall-for-range-request", # cache media file forever
"." => "30 update-on-refresh" # default to update every 30 minutes and on refresh requests
)
#mod_proxy setting, config your backend servers here
proxy.server = ( "/" =>
(
( "host" => "x.x.x.x", "port" => 80 ) # real backend http server ip and port
)
)
#it's important to enable proxy.worked-with-mod-cache or mod_proxy will not cooperate with modcache
proxy.worked-with-mod-cache = "enable"
FOR BBS AND FORUM SERVER (V1.6.0 SUPPORTED):
server.modules = (
# ...., other modules
"mod_cache", # make sure mod_cache loaded before mod_proxy
"mod_proxy"
)
cache.support-queries = "enable" #ignore '?' in url
cache.dynamic-mode = "enable"
cache.bases = ("/data/cache") #write cached files in /data/cache directory
cache.refresh-pattern = (
"\.(?i)(flv)$" => "0 fetchall-for-range-request flv-streaming", # to work with mod_flv_streaming for flv files
"\.(?i)(js|css|xml)$" => "240", # update js/css/xml every 4 hours and on refresh requests
"\.(?i)(htm|html|shtml)$" => "30", # update html/htm/shtml every 30 minutes and on refresh requests
"\.(?i)(jpg|bmp|jpeg|gif|png)$" => "2880", # update graphics files every 2 days
"\.(?i)(rar|zip|wmv|avi|mp3|ape|rm|mpeg|mpg|wma|asf|rmvb|flv)$" => "0 fetchall-for-range-request", # cache media file forever
".(?i)php$" => "5", # update php request every 5 minutes
"." => "30 update-on-refresh" # default to update every 30 minutes and on refresh requests
)
#mod_proxy setting, config your backend servers here
proxy.server = ( "/" =>
(
( "host" => "x.x.x.x", "port" => 80 ) # real backend http server ip and port
)
)
proxy.worked-with-mod-cache = "enable"
#cache.programs-ext = (".php") # uncomment this if mod_fastcgi was loaded on this lighttpd server
Config example for lighttpd 1.5 series
FOR STATIC WEB PAGE SERVER:
server.modules = (
# ...., other modules
"mod_cache", # make sure mod_cache loaded before mod_proxy_core
"mod_proxy_core",
"mod_proxy_backend_http"
)
cache.support-queries = "enable" #ignore '?' in url
cache.bases = ("/data/cache") #write cached files in /data/cache directory
cache.refresh-pattern = (
"\.(?i)(flv)$" => "0 fetchall-for-range-request flv-streaming", # to work with mod_flv_streaming for flv files
"\.(?i)(js|css|xml)$" => "240", # update js/css/xml every 4 hours and on refresh requests
"\.(?i)(htm|html|shtml)$" => "30", # update html/htm/shtml every 30 minutes and on refresh requests
"\.(?i)(jpg|bmp|jpeg|gif|png)$" => "2880", # update graphics files every 2 days
"\.(?i)(rar|zip|wmv|avi|mp3|ape|rm|mpeg|mpg|wma|asf|rmvb|flv)$" => "0 fetchall-for-range-request", # cache media file forever
"." => "30 update-on-refresh" # default to update every 30 minutes and on refresh requests
)
#mod_proxy_core setting, config your backend servers here
proxy-core.backends = ( "x.x.x.x:80", "y.y.y.y:80")
proxy-core.balancer = "round-robin" # or "sqf" or "carp"
proxy-core.protocol = "http"
#it's important to enable proxy-core.worked-with-modcache or mod_proxy_core will not cooperate with modcache
proxy-core.worked-with-modcache = "enable"
FOR BBS AND FORUM SERVER (V1.6.0 SUPPORTED):
server.modules = (
# ...., other modules
"mod_cache", # make sure mod_cache loaded before mod_proxy_core
"mod_proxy_core",
"mod_proxy_backend_http"
)
cache.support-queries = "enable" #ignore '?' in url
cache.dynamic-mode = "enable"
cache.bases = ("/data/cache") #write cached files in /data/cache directory
cache.refresh-pattern = (
"\.(?i)(flv)$" => "0 fetchall-for-range-request flv-streaming", # to work with mod_flv_streaming for flv files
"\.(?i)(js|css|xml)$" => "240", # update js/css/xml every 4 hours and on refresh requests
"\.(?i)(htm|html|shtml)$" => "30", # update html/htm/shtml every 30 minutes and on refresh requests
"\.(?i)(jpg|bmp|jpeg|gif|png)$" => "2880", # update graphics files every 2 days
"\.(?i)(rar|zip|wmv|avi|mp3|ape|rm|mpeg|mpg|wma|asf|rmvb|flv)$" => "0 fetchall-for-range-request", # cache media file forever
".(?i)php$" => "5", # update php request every 5 minutes
"." => "30 update-on-refresh" # default to update every 30 minutes and on refresh requests
)
#mod_proxy_core setting, config your backend servers here
proxy-core.backends = ( "x.x.x.x:80", "y.y.y.y:80")
proxy-core.balancer = "round-robin" # or "sqf" or "carp"
proxy-core.protocol = "http"
#it's important to enable proxy-core.worked-with-modcache or mod_proxy_core will not cooperate with modcache
proxy-core.worked-with-modcache = "enable"
#cache.programs-ext = (".php") # uncomment this if mod_proxy_backend_fastcgi was loaded on this lighttpd server
Downloads
Stable version 1.8.0, released on Jun 06, 2009
Changelog
Stable Version 1.8.0, 06/06/2009
- 'support-accept-encoding' and 'try-gzip-deflate-only' options removed, 'memory-compress' and 'ignore-vary' options added
Stable Version 1.7.0, 04/30/2009
- support to save content in memory. please read above docs about V1.7.0 feature
Stable Version 1.6.3, 02/18/2009
- support to save gziped response to local cache
Stable Version 1.6.2, 02/17/2009
- v1.6.2 for 1.4.21 = v1.6.0 for lighttpd 1.4.19
Stable Version 1.6.0/1.6.1, 09/01/2008
- support dynamic generated web servers such as bbs/forum servers(see above config example)
- v1.6.0 for lighttpd 1.4.19 = v1.6.1 for lighttpd 1.5.0 r1992
Stable Version 1.4.4, 04/09/2008
- apply mod_proxy.c fix from medic123de#gmail
- upgrade modcache v1.4.4 to lighttpd 1.4.19
Stable Version 1.4.2/1.4.3, 02/29/2008
- fix bug on fetchall-for-range-request option
- can work with mod_flv_streaming module
- backport modcache v1.4.2 to lighttpd 1.4.18 as modcache v1.4.3
Stable Version 1.4.1, 09/23/2007
- upgrade lighttpd 1.5 to r1992
- put splaytree.c into modcache.c
- fix memory leak on handler_ctx usage
- fix memory leak on splaytree_splay usage
Stable Version 1.4, 05/03/2007
- upgrade lighttpd 1.5 to r1811
- status page for mod_status added
- cache.ignore-hostname added
- bugfix for checking cachehd file
Stable Version 1.3.2, 02/08/2007
- upgrade lighttpd 1.5 to r1605
- fix bug of saving partial content of backend server
- update logic of saving cache file
Stable Version 1.3.1, 01/29/2007
- upgrade lighttpd 1.5 to r1540
- two refresh-pattern options added: override-expire, ignore-cache-control-header
Stable Version 1.3, 01/23/2007
- porting modcache 1.2 to lighttpd 1.5 trunk(r1524), no new feature added
Stable Version 1.2, 11/28/2006
- fix fetch-all-for-range-request handling with http servers such as Apache
- use splaytree instead hash table to avoid collision of Range-Request or Cache Save handling
Stable Version 1.1, 11/17/2006
- cache.denyurls removed in favor of refresh-pattern's nocache options
- set proper RFC-compliant expire headers based on refresh-pattern rules and no-expire-header option added
- PURGE method supported!
for examples: Use 'PURGE /uri HTTP/1.1\r\nHost: www.examples.com\r\n\r\n' to delete cache file of http://www.examples.com/uri.
- bugfix in update_response_header_by_asis function
Stable Version 1.0, 10/27/2006
- V1.0 has been tested for more than 2 months on heavy traffic servers and worked as expected. It is quite stable!
- Right now V1.0 only supports static website very well, for better dynamic content caching, please wait for upcoming releases.
TODO
- Local disk cache management.
Discussion Group
Please visit ModCache group hosted on google-groups. Feedback are welcomed!
ModCache released under BSD License, Copyright (c) 2006, 2009 QUE Hongyu