amuck-landowner

Extremely Fast WordPress with Redis Cache

ElliotJ

Member
Verified Provider
Hey everyone.

Thought I should share this method of speeding WordPress up dramatically without much configuration.

This is the caching method used over at Gatsby and any WordPress based client sites I maintain. As the cache is in-memory, it handles surges of traffic very well.

Want to see how it handles? Head over to Gatsby.

Requirements:

  • The ability to follow simple instructions
  • Root access to your server (Just incase this is picked up by Google)
  • About 15 minutes of your time
This tutorial assumes you already have WordPress set up and ready to roll.
I personally use this in conjunction with APC. It should work with other caching methods as well, but your milage may vary.

1. Back your stuff up

Although nothing we're going to be doing will touch your databases and whatnot, it's probably a good idea to make sure you're able to revert to how things were originally. Just incase you completely fudge something up.

In all honesty, you should have robust backups in place already. If not, here's your gentle reminder to get backups set up.

Also - It's not a backup unless you're able to restore it easily in an emergency.

2. Add a Repo

This is genuinely the most taxing part of the process, although it's relatively simple. The issue is that most Linux distros have pretty outdated versions of Redis in their repositories.

Although you could just install the respective .deb/.rpm, it's a good idea to get a frequently updated repository added to your system just incase an exploit is found in Redis.

If you're running Debian Linux I personally recommend you use the DotDeb repository

If you're running a RedHat based Linux distro, I personally recommend you use Remi Collet's repository

Follow the respective instructions on each site!

3. Install Redis

If you're running a Debian based Linux distro


apt-get install redis

If you're running a RedHat based Linux distro


yum install redis

Once installed, you can fire up Redis


/etc/init.d/redis start
OR
/etc/init.d/redis-server start

4. Make WordPress Use Redis

Here's the last step. We're going to need a couple of files to make WordPress interact with Redis.

The idea is that we want to use a new index.php, so that every single valid request hits Redis before asking WordPress to regenerate the page.

To do that, we'll have to move the original index.php


mv index.php backup_index.php

You'll then need to grab predis.php so PHP can interact with Redis


wget http://uploads.staticjw.com/ji/jim/predis.php

Finally, grab the new index.php


wget http://pastie.org/pastes/7953263/text -O index.php

If all goes well, load up your WordPress site and pages should appear. If not, you've probably done something wrong.

Final Statements

  • I do not claim any credit for this caching method, all of which goes to Jim Westergren.
  • In regards to security, it only displays the cached pages if the visitor isn't logged in - That means that whilst you're logged in pages may load slower.
  • To refresh a page's cache, force a page reload (F5). Pages aren't regenerated if you're simply clicking through pages.
 
Last edited by a moderator:

NodeDeals

New Member
A good tutorial. It would be great if you can explain how this will speed up a wordpress site. How is this caching different then using CDN like cloudflare, wordpress CDN and Cache plugins like total cache?
 

Amitz

New Member
The tutorial itself is great, but I would also be interested in some comparison to Varnish & Co.!
 

ElliotJ

Member
Verified Provider
Which site are you testing this on, or is an example of?
I'm using it across the Gatsby.im network if you want a peak around.

If you view the source of any page at the bottom it should indicate how fast the page was generated.

A good tutorial. It would be great if you can explain how this will speed up a wordpress site. How is this caching different then using CDN like cloudflare, wordpress CDN and Cache plugins like total cache?
It speeds up the page generation aspect of speeding a WordPress site up.

It's not an alternative for a CDN - You can use caching and a CDN together though - I personally use Redis+CDN77.

The real question is whether this is the best method for you.

For me, security was a concern, and blog authors needed to be able to view their changes in real-time without having to wait for the cache to catch up. No other solution was as simple, reliable and fulfilled my needs like Redis.
 

eva2000

Active Member
The real question is whether this is the best method for you.

For me, security was a concern, and blog authors needed to be able to view their changes in real-time without having to wait for the cache to catch up. No other solution was as simple, reliable and fulfilled my needs like Redis.
Thanks for the guide, definitely the easiest wordpress cache method to setup and this is actually my first time using redis !

Did a very quick benchmark against my Centmin Mod v1.2.3 beta based Wordpress fastcgi_cache setup versus the above redis cache setup.

If you get 500 Internal Server Error loading the custom index.php page and the following error see https://gist.github.com/JimWestergren/3053250/#comment-832738

 



2013/05/25 04:07:20 [error] 3539#0: *22 FastCGI sent in stderr: "PHP message: PHP Parse error:  syntax error, unexpected ')' in /usr/local/nginx/html/wp/index.php on line 61" while reading response header from upstream, client: 192.168.56.1, server: localhost, request: "GET /wp/ HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "192.168.56.140", referrer: "http://192.168.56.140/wp/"
You may have extra closing bracket ) on line 61

 

change

 



(isset($_SERVER['HTTP_CACHE_CONTROL']) && $_SERVER['HTTP_CACHE_CONTROL'] == 'max-age=0') ? $submit = 1 : $submit = 0);   
to



(isset($_SERVER['HTTP_CACHE_CONTROL']) && $_SERVER['HTTP_CACHE_CONTROL'] == 'max-age=0') ? $submit = 1 : $submit = 0;   

With default Centmin Mod v1.2.3 beta install you have a choice of 2 different versions of redis, for below tests, I will use redis 2.6.13-1 from CentALT repository.

 


Code:
[root@hostname tools]# yum -q list redis
Available Packages
redis.x86_64   2.4.10-1.el6   epel


Code:
[root@hostname tools]# yum -q list redis --disablerepo=epel
Available Packages
redis.x86_64   2.6.13-1.el6   CentALT



Install redis 2.6.13-1 for CentOS 6.3 64bit



Code:
yum -y install redis --disablerepo=epel


Siege 3.0.1 benchmarks

 

Wordpress redis/predis enabled

 


Code:
curl -I http://192.168.56.140/wp/
HTTP/1.1 200 OK
Server: nginx
Date: Fri, 24 May 2013 18:17:12 GMT
Content-Type: text/html; charset=utf-8
Connection: keep-alive
Vary: Accept-Encoding

Code:
siege -q -b -c100 -r100 http://192.168.56.140/wp/

Transactions:                  10000 hits
Availability:                 100.00 %
Elapsed time:                  15.39 secs
Data transferred:              34.75 MB
Response time:                  0.15 secs
Transaction rate:             649.77 trans/sec
Throughput:                     2.26 MB/sec
Concurrency:                   99.43
Successful transactions:       10000
Failed transactions:               0
Longest transaction:            0.20
Shortest transaction:           0.04



Wordpress fastcgi_cache with ngx_pagespeed off

 


Code:
[root@hostname wp]# curl -I http://192.168.56.140/wp/
HTTP/1.1 200 OK
Server: nginx
Date: Fri, 24 May 2013 18:55:44 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Vary: Accept-Encoding
X-Pingback: http://192.168.56.140/wp/xmlrpc.php
X-Cached: HIT

 


Enable Nginx fastcgi_cache for wordpress

Code:
[root@hostname wp]# /root/tools/fastcgicache_switch.sh 
/root/tools/fastcgicache_switch.sh on
/root/tools/fastcgicache_switch.sh off


Code:
[root@hostname wp]# /root/tools/fastcgicache_switch.sh on
fastcgi_cache enabled


Setting option from ("off")
Setting option from ("FileCachePath", "/var/ngx_pagespeed_cache")
Setting option from ("MessageBufferSize", "100000")
Setting option from ("XHeaderValue", "ngx_pagespeed")
Setting option from ("RewriteLevel", "CoreFilters")
Setting option from ("EnableFilters", "collapse_whitespace,remove_comments")
Setting option from ("EnableFilters", "combine_javascript")
Setting option from ("EnableFilters", "rewrite_images")
Setting option from ("EnableFilters", "convert_png_to_jpeg")
Setting option from ("EnableFilters", "convert_jpeg_to_webp")
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
Stopping nginx:                                            [  OK  ]
Starting nginx: Setting option from ("off")
Setting option from ("FileCachePath", "/var/ngx_pagespeed_cache")
Setting option from ("MessageBufferSize", "100000")
Setting option from ("XHeaderValue", "ngx_pagespeed")
Setting option from ("RewriteLevel", "CoreFilters")
Setting option from ("EnableFilters", "collapse_whitespace,remove_comments")
Setting option from ("EnableFilters", "combine_javascript")
Setting option from ("EnableFilters", "rewrite_images")
Setting option from ("EnableFilters", "convert_png_to_jpeg")
Setting option from ("EnableFilters", "convert_jpeg_to_webp")
                                                           [  OK  ]


Code:
[root@hostname wp]# siege -q -b -c100 -r100 http://192.168.56.140/wp/

Transactions:                  10000 hits
Availability:                 100.00 %
Elapsed time:                   4.07 secs
Data transferred:              32.42 MB
Response time:                  0.04 secs
Transaction rate:            2457.00 trans/sec
Throughput:                     7.97 MB/sec
Concurrency:                   97.96
Successful transactions:       10000
Failed transactions:               0
Longest transaction:            0.14
Shortest transaction:           0.00

Summary Results for Siege 3.0.1 Benchmark

 

Run with 100 user concurrency and 100 reps shows Nginx fastcgi_cache is ~4x times faster but indeed Redis cache above is much easier to setup and better than no cache as I tried and load was too high for my virtualbox instance without caching !

 

Redis cache 

  • Transaction rate: 649.77 trans/sec 
  • Average Response time: 0.15s
  • Longest Transaction: 0.20s
  • Shortest Transaction: 0.04s
Nginx fastcgi_cache 

  • Transaction rate: 2,457 trans/sec 
  • Average Response time: 0.04s
  • Longest Transaction: 0.14s
  • Shortest Transaction: 0.00s

 

From phpRedisAdmin https://github.com/ErikDubbelboer/phpRedisAdmin showing cached wordpress page in redis cache

 

8aRYglY.png
 
Last edited by a moderator:

ElliotJ

Member
Verified Provider
Cheers for the additional info eva2000 :)

I'd never really benchmarked it against anything else in a technical way, besides 'well, this feels faster' testing.

It's eyeopening to see how (relatively) slow it is compared with other methods.

Perhaps putting the extra 30 minutes in for a faster set up is worth it, ah well :p
 

eva2000

Active Member
Yeah I love my benchmarking/stats gathering :D

Will be interesting to see how redis scales as concurrency loads increase - just need to move my testing to beefier servers :)
 

eva2000

Active Member
Oh one more thing wget of the paties.org text for new index.php didn't work for me, it downloaded a html page itself so loading index.php showed html php code.

Used lynx to dump php code to index.php

Code:
lynx -dump http://pastie.org/pastes/7953263/text > index.php
 

willie

Active Member
Interesting including the nginx comparison.  I guess redis suffers a bit because of the extra tcp roundtrip.  Overall unless you have super high traffic, I think it's simplest to use one of the new cheap SSD vps's, which should get rid of almost all of the traditional mysql lag.  I'm very impressed with the $15.60/year one (leb35 coupon) from ramnode.
 

eva2000

Active Member
Indeed fast SSD or SSD cached VPS does help as well - just setup a cheap 128MB SSD Cached VPS for further wordpress + Centmin Mod nginx tests :)
 

Ruchirablog

New Member
Auther says and I quote 

Average execution without redis: 1.614 seconds for the home page and 0.174 seconds for blog posts (without using any cache plugin).
He should be having some serious performance issues then. Check out my blog www.ruchirablog.com and load some pages. There is a page generation time counter on the footer. 19 plugins active and no cache. No memcached or anything and no CDN's . Every page is generated dynamically. 
 
Last edited by a moderator:

thuvienvps

New Member
Seems really useful guide for me, most of my site is running on Wordpress (Nginx, PHP FPM, MaridDB). Bookmarked and will try soon. Many tks!
 
Top
amuck-landowner