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'
]);