Fast content serving WordPress HA with Caching, Galera & GlusterFS

Everyone wants to make the most of the least and for this we must head for smart choices. After many searches and test-driving solutions and complex combinations of memcached, redis, tmpfs ramdisk and various WordPress plugins I found a decent combination that everyone can apply.

For prerequisites I will point to other posts of mine and will concentrate on optimizations for this one.

Goals to achieve:

  • High Availability
  • Load balancing
  • Scalability
  • Centralized storage
  • Reduced server overhead and fast loading content

Prerequisites:

 

First if you have a classic WordPress installation test it’s performance here: http://gtmetrix.com and they will give you a detailed report and also suggestions what you should improve.

I was running a poor performing WP until now and decided to take action.

 

Steps:

Setup a galera cluster and migrate your database into

Then point wp-config.php to use the floating IP of Galera Cluster.

 

Setup you new WP instances

for host in {wordpress01,wordpress02}; do ssh $host \
   "yum -y install httpd"; done

for host in {wordpress01,wordpress02}; do ssh $host \
   "rm -fv /etc/httpd/conf.d/welcome.conf"; done

for host in {wordpress01,wordpress02}; do ssh $host \
   "tee /etc/httpd/conf.d/wordpress.conf << wp_alfa_beta
    <Directory "/wordpress">
    AllowOverride All
    </Directory>

    <filesMatch "\.(jpg|jpeg|js|html|css)$">
    SetOutputFilter DEFLATE
    </filesMatch>

    <VirtualHost *:80>
    ServerAdmin user@domain.com
    ServerName domain.tld
    ServerAlias http://www.domain.tld

    DocumentRoot /wordpress

    </VirtualHost>
    wp_alfa_beta"; done

 

Make sure you have a running GlusterFS on decent hardware

On every WP instance do:

mkdir /wordpress

yum -y install nfs-utils attr

systemctl enable rpcbind && systemctl start rpcbind

mount -t nfs gluster01.stor.domain.tld:/wordpress /wordpress

With a small comment here: if you are running WP instances and GlusterFS nodes as virtual machines on common hypervisors point every WP instance to the closest GlusterFS node.

Do not use glusterfs-fuse because it is slow and does not cope.

Example:

hv01: wordpress01, gluster01

hv02: wordpress02, gluster02

 

[root@wordpress01 ~] mount -t nfs gluster01.stor.domain.tld:/wordpress /wordpress

echo "gluster01.stor.domain.tld:/wordpress /wordpress nfs defaults,_netdev 0 0" >> /etc/fstab

[root@wordpress02 ~] mount -t nfs gluster02.stor.domain.tld:/wordpress /wordpress

echo "gluster02.stor.domain.tld:/wordpress /wordpress nfs defaults,_netdev 0 0" >> /etc/fstab

 

Sync your old content to the GlusterFS storage

[root@wordpress01_old ~]# rsync -avzr /var/www/html/* root@wordpress01.domain.tld:/wordpress/

[root@wordpress01 ~]# chown -R apache.apache /wordpress/*

 

Start you WP instances and get ready

for host in {wordpress01,wordpress02}; do ssh $host \
   "systemctl enable httpd && systemctl start httpd"; done

 

High Availability and Load Balancing will be achieved via HAProxy

We presume HAProxy is already installed.

vi /etc/haproxy/haproxy.cfg

and add something similar:

# Frontends
listen http *:80
option http-server-close # very important for keep-alive
option forwardfor except 127.0.0.0/8
acl wordpress hdr(host) -i domain.tld
use_backend wp_cluster if wordpress

# Backends
backend wp_cluster
server wordpress01 192.168.100.101:80 check
server wordpress02 192.168.100.102:80 check

 

Cache validator inside .htaccess

Make sure you .htaccess contains ETag header

<FilesMatch "\.(html|htm)$">
AddDefaultCharset UTF-8
<ifModule mod_headers.c>
Header unset Pragma
FileETag INode MTime Size
Header set Cache-Control "public, max-age=604800, must-revalidate"
Header set Connection keep-alive
</ifModule>
</FilesMatch>

<FilesMatch "\.(?i:ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf|x-html|css|xml|js|woff|woff2|ttf|svg|eot)(\.gz)?$">
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault A0
ExpiresByType image/gif A2592000
ExpiresByType image/png A2592000
ExpiresByType image/jpg A2592000
ExpiresByType image/jpeg A2592000
ExpiresByType image/ico A2592000
ExpiresByType image/svg+xml A2592000
ExpiresByType text/css A2592000
ExpiresByType text/javascript A2592000
ExpiresByType application/javascript A2592000
ExpiresByType application/x-javascript A2592000
</IfModule>
<IfModule mod_headers.c>
Header unset Pragma
FileETag INode MTime Size
Header set Cache-Control "public, max-age=2592000"
Header set Connection keep-alive
</IfModule>
</FilesMatch>

 

Once you have you WP running it’s time to optimize content

The best plugins I could find until now are:

Most efficient .css & .js minify solution until now

wget https://github.com/yui/yuicompressor/releases/download/v2.4.8/yuicompressor-2.4.8.jar

yum install java-1.8.0-openjdk

cd /wordpress/wp-content/themes/<theme>

for i in `ls . |grep .css`; do cp -p "$i" "$i"_orig && java -jar /root/yuicompressor-2.4.8.jar --type css -o "$i" "$i"_orig; done

cd /wordpress/wp-content/themes/<theme>/css

for i in `ls . |grep .css`; do cp -p "$i" "$i"_orig && java -jar /root/yuicompressor-2.4.8.jar --type css -o "$i" "$i"_orig; done

cd /wordpress/wp-content/themes/<theme>/js

for i in `ls . |grep .js`; do cp -p "$i" "$i"_orig && java -jar /root/yuicompressor-2.4.8.jar --type js -o "$i" "$i"_orig; done

 

WP Fastest Cache (generates persistent static html content for every dynamic page) – download

Features:

  1. Mod_Rewrite which is the fastest method is used in this plugin
  2. All cache files are deleted when a post or page is published
  3. Admin can delete all cached files from the options page
  4. Admin can delete minified css and js files from the options page
  5. Block cache for specific page or post with Short Code
  6. Cache Timeout – All cached files are deleted at the determinated time
  7. Cache Timeout for specific pages
  8. Enable/Disable cache option for mobile devices
  9. Enable/Disable cache option for logged-in users
  10. SSL support
  11. CDN support
  12. Preload Cache – Create the cache of all the site automatically

Performance Optimization:

  1. Generating static html files from your dynamic WordPress blog
  2. Minify Html – You can decrease the size of page
  3. Minify Css – You can decrease the size of css files
  4. Enable Gzip Compression – Reduce the size of files sent from your server to increase the speed to which they are transferred to the browser.
  5. Leverage browser caching – Reduce page load times for repeat visitors
  6. Combine CSS – Reduce number of HTTP round-trips by combining multiple CSS resources into one
  7. Combine JS

WP Smush – Image Optimization (does Lossless image optimization) – download

Features:

  • Optimize your images using advanced lossless compression techniques.
  • Process JPEG, GIF and PNG image files.
  • Auto-smush your attachments on upload.
  • Manually smush your attachments individually in the media library, or in bulk 50 attachments at a time.
  • Smush all standard web-sized images 1MB or smaller.
  • Smush images with no slowdown using WPMU DEV’s fast, reliable Smush API.
  • View advanced compression stats per-attachment and library totals.

WP Deffered JavaScripts (delays the load of JavaScripts for faster response)

This plugin defer the loading of all JavaScripts added by the way ofwp_enqueue_script(), using LABJS. The result is a significant optimization of loading time.

It is compatible with all WordPress JavaScript functions (wp_localize_script(), js in header, in footer…) and works with all well coded plugins.

ShortPixel Image Optimizer

ShortPixel makes your website load faster by reducing the size of your images and helps you rank better in Google search. With both lossy and lossless image compression available for all common image types (PNG, JPG, GIF), plus PDF files. The plugin is free to use for 100 images/month.

How does it work?

Both new and old images can be optimized with ShortPixel. Once activated, the plugin instantly processes new images uploaded to your website. Bulk optimization will automatically process all your past image gallery with one click. Images and thumbnails are processed in the cloud, and replaced back into your website. It’s simple to use, yet incredibly powerful.

Plugin features. What you see is what you get:

  • supports PNG, JPG, GIF (still and animated) images and PDF documents
  • thumbnails and featured images are also optimized
  • CMYK to RGB conversion
  • free 100 image credits/month. Images that are optimized less that 5% are bonus
  • no file size limit
  • originals are saved in a backup folder and can be manually restored
  • ‘Bulk’ optimize past gallery with one click
  • 40 days optimization report with all image details and overall statistics
  • works great for eCommerce websites using WooCommerce plugin
  • multisite support for a single API key
  • compatible with WP Engine hosted websites
  • compatible with WPML and WPML Media plugins.

 

 

Test the performance of you WP again

Performance test here: http://gtmetrix.com and compare the detailed report for more suggestions what you could improve.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s