<html>
<!--AD_DND-->
<head>
<title>Server Clustering</title>
</head>

<body bgcolor=white>
<h2>Server Clustering</h2>

part of the <a href="">ArsDigita Community System</a> by by <a href="jsalz@mit.edu">Jon Salz</a>

<hr>

<ul>
<li>Tcl: /tcl/ad-server-cluster.tcl
</ul>

<h2>The Problem</h2>

Many heavily-hit sites sit behind load balancers, which means that requests to a particular
site can be handled by one of several machine conspiring to appear as a single server.
For instance, requests to <tt>www.foobar.com</tt> might be routed to either <tt>www1.foobar.com</tt>,
<tt>www2.foobar.com</tt>, or <tt>www3.foobar.com</tt>,
three physically separate servers which share an Oracle tablespace (and
hence all the data in ACS).

<p>Many database queries are memoized in individual servers' local memory
(using the <tt><a href="/doc/proc-one.tcl?proc_name=util_memoize">util_memoize</a></tt> procedures) to minimize fetches from the database.
When a server updates an item in the database, the
old item needs to be removed from the server's local cache (using <tt><a href="/doc/proc-one.tcl?proc_name=util_memoize_flush">util_memoize_flush</a></tt>)
to force a database query the next time this item is accessed. But what happens when:

<ul>
  <li><tt>www1.foobar.com</tt> does <tt><a href="/doc/proc-one.tcl?proc_name=util_memoize">util_memoize</a> "get_greeble_info 43"</tt> (incurring an actual
      database lookup, <tt>SELECT * FROM greeble WHERE greeble_id = 43</tt>, and caching the result)
  <li><tt>www2.foobar.com</tt> does <tt><a href="/doc/proc-one.tcl?proc_name=util_memoize">util_memoize</a> "get_greeble_info 43"</tt> (incurring a
      database lookup and caching the result)
  <li><tt>www1.foobar.com</tt> <tt>UPDATE</tt>s the info for greeble #43 and does
      <tt><a href="/doc/proc-one.tcl?proc_name=util_memoize_flush">util_memoize_flush</a> "get_greeble_info 43"</tt>
  <li><tt>www2.foobar.com</tt> does <tt><a href="/doc/proc-one.tcl?proc_name=util_memoize">util_memoize</a> "get_greeble_info 43"</tt> (returned a cached
      value). The old info for greeble #43 hasn't been flushed from its local cache, so the result
      is outdated!
</ul>

In general, if any of several servers can
update an item, the old version of the item can remain in other servers' local caches.
<a href="http://www.mshonline.com/how/homer/doh.wav">Doh!</a>

<h2>The Solution</h2>

We introduce the concept of a <i>server cluster</i>, a group of look-alike servers sharing an Oracle tablespace.
To set up a cluster, add the following to the ACS <tt>parameters/yourservername.ini</tt> file on each
of the servers in the cluster:

<blockquote><pre>; address information for a cluster of load-balanced servers (to enable
; distributed util_memoize_flushing, for instance). One entry per
; server; this machine's IP may be included as well
[ns/server/click/acs/server-cluster]
; 192.168.16.1 is www1.foobar.com
ClusterMachine=192.168.16.1
; 192.168.16.2 is www2.foobar.com
ClusterMachine=192.168.16.2
; 192.168.16.3 is www3.foobar.com
ClusterMachine=192.168.16.3</pre></blockquote>

Now when a server (say, <tt>www1.foobar.com</tt>) invokes
<tt><a href="/doc/proc-one.tcl?proc_name=util_memoize_flush">util_memoize_flush</a></tt> or <tt><a href="/doc/proc-one.tcl?proc_name=util_memoize_seed">util_memoize_seed</a></tt>, those routines use
<tt><a href="/doc/proc-one.tcl?proc_name=server_cluster_httpget_from_peers">server_cluster_httpget_from_peers</a></tt>
to issue an HTTP GET request to all machines in the cluster (omitting the local server):

<ul>
<li><tt>GET http://www2.foobar.com/SYSTEM/flush-memoized-statement.tcl?statement=<i>tcl-statement</i></tt>
<li><tt>GET http://www3.foobar.com/SYSTEM/flush-memoized-statement.tcl?statement=<i>tcl-statement</i></tt>
</ul>

causing the other machines (<tt>www2.foobar.com</tt> and <tt>www3.foobar.com</tt>) to flush the Tcl statement
from their local caches. This is transparent and works with all existing code.

<p>So don't think about it - just set up the <tt>server-cluster</tt> block in your <tt>yourservername.ini</tt> file,
and <tt>util_memoize</tt> and friends will be <a href="http://www.mshonline.com/how/homer/woohoo.wav">happy</a>.

<hr>

<a href="mailto:jsalz@mit.edu"><address>jsalz@mit.edu</address></a>

</body>
</html>