<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Dan Cryer - Leeds Web Developer &#187; cluster</title>
	<atom:link href="http://www.dancryer.com/tag/cluster/feed" rel="self" type="application/rss+xml" />
	<link>http://www.dancryer.com</link>
	<description>Dan Cryer - Leeds Web Developer</description>
	<lastBuildDate>Mon, 06 Sep 2010 22:05:42 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
<atom:link rel="hub" href="http://pubsubhubbub.appspot.com"/><atom:link rel="hub" href="http://superfeedr.com/hubbub"/>		<item>
		<title>MySQL Load-Balanced Cluster Guide – Part 3</title>
		<link>http://www.dancryer.com/2010/01/load-balancing-mysql-with-ha-proxy</link>
		<comments>http://www.dancryer.com/2010/01/load-balancing-mysql-with-ha-proxy#comments</comments>
		<pubDate>Thu, 28 Jan 2010 17:14:00 +0000</pubDate>
		<dc:creator>Dan Cryer</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[cluster]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[PHP Conference 2010]]></category>
		<category><![CDATA[replication]]></category>
		<category><![CDATA[scaling]]></category>
		<category><![CDATA[servers]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://www.dancryer.com/?p=434</guid>
		<description><![CDATA[This article is the last in my MySQL Load-Balanced Cluster Guide series, following on from my earlier post today on setting up MySQL Monitoring on the cluster nodes, this article is a guide to setting up the load balancer with HAProxy, using the monitoring scripts we&#8217;ve created to check the node status. HAProxy is a [...]]]></description>
			<content:encoded><![CDATA[<p>This article is the last in my MySQL Load-Balanced Cluster Guide series, following on from my earlier post today on <a href="http://www.dancryer.com/2010/01/mysql-monitoring-with-xinetd">setting up MySQL Monitoring on the cluster nodes</a>, this article is a guide to setting up the load balancer with HAProxy, using the monitoring scripts we&#8217;ve created to check the node status.</p>
<p>HAProxy is a well known, powerful load balancer. Best known for use with HTTP servers, but it can work with any kind of TCP traffic, including MySQL. Upcoming versions will support native MySQL monitoring, so we&#8217;ll be able to retire the custom scripts we created in the previous step, when they&#8217;re available in apt-get.</p>
<p><strong>1. Install HAProxy using the following apt-get command: </strong>apt-get install haproxy</p>
<p><strong>2. Delete the file /etc/haproxy/haproxy.cfg and create a new one with the following contents:</strong></p>
<p><code>global<br />
log 127.0.0.1   local0<br />
maxconn 4096<br />
user haproxy<br />
group haproxy<br />
daemon</code></p>
<p><code> </code></p>
<p><code>defaults<br />
log     global<br />
mode    tcp<br />
option  tcplog<br />
option  dontlognull<br />
retries 3<br />
option redispatch<br />
maxconn 2000<br />
contimeout      4000<br />
clitimeout      50000<br />
srvtimeout      30000<br />
stats enable<br />
stats scope	.</code></p>
<p><code>frontend mysql_cluster<br />
bind {load-balancer-ip}:3306<br />
default_backend	mysql_cluster</code></p>
<p><code>backend mysql_cluster<br />
mode tcp<br />
balance roundrobin<br />
stats enable<br />
option tcpka<br />
option httpchk<br />
server {node-name} {ip-address}:3306 weight 1 check port 9200 inter 5s rise 2 fall 2<br />
server {node-name} {ip-address}:3306 weight 1 check port 9200 inter 5s rise 2 fall 2</p>
<p></code></p>
<p><code>listen stats {load-balancer-ip}:80<br />
mode http<br />
option httpclose<br />
balance roundrobin<br />
stats uri     /<br />
stats realm   Haproxy\ Statistics<br />
stats auth    {username}:{password}<br />
</code></p>
<p>Once you&#8217;ve modified this file with settings appropriate to your environment, you&#8217;ll have a ready to go load balancer for MySQL. It&#8217;ll open port 3306 on the load balancer and forward those connections using round-robin load balancing to your two cluster servers. If either server goes down, it&#8217;ll be removed from the pool and no connections will be sent to it until it comes back up.</p>
<p>Additionally, it&#8217;ll create a statistics interface similar to the following, which you can access by going to your load balancing server&#8217;s address in your browser.</p>
<p><a href="http://www.dancryer.com/wp/wp-content/uploads/2010/01/haproxy.png"><img class="aligncenter size-large wp-image-437" title="HA Proxy" src="http://www.dancryer.com/wp/wp-content/uploads/2010/01/haproxy-1024x566.png" alt="HA Proxy Web Interface" width="450" height="248" /></a></p>
<p>Each cluster node should be listed under the first &#8220;mysql_cluster&#8221; section. They should all appear in green, as they should all be live. If a server is down, it&#8217;ll appear red, as explained in the key at the top of the page. From this interface you can also see how long the load balancer has been up, how long each server has been up, how much downtime each have had, as well as the individual number of downtime incidents. As you can see in the image above, our &#8216;cluster-1&#8242; server has had 21 separate downtime incidents, totalling just over 9 minutes of downtime.</p>
<p>So what do you need to change in your haproxy.cfg file? Here&#8217;s a quick rundown:</p>
<ul>
<li>Firstly, you&#8217;ll need to change the line starting &#8216;bind&#8217; to use your load balancer&#8217;s public IP address.</li>
<li>Secondly, make the same change on the line starting &#8216;listen stats&#8217;. You may also choose to put this service on a different port than port 80.</li>
<li>Next, change the {username} and {password} section of the &#8216;stats auth&#8217; line to ones of your choosing. This provides password protection to your web interface.</li>
<li>Finally, for each of your MySQL cluster nodes, you&#8217;ll need an appropriate &#8216;server&#8217; line in the &#8216;mysql_cluster&#8217; backend group. The things you need to change are {node-name}, to the name of the cluster node you defined earlier (e.g. cluster-1, cluster-2) and {ip-address} to the cluster node&#8217;s internal IP address.</li>
</ul>
<p>You may also wish to change the interval at which the load balancer will poll the MySQL servers, by changing &#8216;inter 5&#8242; to a different number. For more information on HAProxy configuration, their detailed &#8211; if a little unfriendly &#8211; documentation is available <a rel="nofollow" href="http://haproxy.1wt.eu/download/1.3/doc/configuration.txt">here</a>.</p>
<p>The final step to get this running, is to restart haproxy: /etc/init.d/haproxy restart - You should now be able to access both your web interface on port 80 and your brand new MySQL cluster on port 3306!</p>
<p>If you&#8217;ve got any questions about these guides or setting up a similar cluster, please leave a comment below and I&#8217;ll do my best to answer it.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dancryer.com/2010/01/load-balancing-mysql-with-ha-proxy/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>MySQL Load-Balanced Cluster Guide – Part 2</title>
		<link>http://www.dancryer.com/2010/01/mysql-monitoring-with-xinetd</link>
		<comments>http://www.dancryer.com/2010/01/mysql-monitoring-with-xinetd#comments</comments>
		<pubDate>Thu, 28 Jan 2010 16:28:35 +0000</pubDate>
		<dc:creator>Dan Cryer</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[cluster]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[PHP Conference 2010]]></category>
		<category><![CDATA[replication]]></category>
		<category><![CDATA[scaling]]></category>
		<category><![CDATA[servers]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://www.dancryer.com/?p=425</guid>
		<description><![CDATA[Following on from yesterday&#8217;s guide to setting up MySQL master-master replication, the first of today&#8217;s guides is how to set up a script to monitor the status of your MySQL cluster nodes, which we&#8217;ll use in the next guide to set up our proxy. On every one of your MySQL cluster nodes, follow the steps [...]]]></description>
			<content:encoded><![CDATA[<p>Following on from yesterday&#8217;s guide to <a href="/2010/01/mysql-circular-replication">setting up MySQL master-master replication</a>, the first of today&#8217;s guides is how to set up a script to monitor the status of your MySQL cluster nodes, which we&#8217;ll use in the next guide to set up our proxy.</p>
<p>On every one of your MySQL cluster nodes, follow the steps below to get it ready for status reporting:</p>
<p><strong>1. Run the following apt-get command: <em>apt-get install xinetd php5-cli php5-mysql</em></strong> &#8211; We need xinetd to host our status server, and php5 for the status checking script.</p>
<p><strong>2. Put the following code into a new file: /etc/xinetd.d/mysqlchk</strong> &#8211; This creates an xinetd &#8220;server&#8221; on port 9200, using the /opt/mysql-status.php file to generate the response. Our proxy will connect to this server to check the status of the node.</p>
<p><code>#<br />
# /etc/xinetd.d/mysqlchk<br />
#<br />
service mysqlchk<br />
{<br />
flags           = REUSE<br />
socket_type     = stream<br />
protocol        = tcp<br />
port            = 9200<br />
wait            = no<br />
user            = mysql<br />
server          = /opt/mysql-status.php<br />
log_on_failure  += USERID<br />
disable         = no<br />
}</code></p>
<p><strong>3. Add the following line at the bottom of /etc/services</strong> &#8211; This registers your newly created xinetd service with the system to allow it to function.<br />
<code>mysqlchk	9200/tcp	# MySQL Monitoring</code></p>
<p><strong>4. Create the PHP file /opt/mysql-status.php with the code below.</strong><br />
This script tries to connect to your MySQL server, and if it succeeds, checks the &#8216;Seconds_Behind_Master&#8217; value of the slave status to make sure it is not too far behind it&#8217;s master. If either of these checks fail, it will return a 503 error to the client, telling it that the server is down.<br />
<code>#!/usr/bin/php<br />
&lt; ?php<br />
/**<br />
*	MySQL Replication Monitor<br />
*/</code></p>
<p><code>// Connection details:<br />
$_host     = 'localhost';<br />
$_username = '{username}';<br />
$_password = '{password}';<br />
$_timeout  = 60; // Number of seconds behind master this node can fall before being marked as "down".</p>
<p>try<br />
{<br />
$pdo = new PDO('mysql:host='.$_host, $_username, $_password);<br />
$pdo-&gt;setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);</p>
<p>$stmt   = $pdo-&gt;query('SHOW SLAVE STATUS');<br />
$status = $stmt-&gt;fetch(PDO::FETCH_ASSOC);</p>
<p>if($status == false)<br />
{<br />
serverIsDown('Querying slave status failed.');<br />
}</p>
<p>if(intval($status['Seconds_Behind_Master']) &gt; $_timeout)<br />
{<br />
serverIsDown('Slave is behind.');<br />
}<br />
}<br />
catch(Exception $ex)<br />
{<br />
if(!is_null($pdo))<br />
unset($pdo);</p>
<p>serverIsDown('Failed to connect to MySQL.');<br />
}</p>
<p>unset($pdo);</p>
<p>serverIsUp();</p>
<p>function serverIsDown($message)<br />
{<br />
$output = 'Server is currently down. Message:' . $message;<br />
print "HTTP/1.1 503 Service Unavailable\r\n";<br />
print "Date: " . date('r') . "\r\n";<br />
print "Server: MySQL Monitor/1.0\r\n";<br />
print "Connection: close\r\n";<br />
print "Content-Type: text/plain\r\n";<br />
print "Content-Length: " . strlen($output) . "\r\n";<br />
print "\r\n";<br />
print $output;<br />
die;<br />
}</p>
<p></code></p>
<p><code>function serverIsUp()<br />
{<br />
$output = 'Server is up. All is okay.';<br />
print "HTTP/1.1 200 OK\r\n";<br />
print "Date: " . date('r') . "\r\n";<br />
print "Server: MySQL Monitor/1.0\r\n";<br />
print "Connection: close\r\n";<br />
print "Content-Type: text/plain\r\n";<br />
print "Content-Length: " . strlen($output) . "\r\n";<br />
print "\r\n";<br />
print $output;<br />
die;<br />
}</code></p>
<p><strong>5. chown -fv mysql:mysql /opt/mysql-status.php</strong> &#8211; Give ownership of the status checking script to mysql.<br />
<strong>6. chmod -fv +x /opt/mysql-status.php</strong> &#8211; Give execute permissions on the script.<br />
<strong>7. /etc/init.d/xinetd restart</strong> &#8211; Restart xinetd, to make all of the changes we&#8217;ve just made live.</p>
<p>Having completed the steps above, you will now have a script that checks the current status of your MySQL server, responding to connections on port 9200 of your server. In the next article, I&#8217;ll describe how to set up your load balancing server with HAProxy, and utilise the server we&#8217;ve just created to check which nodes are live at any given time.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dancryer.com/2010/01/mysql-monitoring-with-xinetd/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>MySQL Load-Balanced Cluster Guide &#8211; Part 1</title>
		<link>http://www.dancryer.com/2010/01/mysql-circular-replication</link>
		<comments>http://www.dancryer.com/2010/01/mysql-circular-replication#comments</comments>
		<pubDate>Wed, 27 Jan 2010 17:35:21 +0000</pubDate>
		<dc:creator>Dan Cryer</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[cluster]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[PHP Conference 2010]]></category>
		<category><![CDATA[replication]]></category>
		<category><![CDATA[scaling]]></category>
		<category><![CDATA[servers]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://www.dancryer.com/?p=409</guid>
		<description><![CDATA[I&#8217;m currently working on setting up a load-balanced many-master MySQL cluster at work, without using MySQL Cluster as it&#8217;s incompatible with our needs. Finding good guides on how to do this has proven incredibly difficult, so I thought I would document the process here. This first post is going to cover setting up the servers [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m currently working on setting up a load-balanced many-master MySQL cluster at work, without using MySQL Cluster as it&#8217;s incompatible with our needs. Finding good guides on how to do this has proven incredibly difficult, so I thought I would document the process here.</p>
<p>This first post is going to cover setting up the servers themselves and configuring MySQL replication.</p>
<p><strong>1. Set up the following three servers:<br />
</strong></p>
<ul>
<li><strong>Cluster Load Balancer</strong> &#8211; One Public IP, One Internal IP &#8211; Ubuntu Jaunty Basic installation</li>
<li><strong>Cluster MySQL 1</strong> &#8211; One Public IP, One Internal IP &#8211; Ubuntu Jaunty Basic + MySQL Server 5.x</li>
<li><strong>Cluster MySQL 2</strong> &#8211; One Public IP, One Internal IP &#8211; Ubuntu Jaunty Basic + MySQL Server 5.x</li>
</ul>
<p>We&#8217;re using <a rel="nofollow" href="http://manage.aff.biz/z/146/CD2815/">VPS.NET</a>. If you&#8217;re going to do the same, use the &#8216;Ubuntu 8.04 LTS 64-bit Basic Installation&#8217; template for the Load Balancer and &#8216;Ubuntu 8.04 x64 MySQL&#8217; for the MySQL nodes. You&#8217;ll then need to do the following to upgrade to Jaunty:</p>
<ul>
<li>Edit the file &#8216;<em>/etc/update-manager/release-upgrades</em>&#8216; and change the line &#8216;<em>Prompt=lts</em>&#8216; to &#8216;<em>Prompt=normal</em>&#8216;.</li>
<li>Run the command &#8216;<em>do-release-upgrade</em>&#8216;. Let it go through the entire process of installing Intrepid, then reboot.</li>
<li>Repeat the step above again to install of Jaunty.</li>
</ul>
<p><strong>2. On the two MySQL servers, edit /etc/mysql/my.cnf and comment out the line &#8216;<em>bind-address 127.0.0.1</em>&#8216; &#8211; the servers need to allow remote TCP/IP connections.<br />
</strong><br />
<strong>3. On each server, add the following to the /etc/mysql/my.cnf file:<br />
</strong><br />
<code>server-id = 1                         # Increment this number by one for each server, so 1 for cluster-1, 2 for cluster-2<br />
auto_increment_increment = 2          # Set to the number of nodes you have (or are likely to have)<br />
auto_increment_offset = 1             # Set to the same as the server-id<br />
replicate-same-server-id = 0          # To ensure the slave thread doesn't try to write updates that this node has produced.<br />
log-bin                               # Turn on binary logging (neccessary for replication)<br />
log-slave-updates                     # Neccessary for chain or circular replication<br />
relay-log                             # As above<br />
relay-log-index                       # As above</code></p>
<p><strong>Note:</strong> On our servers, we&#8217;ve used an <em>auto_increment_increment </em>of 4, to allow us to add two more nodes to our cluster at a later date, without hitting auto-increment problems.</p>
<p><strong>4. Restart MySQL on both servers.<br />
</strong><br />
<strong>5. On Cluster 1, log into the MySQL Console and run the following queries:<br />
</strong><br />
<code>STOP SLAVE;<br />
CHANGE master TO master_host="cluster-2.yourdomain.com", master_user="{username}", master_password="{password}", master_log_file="mysqld-bin.000001", master_log_pos=98;<br />
START SLAVE;</code></p>
<p><strong>Note:</strong> To verify the master_log_pos value, execute the query: &#8220;SHOW MASTER STATUS;&#8221; and check the Position column. Also, you may wish to use your internal IP addresses for the master_host option.</p>
<p><strong>6. On Cluster 2, log into the MySQL Console and run the following queries:<br />
</strong><br />
<code>STOP SLAVE;<br />
CHANGE master TO master_host="cluster-1.yourdomain.com", master_user="{username}", master_password="{password}", master_log_file="mysqld-bin.000001", master_log_pos=98;<br />
START SLAVE;</code></p>
<p><strong>Note:</strong> If on either server you get an error message at this point, verify that:</p>
<ul>
<li>a) the master_log_file name in the query above matches the ones your servers are generating</li>
<li>b) your username and password for the other server are correct</li>
<li>c) that your servers can communicate with each other using the host names you specified.</li>
<li>Additionally, you may wish to remove AppArmor, as that can interfere with MySQL replication and cause all kinds of miscellaneous problems. To do so, run &#8216;<em>apt-get remove apparmor</em>&#8216; followed by &#8216;<em>apt-get purge apparmor</em>&#8216;.</li>
</ul>
<p>You should now have master to master replication set up and running across your two MySQL servers. To test, create a database on cluster-1, then create a table within that database and insert some data into it. Next, log on to cluster-2 and you should be able to see that newly created table, complete with data.</p>
<p>If you want to ensure that it works both ways, insert some data on cluster-2 and you should see it on cluster-1. You will also want to test that your auto-increment settings are working correctly.</p>
<p>If you&#8217;ve got any questions about this article, or have any problems setting up the replication, please leave a comment below and I&#8217;ll do my best to help. The next article in this guide will cover setting up a proxy on the load balancer and hopefully, implementing failover.</p>
<ul>
<li>Next Step: <a href="http://www.dancryer.com/2010/01/mysql-monitoring-with-xinetd">Setting up MySQL Monitoring on the cluster nodes</a>.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.dancryer.com/2010/01/mysql-circular-replication/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
