High performance caching with nginx redis and php
A little how to on high performance caching using Nginx, Redis, PHP.
Prerequisites
There are various how to's all over the internet about installing the above to your server so we won't be going into that now!.
Once all of the above is installed we need to make some configuration changes to nginx.conf and your vhost.
Firstly edit nginx.conf
$ nano /etc/nginx/nginx.conf
Inside the http{}
block put the following:
upstream redis { server unix:/tmp/redis.sock; }
Now we need to edit the vhost file for the site you wish to cache.
$ nano /etc/nginx/sites-enabled/example.conf
Add the following inside a server{}
block
location ~ \.php$ { set $redis_key 'cache:$scheme://$host$request_uri'; if ($http_cookie ~* '_ndx') { set $redis_key '____FALSE'; } default_type text/html; redis_pass redis; error_page 404 405 502 504 = @php; } location @php { fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass unix:/dev/shm/example.sock; fastcgi_index index.php; include fastcgi_params; fastcgi_buffers 32 32k; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; }
Now test the configuration (dont restart yet)
$ /etc/init.d/nginx -t
If you have not already installed the http redis module for nginx please download and install from http://people.freebsd.org/~osa/ngx_http_redis-0.3.6.tar.gz. Recompile and restart nginx.
What we have done so far is tell Nginx to check Redis for a value with the key of cache:$scheme://$host$request_uri and if found it returns the value (the html) to the client and finishes the request trail else if not found it passes it to the @php upstream that is defined.
We now need to add things to the cache in the backend. We could do this inside Nginx directly with the redis2 module but it's not very flexible and we want the ability to make selective choices when caching to only cache certain objects for certain people, having our application do this and work out the logic at runtime is by far the most flexible and abstract way to accomplish the task.
This how to assumes you have access to the full rendered html that your application has outputted - this can be obtained using php's ob_* (output buffering) functions to collect the data into a variable.
Once you have the html string in a variable the rest is really quite simple, in lamens terms you connect to redis and add an expiring (if you wish) value with the key that was defined above (cache:$scheme://$host$request_uri). (psuedo code below)
Comments are disabled