How to Set Up a Load Balanced and Redundant LAMP Web Application on GoGrid
From GoGrid
Contents |
Overview
This how-to document is a step-by-step guide to setting up an HA (Highly Available) LAMP (Linux/Apache/MySQL/PHP) environment within GoGrid. The setup consists of a load-balanced web front end with content being stored on Cloud Storage. The backend database configuration employs MySQL Master-Master replication. Failover for both the web front end and the database backend are seamless. In addition to providing additional resources to handle higher loads, the web site(s) being run on this configuration will stay online even when one web server and/or one database server(s) go offline.
The example architecture used in this document can be applied to any Linux environment available on GoGrid. The resources used in this how-to consist of the following:
- 2+ web/app servers using CentOS 5.1 64-bit with LAMP software
- 2 database serverw using CentOS 5.1 64-bit with MySQL 5.0
- GoGrid's Cloud Storage service
- GoGrid's (F5) Load Balancer service
This setup will allow you to easy manage a high availability PHP/MySQL application such as Drupal, PHPBB, osCommerce, Wordpress, Joomla, Mambo, ZenCart, or your own application. The same general principals can be applied to Windows environment that run on ASP.NET, however the setup will certainly vary.
The above infrastructure will allow you to host all of your web files on Cloud Storage with your web/app servers simply acting as TCP/IP processors for hosting your site. The database server will act as your private database with no public connection to the outside world while the F5 load balancer will balance the traffic among your public web/app servers. To scale your infrastructure, simply add more web/app servers and follow the same configuration guidelines mentioned below.
This setup is secure, redundant and maximizes the resources available to your GoGrid cloud.
Getting Started
Overview
In this scenario, we will be using the following objects in our GoGrid cloud. Instructions for instantiating each of the objects are below. You may wish to use different configurations in your own environment.
Servers
| Name | Type | RAM | Operating System | Image | Public IP | Private IP |
|---|---|---|---|---|---|---|
| web01 | Web Server | 1GB | CentOS 5.1 (64-bit) | LAMP | 208.1.1.3 | 10.1.1.3 |
| web02 | Web Server | 1GB | CentOS 5.1 (64-bit) | LAMP | 208.1.1.4 | 10.1.1.4 |
| db01 | Database Server | 2GB | CentOS 5.1 (64-bit) | MySQL 5.0 | 208.1.1.11 | 10.1.1.11 |
| db02 | Database Server | 2GB | CentOS 5.1 (64-bit) | MySQL 5.0 | 208.1.1.12 | 10.1.1.12 |
The amount of RAM used for these servers only an example and is not a suggestion as to how much may be required for your particular setup. It is important to deploy servers with enough RAM so that swap utilization can be avoided as much as possible.
Load Balancers
| Name | Load Balancer Type | Load Balancer Persistence | Virtual IP/Port Pair | Real IP/Port Pairs |
|---|---|---|---|---|
| LB01 | Round Robin | Source Address | 208.1.1.2:80 | 208.1.1.3:80 208.1.1.4:80 |
Database IP Failover
| Hearbeat | Floating IP |
|---|---|
| IP used by web servers to access database servers | 10.1.1.10 |
Certain information used through this document such as the IP addresses, domain names, passwords, etc., will be different than what you will use. Such items are emphasized in red and should be replaced with your own. Make sure you do so consistently.
Web/App Servers
The first thing to setup is our first web server. Simply do the following:
- Log into your GoGrid account at My.GoGrid.com.
- Click on the "Add" button from the Grid menu
- Select "web/app server" to deploy from the add menu.
- Select the type of Operating System you want along with the amount of RAM and the Server Image. For this environment, you will want to setup a (CentOS 5.1) LAMP server. For these simple web servers ,you may want to choose 1GB of RAM.
- Enter an IP Address from your list of available IP's at the left of your screen. The system will automatically display all unused IP addresses that are currently available to you. In this scenario, we will use 208.1.1.3 as the IP address of the first web server.
- Name your server and add a description. In this scenario, we will use web01.
- Click on the "Save" button
- Your server will be deployed within 2-15 minutes.
- To obtain your server’s password, go to the “Support” tab and click on “Passwords” or right-click on the server in the UI and click on "Password". Changing the password here will not change your server password; this interface is only used for you to store passwords and to allow our Support teams access to your passwords to provide technical support, when needed.
Do this again for an additional web server. In this example, the second server's name will be web02 with an IP of 208.1.1.4.
Database Servers
Now that you have a web/app server, you need a database server. To add a database server, do the following:
- Log into your GoGrid account at My.GoGrid.com.
- Click on the "Add" button from the Grid menu
- Select "database server" to deploy from the add menu.
- Select the type of Operating System you want along with the amount of RAM and the Server Image. For this environment, you will want to setup a (CentOS 5.1) MySQL 5.0 server. For your db server, it is best to choose at least 2GB of RAM.
- Enter an IP Address from your list of available IP's at the left of your screen. The system will automatically display all unused IP addresses that are currently available to you. In this scenario, we will use 208.1.1.11 as the IP address of the first database server.
- Name your server and add a description. In this scenario, we will use db01.
- Click on the "Save" button.
- Your server will be deployed within 2-15 minutes.
- To obtain your server’s password, go to the “Support” tab and click on “Passwords” or right-click on the server in the UI and click on "Password". Changing the password here will not change your server password; this interface is only used for you to store passwords and to allow our Support teams access to your passwords to provide technical support, when needed.
Do this again for an additional database server. In this example, the second server's name will be db02 with an IP of 208.1.1.12.
Cloud Storage
Next, you need to add Cloud Storage and set up the routes to each server:
- Click on the "+" button on the Grid tab.
- Select the "Cloud Storage" option and icon. This will allow you to utilize more than 10GB of Cloud Storage
- Each GB of data over the initial 10GB quota will be charged for at a rate of $0.15 per GB.
To set up the connections from your web/app and database servers to Cloud Storage, follow the instructions on the Cloud Storage getting started guide.
F5 Load Balancers
Lastly, you can set up the F5 Load Balancer. Do this once you have set up ALL of your web/app and database servers.
- Click on the "add" button from the Grid menu
- Select "Load Balancer"
- The "Add Load Balancer" window will open
- Provide a name and description for the Load Balancer (you can have multiple instances of Load Balancers, all for different purposes)
- Add a "Virtual IP" from the list of available IP's at the left of screen. The system will automatically suggest the next available VIP from your IP block for you. In this scenario, we will use set the virtual IP to 208.1.1.2.
- Add a "Virtual Port" number for the port you wish to balance. In this example, the port will be set to port 80.
- Add "Real IP's" and "Real Ports" to the pool. These are the IP addresses and corresponding ports you wish to Load Balance. The system will automatically suggest the IP addresses you currently have deployed on the grid. For this example, we will add the IP addresses 208.1.1.3 and 208.1.1.4.
- You can add additional IP's and ports to the pool by clicking on the "+" button or by tabbing down a line if necessary.
- Select the type and persistence for the Load Balancing Algorithm. In this example, we will use Round Robin load balancing with Source Address persistence.
- Click "Save" and your Load Balancer should be completely deployed within a few minutes.
Configuring Your Servers
The following configuration should be done on all of your servers.
- To begin, enter the following command to edit your network interface configurations:
vi /etc/sysconfig/network-scripts/ifcfg-eth1
The entire file should read as below, but change
IPADDR=10.1.1.3to match the IP of the host you are editing. In this example it is for web01. Do this on each server, changing the IP as appropriate.DEVICE=eth1 BOOTPROTO=static ONBOOT=yes IPADDR=10.1.1.3 NETMASK=255.255.255.0
-
Set the hostname on all of your servers with the following command:
vi /etc/sysconfig/network
The entire file should read as below, but change
HOSTNAME=web01.localdomain.comfor hostname of the host you are editing. In this example it is forweb01. Do this on each server, changing theHOSTNAMEas appropriate.NETWORKING=yes NETWORKING_IPV6=no HOSTNAME=web01.localdomain.com
-
Set up your hosts files on each server.
vi /etc/hosts
The
/etc/hostsfile must contain all the cluster nodes hostnames. These names should be identical to the result ofuname -ncommand. The entire file should read as below, but change127.0.0.1 localhost.localdomain web01 localhoston the first line only (for localhost) to match whatever host you are editing. The remaining lines should be edited to reflect the IP addresses and hostnames of the other servers in your environment.127.0.0.1 localhost.localdomain web01 localhost 10.1.1.3 web01.localdomain.com web01 10.1.1.4 web02.localdomain.com web02 10.1.1.11 db01.localdomain.com db01 10.1.1.12 db01.localdomain.com db02
-
Now create a route to access GoGrid's Cloud Storage for each machine. You can easily do this with the following commands:
echo “any net 10.117.0.0/24 gw 10.1.1.1” >> /etc/sysconfig/static-routes
mkdir /mnt/cloudstorage
vi /etc/fstab
Append the following to the bottom of the
fstabfile, all on one line. Be sure to replace all occurrences of12345with your actual customer number (first part of your Cloud Storage hostname) and theyour_cloud_storage_passwordwith your Cloud Storage password which can be found on my.gogrid.com.//12345.cloud.storage.gogrid.com/12345 /mnt/cloudstorage cifs file_mode=0660,dir_mode=0770,uid=apache,gid=apache,userid=12345,password=your_cloud_storage_password
-
Now append the following lines to the bottom of the
rc.localfile:vi /etc/rc.local
So that it looks like this:
mount /mnt/cloudstorage umount /mnt/cloudstorage echo 0 > /proc/fs/cifs/LinuxExtensionsEnabled mount /mnt/cloudstorage
- Lastly, you want to ensure all of your servers are up to date. When this has completed, you can reboot them:
yum -y update
reboot
Configuring your Web Servers
To configure your web servers, do the items listed below. Remember that this tutorial is geared towards Wordpress, but you can do this with any PHP-MySQL applation for Linux.
- Ensure that
php-mysqlis installed on each web server:yum -y install php-mysql
- Now install Wordpress. You only have to do this from one web server and it doesn't matter which one you choose as the wordpress source files will actually be installed on your Cloud Storage allotment. Replace
wordpress-2.7.1.tar.gzwith the filename of whatever version you downloaded if it differs.cd /mnt/cloudstorage wget http://www.wordpress.org/latest.tar.gz tar zxvf wordpress-2.7.1.tar.gz mv wordpress myblog_wordpress cd myblog_wordpress mv wp-config-sample.php wp-config.php vi wp-config.php
- Now locate the following lines in the conf file edit them as shown below, replacing
myblog_wordpresswith the name you will assign to your database at a later step,wpadminwith the name you will assign to your database user at a later step,abcd1234with the password you will assign to your database user at a later step, and10.1.1.10with the IP address you will assign to your heartbeat at a later step.define('DB_NAME', 'myblog_wordpress'); define('DB_USER', 'wpadmin'); define('DB_PASSWORD', 'abcd1234'); define('DB_HOST', '10.1.1.10'); - Now configure Apache on each web server. To start, edit the Apache conf file:
vi /etc/httpd/conf/httpd.conf
Locate the following lines and remove the
#comment so that they look like below:EnableMMAP off EnableSendfile off
- Now your vhosts need to be configured so that you can run multiple websites on these servers if you ever need to:
vi /etc/httpd/conf.d/vhosts.conf
The entire file should read as below, but change the IP address to match the web server you are editing, in this example it is for web01. Do this on each web server, changing the IP as appropriate. Be sure to change
208.1.1.3with the appropriate IP address of the machine,yourdomain.comwith the appropriate domain name,yourname@youremail.comwith your actual email address, andmyblog_wordpresswith the actual document root of your web server asset up above.NameVirtualhost 208.1.1.3:80 <VirtualHost 208.1.1.3:80> ServerName yourdomain.com ServerAlias www.yourdomain.com ServerAdmin yourname@youremail.com DocumentRoot "/var/www/myblog_wordpress" AccessFileName .htaccess php_admin_flag safe_mode off php_value register_globals "1" php_value upload_max_filesize 8M <Directory "/var/www/myblog_wordpress"> Options Indexes FollowSymLinks AllowOverride All Order allow,deny Allow from all </Directory> </VirtualHost> - On each web server, create a symbolic link to Cloud Storage from the Apache document root with the following command, replacing
myblog_wordpresswith your actual document root.:ln -s /mnt/cloudstorage/myblog_wordpress /var/www/myblog_wordpress
- Restart Apache on each web server for the changes to take effect:
service httpd restart
Configuring Your Database Servers
- Install
heartbeaton both of your db servers. When installing heartbeat, you have to issue the command twice to get it fully installed. Do this on both DB servers:yum -y install heartbeat yum -y install heartbeat chkconfig heartbeat on
- Create a heartbeat
ha.cfconfiguration file on each DB server:vi /etc/ha.d/ha.cf
- Below are the complete contents of
ha.cffor db01. This file will be identical on both DB servers except for the line that begins withucastwhich should specify the private IP for the other DB server, and thenodevalues with the actualuname -aoutput from each database server:# File to write debug messages to debugfile /var/log/ha-debug # File to write other messages to logfile /var/log/ha-log # Facility to use for syslog()/logger logfacility local0 #logfacility daemon # keepalive: how long between heartbeats? keepalive 2 # deadtime: how long-to-declare-host-dead? deadtime 5 # warntime: how long before issuing "late heartbeat" warning? # See the FAQ for how to use warntime to tune deadtime. warntime 3 # Very first dead time (initdead) initdead 10 # What UDP port to use for bcast/ucast communication? udpport 694 # What interfaces to broadcast heartbeats over? #bcast eth1 ucast eth1 10.1.1.12 #specify a different system if using ucast (unicast) auto_failback on # Tell what machines are in the cluster # node nodename ... -- must match uname -n node db01.localdomain.com db02.localdomain.com # Less common options... # Treats ip as a psuedo-cluster-member # Used together with ipfail below... # note: don't use a cluster node as ping node #ping 10.10.10.1 # This assumes the network mentioned above is 10.10.10.0/24 # Processes started and stopped with heartbeat. Restarted unless # they exit with rc=100 #respawn userid /path/name/to/run #respawn hacluster /usr/lib/heartbeat/ipfail # 32-bit OS respawn hacluster /usr/lib64/heartbeat/ipfail # 64-bit OS # Do we use logging daemon? # If logging daemon is used, logfile/debugfile/logfacility in this file # are not meaningful any longer. You should check the config file for logging # daemon (the default is /etc/logd.cf) # more information can be found in # http://www.linux-ha.org/ha_2ecf_2fUseLogdDirective # Setting use_logd to "yes" is recommended use_logd yes
- Now you will need to create heartbeat authentication keys on each DB server by entering the
authkeysfile:vi /etc/ha.d/authkeys
- This file needs to be exactly the same on both DB servers and should contain the following two lines:
auth 2 2 sha1 insert_your_password_here
where
insert_your_password_hereis replaced with your real password. - Set permissions as follows on the file that was just created:
chmod 600 /etc/ha.d/authkeys
- Create a heartbeat haresources file on each DB server:
vi /etc/ha.d/haresources
This file also needs to be exactly the same on both DB servers and should contain the following single line where
db01.localdomain.comis replaced with your actual hostname and10.1.1.10is replaced with your hearbeat IP:db01.localdomain.com IPaddr::10.1.1.10
- Start heartbeat on both DB servers with the following command:
service heartbeat start
Check the output of the
ifconfigcommand and look for the floating IP to appear undereth1:0
MySQL Master-Master Replication
- Now we will set up MySQL with master-master replication. First, set the MySQL root user password on both machines where
YOUR_PASSWORD_HEREis replaced with your MySQL root password:mysqladmin -u root password YOUR_PASSWORD_HERE
- Create a user
replicationand grant it privileges on the database. Replace10.1.1.with the first three octets of your private IP range:mysql -u root –p mysql> GRANT REPLICATION SLAVE ON *.* TO ‘replicaton’@’10.1.1.%’ IDENTIFIED BY ‘slave’; mysql> GRANT REPLICATION CLIENT ON *.* TO ‘replication’@’10.1.1.%’; mysql> GRANT SUPER ON *.* TO ‘replication’@’10.1.1.%’; mysql> GRANT RELOAD ON *.* TO ‘replication’@’10.1.1.%’;
- Create the Wordpress database and create a db user and password to access the db other than root, replacing
myblog_wordpress,wpadmin,abcd1234and10.1.1.with the appropriate values you previously set:mysql> CREATE DATABASE myblog_wordpress; mysql> USE myblog_wordpress; mysql> GRANT ALL ON myblog_wordpress.* TO wpadmin@’10.1.1.%’ IDENTIFIED BY ‘abcd1234’; mysql> GRANT ALL ON myblog_wordpress.* TO wpadmin@localhost IDENTIFIED BY ‘abcd1234’; mysql> FLUSH PRIVILEGES; mysql> quit
Configuring db01
- Now configure MySQL on db01 by editing
my.cnfconf file:vi /etc/my.cnf
- Modify the file to look like this, replacing
myblog_wordpresswith the actual name of the database and10.1.1.12with the private IP of db02. Pay extra attention to the lines with the#Differentcomments:[mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock user=mysql # Default to using old password format for compatibility with mysql 3.x # clients (those using the mysqlclient10 compatibility package). old_passwords=1 server-id=1 #Different than db02 log-bin log-bin=/var/log/mysqld/db01-bin #Different than db02 log-bin-index=/var/log/mysqld/db01-bin-log.index #Different than db02 binlog-do-db=myblog_wordpress binlog-ignore-db=mysql binlog-ignore-db=test master-host=10.1.1.12 #Different than db02 master-user=replication master-password=slave replicate-same-server-id=0 auto-increment-increment=2 auto-increment-offset=1 master-connect-retry=5 relay-log=/var/log/mysqld/db01-relay-bin #Different than db02 relay-log-index=/var/log/mysqld/db01-relay-log.index #Different than db02 expire_logs_days=10 max_binlog_size=500M [mysqld_safe] log-error=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid
- Create the log file directories for the new MySQL logging and then restart the service:
mkdir /var/log/mysqld chown mysql:mysql /var/log/mysqld service mysqld restart
Configuring db02
- Now configure MySQL on db02 by editing
my.cnfconf file:vi /etc/my.cnf
- Modify the file to look like this, replacing
myblog_wordpresswith the actual name of the database and10.1.1.11with the private IP of db01. Pay extra attention to the lines with the#differentcomments:[mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock user=mysql # Default to using old password format for compatibility with mysql 3.x # clients (those using the mysqlclient10 compatibility package). old_passwords=1 server-id=2 log-bin log-bin=/var/log/mysqld/db02-bin #Different than db01 log-bin-index=/var/log/mysqld/db02-bin-log.index #Different than db01 binlog-do-db=myblog_wordpress binlog-ignore-db=mysql binlog-ignore-db=test master-host=10.1.1.11 #Different than db01 master-user=replication master-password=slave replicate-same-server-id=0 auto-increment-increment=2 auto-increment-offset=2 #Different than db01 master-connect-retry=5 relay-log=/var/log/mysqld/db02-relay-bin #Different than db01 relay-log-index=/var/log/mysqld/db02-relay-log.index #Different than db01 expire_logs_days=10 max_binlog_size=500M [mysqld_safe] log-error=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid
- Create the log file directories for the new MySQL logging and then restart the service:
mkdir /var/log/mysqld chown mysql:mysql /var/log/mysqld service mysqld restart
Verify the MySQL Replication Status
- To verify the MySQL replication, enter MySQL and run the following commands:
mysql -u root –p mysql> SHOW MASTER STATUS; mysql> SHOW SLAVE STATUS\G
- The most important lines to check are the following, which should read “Yes” on both DB servers:
Slave_IO_Running: Yes Slave_SQL_Running: Yes
- Also important is the following line from
SHOW SLAVE STATUS\Gwhich should match thePositionvalue fromSHOW MASTER STATUS;on the other server. The number may differ from what you see below:Read_Master_Log_Pos: 98
- MySQL replication usually works well and is extremely useful, but the databases can get out of sync under certain conditions. One thing to try is to issue the following commands on both servers:
mysql> stop slave; mysql> reset master; mysql> reset slave; mysql> start slave;
- If that doesn’t work, follow the "Restoring from Backups" section below.
Setting up Backups
This backup configuration is very basic and is only a suggestion of one way you can ensure you have something to fall back on if something goes wrong. It only maintains one copy of backups from the night before. Also, some of this is redundant, but it ensures your backups will continue from more than one source should one server be off for an extended period of time. Note that these operations are all scheduled everyday at 2:00am. This time can be adjusted as desired, but should be kept the same on all servers to ensure the web and DB content in the backups are as synchronized as possible.
Configuring Backups on web01
- To configure backups on the first web server, you will need to create a backups directory on the localhost:
mkdir /mnt/cloudstorage/backups mkdir /root/backups
- Now create a simple bash script to backup your document root:
vi /root/backups/web01-backup.sh
Enter the following into the file, replacing
myblog_wordpressin all instances with the document root on Cloud Storage:#!/bin/bash tar czf /mnt/cloudstorage/backups/web01-myblog_wordpress.tar.gz /mnt/cloudstorage/myblog_wordpress /bin/cp /mnt/cloudstorage/backups/web01-myblog_wordpress.tar.gz /root/backups/web01-myblog_wordpress.tar.gz
- Modify the script's permissions to be run by root:
chmod +x /root/backups/web01-backup.sh
- Now set up a crontab to execute the backup script nightly at 2am:
crontab -e * 2 * * * /root/backups/web01-backup.sh
Configuring Backups on web02
- Now configure backups on the second web server. The process is identical to web01 except the name of the server has changed:
mkdir /root/backups
- Now create a simple bash script to backup your document root:
vi /root/backups/web02-backup.sh
Enter the following into the file, replacing
myblog_wordpressin all instances with the document root on Cloud Storage:#!/bin/bash tar czf /mnt/cloudstorage/backups/web02-myblog_wordpress.tar.gz /mnt/cloudstorage/myblog_wordpress /bin/cp /mnt/cloudstorage/backups/web02-myblog_wordpress.tar.gz /root/backups/web02-myblog_wordpress.tar.gz
- Modify the script's permissions to be run by root:
chmod +x /root/backups/web02-backup.sh
- Now set up a crontab to execute the backup script nightly at 2am:
crontab -e * 2 * * * /root/backups/web02-backup.sh
Configuring Backups on db01
- Configure backups on the first db server. You will need to create a backups directory on the localhost:
mkdir /root/backups
- Now create a simple bash script to backup your document root:
vi /root/backups/db01-backup.sh
Enter the following into the file, replacing
wpadminwith your database username,abcd1234with your database password, andmyblog_wordpresswith your database name:#!/bin/bash mysqldump --user=wpadmin --password=abcd1234 myblog_wordpress > /root/backups/db01-myblog_wordpress.sql /bin/cp /root/backups/db01-myblog_wordpress.sql /mnt/cloudstorage/backups/db01-myblog_wordpress.sql
where
abcd1234is replaced with your database password. - Modify the script's permissions to be run by root:
chmod +x /root/backups/db01-backup.sh
- Now set up a crontab to execute the backup script nightly at 2am:
crontab -e * 2 * * * /root/backups/db01-backup.sh
Configuring Backups on db02
- Configure backups on the second db server. This is almost identical to db01 except the hostnames have changed:
mkdir /root/backups
- Now create a simple bash script to backup your document root:
vi /root/backups/db02-backup.sh
Enter the following into the file, replacing
wpadminwith your database username,abcd1234with your database password, andmyblog_wordpresswith your database name:#!/bin/bash mysqldump --user=wpadmin --password=abcd1234 myblog_wordpress > /root/backups/db02-myblog_wordpress.sql /bin/cp /root/backups/db02-myblog_wordpress.sql /mnt/cloudstorage/backups/db02-myblog_wordpress.sql
where
abcd1234is replaced with your database password. - Modify the script's permissions to be run by root:
chmod +x /root/backups/db02-backup.sh
- Now set up a crontab to execute the backup script nightly at 2am:
crontab -e * 2 * * * /root/backups/db02-backup.sh
Restoring From Backups
If something causes the databases to become out of synch or if it is necessary to go back to an earlier state of the Wordpress blog for any other reason, the following procedure can be used to restore the backups that were setup in the previous section. Since Wordpress content is stored as a mixture of web and database content, it is important when performing a restore to restore everything from web and DB backups taken at the same time.
Be certain to check that the backups exist and are in good order before proceeding as the first steps are destructive. It’s always a good idea to be safe and make backup copies of the existing content before proceeding with this restoration.
Restoring Web Servers
You can restore web servers once from either web server since the source files are hosted on Cloud Storage. Since each web server accesses the files on Cloud Storage, you will simply need to run the following commands from one of the web server to restore a backup, replacing myblog_wordpress in all instances with your document root.
rm -rf /mnt/cloudstorage/myblog_wordpress tar zxvf /mnt/cloudstorage/backups/web01-myblog_wordpress.tar.gz /mnt/cloudstorage
This will restore a single backup to both web servers with minimal downtime.
Restoring Database Servers
Since the MySQL servers are in master-master replication, you will only need to restore one database server and the other will pick up the changes. Enter the following commands on a single db server to restore them both, replacing myblog_wordpress in all instances with your database name, wpadmin in all instances with your database password, 10.1.1 in all instances with the first 3 octets of your private IP range, and abcd1234 in all instances with your database password:
mysql -u root -p mysql> DROP DATABASE myblog_wordpress; mysql> CREATE DATABASE myblog_wordpress; mysql> USE myblog_wordpress; mysql> source /mnt/cloudstorage/backups/db01-myblog_wordpress.sql mysql> GRANT ALL ON myblog_wordpress.* TO wpadmin@'10.1.1.%' IDENTIFIED BY 'abcd1234'; mysql> GRANT ALL ON myblog_wordpress.* TO wpadmin@localhost IDENTIFIED BY 'abcd1234'; mysql> quit
This will restore both databases and no further action is necessary.
Testing
Test the setup to ensure everything is working as expected. It should be possible to take down 1 web server and 1 database server and the blog will continue to be online. The blog can still be updated when a web or database server is offline. When the database server comes back online, it should “catch up” with the other thanks to the replication services. Try different combinations of shutting down servers, accessing the blog, and posting content. At worst, there may be an interrupted connection during a failover, but refreshing the browser after a few seconds should then show the site.




