How to Implement WordPress Load Balancing with Shared Database and File Synchronization


16 views

When scaling WordPress for high-traffic scenarios, a common approach involves:

  • Two or more web servers behind a load balancer
  • A centralized database server (often with replication)
  • Synchronized file storage for uploads

Here's the technical workflow we implemented:

1. SAN Cluster Setup:
   - Configured two web servers connected to SAN storage
   - Created /blog directory on SAN
   - Mounted as virtual directory on both servers (e.g., /var/www/html/blog)

2. WordPress Installation:
   - Single installation on primary server
   - Configured to use remote MySQL servers
   - Identical IIS virtual directory configuration on both servers

3. Database Configuration:
   - MySQL master-slave replication setup
   - wp-config.php modifications:
     define('DB_HOST', 'mysql-cluster.example.com');
     define('WP_DEBUG', false);

For the wp-content/uploads directory, we implemented these solutions:

  • SAN Storage: All uploads go directly to shared storage
  • Alternative Approaches:
    • NFS mounts for shared filesystem
    • GlusterFS distributed filesystem
    • rsync cron jobs (for simpler setups)

Key considerations for the LB setup:

# Sample HAProxy configuration snippet
frontend http-in
    bind *:80
    acl is_blog path_beg /blog
    use_backend blog_servers if is_blog

backend blog_servers
    balance leastconn
    option httpchk HEAD /blog HTTP/1.1\r\nHost:\ example.com
    server blog1 192.168.1.10:80 check
    server blog2 192.168.1.11:80 check

For optimal performance:

# Redis Object Cache Configuration
define('WP_REDIS_HOST', 'redis.example.com');
define('WP_REDIS_PORT', 6379);
define('WP_CACHE_KEY_SALT', 'blog_');

# Batcache settings (in wp-config.php)
$batcache = array(
    'remote' => 1,
    'debug' => false,
    'cache_control' => true
);

Essential monitoring tools:

  • New Relic APM for PHP performance
  • Percona PMM for MySQL monitoring
  • File integrity checks using Tripwire

When deploying WordPress across multiple web servers behind a load balancer with a centralized database, we need to address several critical components:

  • File system synchronization (particularly for wp-content/uploads)
  • Session persistence configuration
  • Database connection management
  • Caching layer coordination

The SAN-based approach mentioned works well for Windows environments. For Linux-based deployments, consider these alternatives:

// Example fstab entry for NFS share
nas01:/wp_shared /var/www/html/wp-content/uploads nfs rw,hard,intr 0 0

// Alternative using GlusterFS
mount -t glusterfs gluster01:/wp_volume /var/www/html/wp-content

For MySQL high availability, implement either master-slave replication or a cluster solution:

# Sample my.cnf for master server
[mysqld]
server-id = 1
log-bin = mysql-bin
binlog-format = ROW
binlog-do-db = wordpress_db

# Sample my.cnf for slave server
[mysqld]
server-id = 2
relay-log = mysql-relay-bin
read-only = 1

Essential wp-config.php modifications:

define('WP_HOME', 'https://mycompany.com/blog');
define('WP_SITEURL', 'https://mycompany.com/blog');
define('WP_CONTENT_DIR', '/san_mount/wp-content');
define('WP_CONTENT_URL', 'https://mycompany.com/blog/wp-content');

// For database failover
$mysql_servers = array(
    'primary' => array(
        'host' => 'db01.mycompany.com',
        'user' => 'wp_user',
        'password' => 'secure_password',
        'database' => 'wordpress_db'
    ),
    'secondary' => array(
        'host' => 'db02.mycompany.com',
        'user' => 'wp_user',
        'password' => 'secure_password',
        'database' => 'wordpress_db'
    )
);

Key considerations for your load balancer setup:

  • Session stickiness configuration
  • Health check endpoints (/blog/wp-admin/admin-ajax.php?action=health-check)
  • SSL termination strategy

Example NGINX configuration for session persistence:

upstream wordpress_backend {
    ip_hash;
    server web01.mycompany.com:80;
    server web02.mycompany.com:80;
    keepalive 32;
}

For environments without shared storage, implement rsync synchronization:

#!/bin/bash
# Sync wp-content every 5 minutes
*/5 * * * * rsync -az --delete web01:/var/www/html/wp-content/ web02:/var/www/html/wp-content/

Implement a distributed caching solution to prevent cache inconsistencies:

// Redis Object Cache configuration
define('WP_REDIS_HOST', 'redis-cluster.mycompany.com');
define('WP_REDIS_PORT', 6379);
define('WP_REDIS_CLUSTER', [
    'tcp://redis01:6379',
    'tcp://redis02:6379',
    'tcp://redis03:6379'
]);