Tuesday, October 16, 2012

Terracotta and Tomcat Clustering - Page 1

In this tutorial we will learn a lot of stuff :)
  1. How to install Terracotta in an Active/Passive HA (High Availability) model.
  2. How to configure Tomcat 6.0 to store/retrieve sessions on Terracotta.
  3. How to install and configure Apache Web Server configure it to relay requests to Tomcat.

Why?

i can do session replication using Tomcat built-in clustering module, so why do i use Terracotta?
well, the Tomcat clustering works just perfect with major four concerns:
  1. Clients' sessions data are part of the Tomcat JVM instance.
  2. There is extra work for Tomcat to make sure that the sessions and its data are replicated among the cluster
  3. not suitable for larger cluster because of using multicasting, imagine the network traffic generated by eight tomcat nodes replicating their sessions.
  4. You can't store an object which is not serializable.
So, moving this responsibility to Terracotta would help eliminating those four concerns.

Our Final architecture 


it is really simple:
  1. Both Tomcats store/retrieve sessions on the active Terracotta server.
  2. Apache web server forwards requests to both Tomcats.
  3. If the active Terracotta fails the passive Terracotta will be the active.

Let's Digg in

First things first! we need:
My five servers built on a single windows 7 box as a POC, you should have no troubles with running the same example on Linux, only minor chages are needed.

Install and Configure Terracotta

open a terminal and change the directory to the place where you downloaded terracotta-3.7.0-installer.jar
java -jar terracotta-3.7.0-installer.jar
you will see a setup wizard, it is straight forward, install Terracotta to the directory of your choice, from now on i will refer to that directory as ${TC_HOME}
now, go to ${TC_HOME} and create a new directory called 'config', this directory will contain our Terracotta configuration file that will set up the Terracotta cluster.
create a new file inside the config directory called tc-config.xml with the following content:
<tc-config xmlns="http://www.terracotta.org/config">
 <servers secure="false" xmlns:tc="http://www.terracotta.org/config" xmlns:con="http://www.terracotta.org/config" xmlns="">
  <server bind="0.0.0.0" host="127.0.0.1" name="node1">
   <data>C:\terracotta\server-data</data>
   <logs>C:\terracotta\server-logs</logs>
   <statistics>C:\terracotta\server-statistics</statistics>
   <dso-port bind="0.0.0.0">9510</dso-port>
   <jmx-port bind="0.0.0.0">9520</jmx-port>
   <l2-group-port bind="0.0.0.0">9530</l2-group-port>
   <data-backup>C:\terracotta\data-backup</data-backup>
   <index>C:\terracotta\server-data\index</index>
   <dso>
    <client-reconnect-window>120</client-reconnect-window>
    <persistence>
     <mode>temporary-swap-only</mode>
    </persistence>
    <garbage-collection>
     <enabled>true</enabled>
     <verbose>false</verbose>
     <interval>3600</interval>
    </garbage-collection>
   </dso>
  </server>
  <server bind="0.0.0.0" host="127.0.0.1" name="node2">
   <data>C:\terracotta\server-data2</data>
   <logs>C:\terracotta\server-logs2</logs>
   <statistics>C:\terracotta\server-statistics2</statistics>
   <dso-port bind="0.0.0.0">9511</dso-port>
   <jmx-port bind="0.0.0.0">9521</jmx-port>
   <l2-group-port bind="0.0.0.0">9531</l2-group-port>
   <data-backup>C:\terracotta\data-backup2</data-backup>
   <index>C:\terracotta\server-data\index2</index>
   <dso>
    <client-reconnect-window>120</client-reconnect-window>
    <persistence>
     <mode>temporary-swap-only</mode>
    </persistence>
    <garbage-collection>
     <enabled>true</enabled>
     <verbose>false</verbose>
     <interval>3600</interval>
    </garbage-collection>
   </dso>
  </server>
  <mirror-groups>
   <mirror-group>
    <members>
     <member>node1</member>
     <member>node2</member>
    </members>
   </mirror-group>
  </mirror-groups>
  <ha>
   <mode>networked-active-passive</mode>
   <networked-active-passive>
    <election-time>5</election-time>
   </networked-active-passive>
  </ha>
  <update-check>
   <enabled>true</enabled>
   <period-days>7</period-days>
  </update-check>
 </servers>
 <system xmlns:tc="http://www.terracotta.org/config" xmlns:con="http://www.terracotta.org/config" xmlns="">
  <configuration-model>production</configuration-model>
 </system>

 <clients xmlns:tc="http://www.terracotta.org/config" xmlns:con="http://www.terracotta.org/config" xmlns="">
  <logs>%(user.home)/terracotta/client-logs</logs>
  <modules>
   <module name="terracotta-toolkit-1.6" group-id="org.terracotta.toolkit"/>
  </modules>
 </clients>
</tc-config>
the important thing to note here is the servers node
  1. for each Terracotta server that will run in the cluster you need to define a server node.
  2. the server tag has three attributes:
    • bind: the default bind address which Terracotta listen to.
    • host: the IP address that will be used to connect to the Terracotta server.
    • name: the name of this node
  3. data: is where this server stores its data (make it unique for each server if you are running the cluster on one box)
  4. logs: is where the server store its logs (make it unique for each server if you are running the cluster on one box)
  5. statistics:  is where the server store its statistics (make it unique for each server if you are running the cluster on one box)
  6. port configurations: JMX, DSO and group ports (make it unique for each server if you are running the cluster on one box)
  7. data-backup: is where the server store its data backups  (make it unique for each server if you are running the cluster on one box)
  8. index: is where the server store its index files  (make it unique for each server if you are running the cluster on one box)
  9. dso: is the Distributed Shared Objects specific options.
we have now defined two servers, we need to define how they would work.
  1. mirror-group: a tag to define Terracotta groups 
    • members: a tag to add a server to a group using its name
  2. ha: is a tag to define the High Availability options of the group
    • mode: networked-active-passive it means that the communications between the servers will relay on networking.
    • election-time: the Terracotta server would wait for that time to decide if it should start as an Active or passive.
let's start out cluster an make sure everything is OK.
  1. open three consoles and navigate to ${TC_HOME}\bin on the three of them
  2. Start node1
    start-tc-server.bat -f ..\config\tc-config.xml -n node1
    
    you should see
    Becoming State[ ACTIVE-COORDINATOR ]
    Terracotta Server instance has started up as ACTIVE node on 0.0.0.0:9510 successfully, and is now ready for work.
    
  3. Start node2
    start-tc-server.bat -f ..\config\tc-config.xml -n node2
    
    you should see
    NodeID[127.0.0.1:9510] joined the cluster
    Moved to State[ PASSIVE-UNINITIALIZED ]
    Moved to State[ PASSIVE-STANDBY ]
    
  4. on the third console start the Terracotta Development Console
    dev-console.bat
    
    connect to either 127.0.0.1:9520 or 127.0.0.1:9521, you should see this screen


as per the screen shot, node1 is active and node2 is passive, play around by taking node1 down and see if node2 becomes the active and then Vice Versa.