CloudTran Home

 
  
 
Contents  >   4.  Concepts
 


4.1 Application Architecture

There are four broad levels in CloudTran's Application architecture. These are outlined in later sections in this page and then described in detail in later pages.

The application architecture is a logical architecture. In contrast, the physical architecture is specified by the deployment: different deployments can have different number of machines for tasks, different numbers of backups, different disks and so on. Deployment aspects are described later.

 4.1.1  The Client Application
 4.1.2  The Grid
 4.1.3  Transaction Management
 4.1.4  Persistent Stores and the Plug-in Architecture

4.1.1  The Client Application
The client application can be created in two ways:
  • Production applications are usually called by an external event - in other words, from a program in an external framework. For example, a user visits a web page and the framework calls a servlet. The external program can call into CloudTran simply by including jars on its classpath of the application. These consist of standard CloudTran and GigaSpaces jars, plus a customized 'CloudTran Framework' jar, containing code generated from the model.

    Just as in JEE, there are two styles of architecture. First, the user can use the CloudTran ORM directly, with the main business logic in the external application. This is equivalent to a Java servlet interacting directly with the database.

    The other approach is to call services in the grid, which execute business logic. If the application has an object in hand, say a Customer record, this is normally more efficient than repeated calls from the external application: the grid-based service is faster if it can access related objects in the same VM.

  • Applications can be modelled, and be resident in the grid. This is useful for clean-up or refresh activities in a production application.

    It can also be used for test applications. The advantage of modelling such applications is that they can be automatically started once the grid and the transaction buffer (and all backups) have started and initialised, rather than having to be started manually. This is useful for functional and load testers.

Client applications use the grid 'underneath' it in two ways:
  • For Processing The grid provides processing capabilities for services. Conceptually these are identical to services in SOA or Web Services, or EJB Stateless Session beans.

    Unlike 'homogenous' services, like web services, which are equal in terms of performance for a given request, services in CloudTran can use content-based routing to direct services to the node that has the key data to service the request. This is important because, for every record that must be accessed across the grid, there is a cost and time penalty; going to the node with the key data is most likely to reduce them.

    Of course, you can also use calls that reach random nodes. This is what to do if the nodes supporting the service are likely to be equally effective at processing the operation - in stateless services, for example.

  • For Persistent Data The grid also provides "persistent in-memory data". In other words, this stored in the grid node's memory, but also persisted - as we will explain later.

    The client accesses this via an ORM that gives a Java object graph view of the information. Of course, the grid cannot store information in this form - in general there is too much information to fit in one node. So CloudTran provides an facility we call an 'ORM' that maps between the object graph view and the data in the grid. This has to collect parts of the object graph from different nodes, in general chasing down relations across different nodes. When storing an object graph, it has to send the information to the correct nodes.

    'ORM' is a misnomer - it's not really an Object Relational Mapper, more an Object Data-Grid Mapper. However, we use the term because it does the same sort of job for the user view as ORMs like Hibernate or JPA.


4.1.2  The Grid
The Grid tier has a number of nodes running services and storing data. Whereas service and data tiers are traditionally kept in separate tiers, in CloudTran they can also be placed in the same tier. Using content-based routing, discussed later, it is possible for services to run faster in a single tier by being colocated (i.e. in the same JVM) with their most used data.

The main concept in the grid is the "Processing Unit" or PU, which is borrowed from GigaSpaces. The PU defines the data and services provided by its deployed nodes. The data types managed by CloudTran are called entities. A type of service and entity instances must reside within a given PU.
       
    PU 
     |
     | 1      *
     |----------> Entity types
     |
     | 1      *             1      *
     |----------> Services ----------> Operations
                                      (Business methods)

(GigaSpaces also has the concept of a 'space', which is the subsystem that holds data and calls into services. In CloudTran, you don't need to model or concern yourself with the space: CloudTran creates a space to hold data for each PU automatically.)

At deployment time, a PU is spread across a number of physical nodes. Normally, a node is a JVM running on a particular machine, but it often makes sense to have one machine running multiple nodes - for example, in testing.

In CloudTran, the grid is the system of record - meaning, this is the definitive version of the information managed by the application. In most Java applications, the system of record is the database, but in CloudTran, the database or other persistent storage systems are secondary: the live information, and the best record of truth, is the grid. CloudTran also coordinates the flow of information to databases and other data stores, but they are not as up-to-date as the grid.

To help you meet internal SLAs and customer expectations, CloudTran provides self-healing and non-stop features so the overall application has very high availability and can tolerate single-node failures.

By "self-healing", we mean that hot standbys can (and should!) be used on all nodes. This operates both on the grid nodes and on the coordinator described below.

"Non-stop" means that CloudTran allows the computers in the Cloud to continue operating as normal even when the persistent store is down. In a way this is obvious: the system of record is in the grid, therefore as long as that keeps up with customer transactions, writing to the secondary persistent storage can be delayed until the persistent store comes back up without any impact (if it's down, the Cloud can't write to it anyway). CloudTran makes this possible because the transaction coordinator buffers transactions when a persistent store goes down.

In the grid, data is stored in Java objects that are quite similar to the objects in the client view. However, relations - that can be expressed as object references in the client view - cannot be stored that way in the grid because the related objects may reside on another node. Therefore, relations are represented as foreign key values. So for example, the Java phrase order.getCustomer() executed on an object in the grid, instead of returning a Customer object, returns a foreign key value; the ORM uses this to locate and retrieve the related object.


4.1.3  Transaction Management
CloudTran implements a transaction management coordinator specially designed for cloud/grid applications.

A new approach to transaction management is needed because there are problems with other approaches in cloud environments:

  • 'Native transactions' are not sufficient.

    Spring refers to one-computer, one-database transactions as 'native transactions'. Native transactions depend on the connection from a client to the database: this is how the transaction is implemented.

    In general, multiple computers are involved in cloud/grid applications use multiple computers. So in general native transactions are not sufficient: two computers can't work over a single internet connection because TCP/IP doesn't allow it, so there must be an additional mechanism. More complex applications will also use multiple databases or data stores, which native transactions do not address.

  • Distributed transactions are not viable.

    Distributed transactions have a reputation of being slow and unreliable in scalable environments. There are many reports describing this problem, e.g. Pat Helland's "Life beyond Distributed Transactions: an Apostate's Opinion".

  • Synchronization between grid and databases Pure in-memory platforms focus on providing transactions between the in-memory nodes and are less concerned about consistency at the database. Databases provide transactionality at the database and are not concerned with transactions in a grid.

    The reality for a programmer is that the data in nodes and on the database are both important and must be kept in synch.

CloudTran provides a scalable, fast transaction facility. On today's commodity hardware, it processes thousands of update transactions per second.

The transaction is "scalable" in that any number of nodes, datastores, and objects can be involved in the transaction.

The 'transaction coordinator' is resident in a PU - the CoordinatorPU - which also has centralised services like key generation and start-of-day initialisation. The code and Javadocs also refer to the 'Transaction Buffer' (also shortened to 'TxB').

In Version 1 of CloudTran the Coordinator is a single machine with one or possible more backups. Future versions will offer a partitioned Coordinator, which will allow multiple nodes to coordinate transactions. It commits updates transactionally into the in-memory nodes first, then sends transactions to the datastores, which will be consistent eventually (the grid is the system of record, remember).

Transaction Logging

In addition to logging to backed-up memory, CloudTran offers transaction logging to "file". In other words, a copy of the transaction is written to a file on a disk or flash memory.

There are three transaction logging options: to log before committing to the user; to log after committing to the user; or not to log at all. Having no transaction log is not recommended because when the coordinator and all its backups (hot standy's) fail, all unpersisted transactions will be logged. Furthermore, if there are multiple persistent stores, some transactions will probably be half-committed. Even though this should never happen, the effort and inconvenience of untangling possibly thousands of transactions when it does may delay restarting of the application for a long time.

The decision of when to log depends on the value of the transactions compared to the need for high performance. The safe option is to log before commit, which is the approach that databases use. CloudTran then guarantees that all transactions which are committed can be restored from the log if the coordinator has a complete failure. The 'log after commit' option is riskier because the coordinator can crash after it commits to the user and that commitment may be lost. However, the write to the transaction log takes around 10-20ms for a locally-attached disk; this delay is avoided with 'log after commit'.


4.1.4  Persistent Stores and the Plug-in Architecture
We have already discussed two formats of information: the client view (in entity-relational form transaction aggregating and reordering they are useful for backup/restore of the data in the IMDG, should power ever go off completely, and for integration with business intelligence and other data analysis tools.

The scalability demands of data in the cloud is driving the creation of a new generation of non-database data stores, such as SimpleDB, BigTable/Hadoop, CouchDB and Cassandra. To support these stores, CloudTran supports a plug-in architecture so that the IMDG can be loaded from/stored to any type of store. This layer is beneath the transaction manager described above and therefore information from these stores can be incorporated into CloudTran transactions.


Copyright (c) 2001-2011 CloudTran Inc.