Welcome!

Java Authors: Michael Sheehan, Maureen O'Gara, Jonny Defh, Suresh Krishna Madhuvarsu, RealWire News Distribution

Related Topics: Java

Java: Article

Top Cluster Considerations

Design your application to work in a cluster and be sure to test it carefully to avoid cluster gotchas

One of the greatest strengths of Java Platform 2, Enterprise Edition (J2EE) application servers is the ability to scale solutions to meet increased performance and availability demands. The inherent clustering and failover capabilities built into products such as the IBM WebSphere Application Server Network Deployment Edition take care of most of the dirty work; however, there are important application considerations that can't be overlooked. If an application isn't designed for cluster awareness, functional or performance issues can surface when deploying your application to a cluster.

Expecting your application to run only in a single server Java Virtual Machine (JVM) is self-limiting, and with a little more upfront work, you can ensure cluster readiness, and be more confident that your application will scale when the need arises. This paper discusses design and implementation considerations for cluster awareness. While many of these best practices are the tried-and-true best practices for any J2EE application, you'll see how essential they become when you move to a cluster. In addition, there are more subtle considerations - often realized the hard way - that cause an application to fail in a cluster.

When an application is moved into a clustered environment, multiple versions of the application are now executing, with some type of workload management distributing and balancing the work. The application may be running on different JVMs on the same physical server or across different servers. Data, resource sharing, and timing have to be carefully designed. Subsequent requests to the same application may end up executing on different servers.

This article discusses the following areas that require special consideration when designing your application for cluster awareness.

  1. Follow user session state best practices
  2. Design configuration data access to avoid local files and in-memory updates
  3. Design application and database for data concurrency and idempotence
  4. Maximize local object accesses within tiers
  5. Leverage messaging to enable background and/or batch processing
  6. Design and partition caches
  7. Configure shared resources appropriately
  8. Use application server provided workload management and replication
  9. TEST, TEST, TEST
Follow User Session State Best Practices
HTTP is a stateless protocol requiring the user state to be stored on the server side using HTTP sessions and other J2EE components such as Stateful Session EJBs. When your application is moved into a clustered environment, different requests from the same user may go to different application servers. This means that all application servers need to have access to these types of session data to maintain availability across user requests. Application servers like WebSphere provide a sophisticated infrastructure to support sharing HTTP session data across servers. This includes performance optimizations in the workload routing and caching so that under normal operating situations, the HTTP session object is actually resident on the server that the request is sent to, eliminating the need for the runtime to repopulate the session object from the database or shared memory.

Though your application server may provide algorithms that minimize the need for a session to be repopulated from the database, any HTTP session replication and failover capability requires adherence to several best practices to perform effectively:

  1. A session should be small and avoid complex object graphs
  2. Session objects must be serializable
  3. References to unnecessary objects that are dependent on the current runtime environment should be avoided
  4. Session wrappers must call the set attribute appropriately
Some techniques that can be helpful in keeping your session small:
  • Make sure it's state data, not history
  • Make sure it's user state data, not application data that's not user-specific
  • Keep a key to the data
  • Re-create the data on failover rather than storing it in the database
An example of a technique using transient variables to enable WebSphere to serialize objects selectively and re-create data is discussed by Brown and Botzum in "Improving HttpSession Performance with Smart Serialization."1

Design Configuration Data to Avoid Local Files and In-Memory Updates
Another type of data that's common is application configuration data or properties. Simple single-server solutions often read configuration data from a local file and store it in a Java object. This is commonly a set of static fields or a singleton. The configuration data is then accessed and updated by the application and may be persisted back to the local file.

These techniques don't work in a cluster. Remember, the configuration data needs to be accessible by the application running on different servers, and any changes have to be visible to all running copies of the application.

Common techniques that work in a cluster include using a database or LDAP server to keep the configuration data. If your design uses a file system, you'll have to set up file replication techniques using ftp or a shared file system. Remember, if you use any of these techniques, you'll need to document the mechanism your application requires since these are not capabilities supplied by the application server runtime.

Design Application and Database for Data Concurrency and Idempotence
Once an application is clustered, there are now multiple copies of the application working against the same shared runtime data. This will usually increase the amount of concurrent access to data. It can also mean that the same user can login and make requests simultaneously from multiple browsers. This increased data concurrency can lead to invalid requests and potential data corruption. When you design your application for database access, appropriate levels of locking within transactions are required to prevent data corruption while also minimizing the lock levels to prevent deadlocks. Concurrent access deadlock problems may not show up until you move to a cluster.

For example, Message Driven Beans (MDBs) that access data in a random order with exclusive locks will work in a single application server environment, but will often be deadlocked when moved to a cluster. MDBs need to have fixed order for any data or tables that are locked exclusively. This can be done by sorting the data before accessing. Another alternative when record processing order doesn't matter is to partition the queues, allowing multiple consumers of the requests.

Another challenge for a clustered application is ID generation for database keys. If high performance is needed, one common design pattern is to add a table to the database that's used to allocate pools of keys for each cluster.


More Stories By Ruth Willenborg

Ruth Willenborg is a senior technical staff member in IBM's WebSphere Technology Institute working on virtualization. Prior to this assignment, Ruth was manager of the WebSphere performance team responsible for WebSphere Application Server performance analysis, performance benchmarking, and performance tool development. Ruth has over 20 years of experience in software development at IBM. She is co-author of Performance Analysis for Java Web Sites (Addison-Wesley, 2002).

More Stories By J. Stan Cox

J. Stan Cox is a senior engineer with IBM's WebSphere Application Server performance group. In this role, he has worked to improve WebSphere application performance for J2EE, Web 2.0, Web services, XML and more. His current focus is WebSphere multicore and parallel foundation performance. Stan holds a B.S.C.S from Appalachian State University (1990) and an MS in computer science from Clemson University (1992).

Comments (1) View Comments

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.


Most Recent Comments
gilinachum 01/22/09 02:36:00 AM EST

My two bits are: Making sure you keep some degree of affinity in the system to combat the inherent cluster complexity.
For example: http session affinity, where a specific user session is always handled by the same specific server instance (as long as no fail-over occurred).

Or, server affinity, imagine a cluster with two presentation web containers (servers: Web1, Web2) talking to a and two business logic servers (Ejb1, Ejb2) cluster, server affinity might mean to configure the Web1 server to hit only on the the Ejb1 server. and have the server Web2 hitting only on the Ejb2 server. although you sacrifice some degree of load balancing and performance (if Web1 is out the game so is Ejb1), the overall layout still highly available (there are two non dependent chains), simpler to grasp by the system operators, and easier to troubleshooting in case of problems.