HIBERNATE JBoss.org
 |  Register  | 
     
News 
About 
   Feature List 
   Road Map 
Documentation 
   Related Projects 
   External Documentation 
Download 
Forum & Mailinglists 
Support & Training 
JIRA Issue Tracking
Wiki Community Area


Hibernate Public Training Courses


Get Hibernate in Action eBook!


JavaWorld 2003 Finalist


Jolt Award 2004 Winner
      
Documentation > Community Area > Using GigaSpaces Grid based Distributed Caching

Using GigaSpaces Grid based Distributed Caching

Overview

GigaSpaces Grid based distributed caching is a major component within the GigaSpaces Data Grid architecture.

It enables applications to reduce the access time to information that resides in the database by bringing the information to the local application memory.

The information is loaded to the cache from the database in an on-demand basis. The cache manages the local memory utilization and the consistency of that information.

Technical description

For more detailed information about the GigaSpaces caching architecture please refer to the following section in the GigaSpaces documentation.

http://www.gigaspaces.com/docs/doc/what_is_gigaspaces_distributed_cache_.htm

GigaSpaces unique features

Grid based architecture enables unlimited cache size through memory virtualization

The GigaSpaces distributed cache is different from most other cache implementation in the sense that a cache size is not limited to the capacity of the physical memory.

Instead it virtualizes a set of physical memory instances as if they where the same physical memory.

Optimized for real time analytic scenarios

Real time analytics application such as fraud detection requires the ability to process vast amount of data in real time.

Processing data in real time involves two aspects:

1. The ability to access the data in real-time.

2. The ability to process the data in real-time.

Most of the caching technique focus on solving the data access item and leave the processing burden to the application developer.

GigaSpaces leverages its Grid based architecture to provide a solution for these two aspects (data access and data processing) by combining a distributed caching with parallel processing engine - See below an example for this technique usage.

With this approach real-time analytics application gain better performance, scalability and simplicity and consistency across all the elements of the application.

In addition to that it saves the cost, complexity and support effort which normally involved when combining two technologies from two different products/vendors together.

Shared cache architecture reduces the hitrate on the underlying database

In the GigaSpaces approach all caches share the same instance of a master cache.

With this approach data element that was loaded from one cache can be accessed by other caches that attempt to load that same instance.

The hitrate on the database can be reduced dramatically with this approach and the response time to the application remains consistent.

Optimized for smart client (rich clients) application

Smart client applications are applications that needs to be able to run business logic on the client side.

These applications very often need to be able to maintain a local representation of the application data that would be used both for reducing the network overhead and to enable work in an offline mode.

GigaSpaces Hibernate Cache

GigaSpaces Hibernate Cache is designed to combine the value of both the GigaSpaces Grid based Cache and Hibernate O/R mapping.

Hibernate users would be able to gain better performance and scalability without changing single line of code.

GigaSpaces users would be able to gain the rich db integration and O/R mapping functionality provided by hibernate.

Main features list

  1. Allows the applications to use Hibernate Object SQL API to access the database.
  2. GigaSpaces provide full database caching using Distributed caching mode that provide local embedded cache (limited with its size - evicts old data automatically) together with master cache that can be clustered across different machines to provide unlimited cache size. The master cache synchronizes/updates the local cache when needed.
  3. Updates are propagated to other clients holds local cache using optimistic locking protocol to ensure data coherency.
  4. GigaSpaces master cache can be configured to provide both scalability and availability using GigaSpaces cluster HAU (High-Availability-Unit) option.
  5. GigaSpaces database caching option is relevant for applications require accessing database with complex SQL queries using Object interface that could benefit from caching the results in object format to save the database access and the SQL row data into object conversion.

Demo

The GigaSpaces Platform examples set includes a simple application using the GigaSpaces Hibernate Cache plug-in.

To run this demo - Open the <GigaSpaces Root>\examples\databaseCache directory and follow the instructions at the readme file.

Make sure you have Ant Installed before running this example.

Client cache side only mode is also supported. 
This option provides the maximum performance (about X 10 faster than the distributed cache mode!) but do not sync the cache with global master cache and do not provide unlimited cache size since the cache size is bounded to the application process available memory.

To move into this mode you would need to modify the build.xml to have the following value for the spaceurl attribute:

java://localhost/<machineName>/JavaSpaces?useLocalCache=false

When running in this mode you do not need GigaSpaces server to run.

Usage Example

See the usage example architecture below:

http://www.gigaspaces.com/images/gsarc.jpg

The architecture diagram demonstrates the usage of the GigaSpaces Grid and its database caching for parallel database query.

This architecture is based on the classic Master/Worker pattern:

  1. J2EE session bean submits tasks into GigaSpaces.
  2. The tasks contain the required information for workers to process and generate the relevant query.
  3. The task submission done via JavaSpaces Write API.
  4. In case there are many tasks to submit writeMultiple API should be considered to speed up the task submission process.
  5. The tasks are picked up by workers using the JavaSpaces Take API.
  6. The workers can run in GigaSpaces container or J2EE container (as session beans). The number of workers can be static or dynamic where new works can be added on-the-fly based on system load.
  7. The workers can run in one or more machines to provide unlimited scalability level.
  8. The workers generate the query and submit it into the database via Object to relational Hibernate API.
  9. The Object to relational API using GigaSpaces distributed cache to speed up the query processing and provide the query result from the local/remote cache in case it has been already loaded.
  10. Cached data can be retrieved from the local cache embedded with the worker or from the master remote cache. The local cache can got limited memory size and evicts data automatically. The worker read cached data first from the local cache and if not found get it from the master cache. This is done automatically by GigaSpaces.
  11. Each worker sends the query result back into the J2EE session bean via JavaSpaces Write method.
  12. The J2EE Session bean that submits the tasks using now Take API to get all results. When all of them arrived sends total result back to the client.
  13. The space used for the tasks/results submission and for remote master cache is fully clustered to provide both scalability and availability.

Implementation

The Hibernate Cache Interface implemented using GigaSpaces Map Interface. See below GigaHibernateCache and GigaSpacesCacheProvider classes:

package net.sf.hibernate.gigacache;
import java.util.Properties;
import com.j_spaces.core.IJSpace;
import com.j_spaces.core.client.SpaceFinder;
import com.j_spaces.dcache.CacheException;
import com.j_spaces.dcache.DCacheMapImpl;
import com.j_spaces.dcache.IDCacheMap;
import net.sf.hibernate.cache.Cache;
import net.sf.hibernate.cache.CacheProvider;
import net.sf.hibernate.cache.Timestamper;
import com.j_spaces.core.client.SpaceURL;

public class GigaSpacesCacheProvider implements CacheProvider {
    private IJSpace space = null;
    IDCacheMap cache;
    public Cache buildCache(String regionName, Properties properties)
            throws CacheException {
        boolean isUsinLocalCache  = true;
        try {
            String url = System.getProperty("spaceurl").toString();
            System.out.println("Getting Space proxy:" + url);
            // defualt mode is local cache
            if (url.toLowerCase().indexOf(SpaceURL.USE_LOCAL_CACHE.toLowerCase() + "=false") >0)
            {
                space = (IJSpace) SpaceFinder.find(url);
                isUsinLocalCache  = false;
                System.out.println("No Local Cache Usage!");
            }
            else
            {
                space = (IJSpace) SpaceFinder.find(url   +"?" + SpaceURL.USE_LOCAL_CACHE + "=true");
                System.out.println("Local Cache Used!");
            }
            cache = new DCacheMapImpl(space);
            System.out.println("Getting Space proxy - OK");
        } catch (Exception e) {
            System.out.println("Getting Space proxy - ERROR!");
            e.printStackTrace();
        }
        return new GigaHibernateCache (cache,space,isUsinLocalCache  );
    }
    public long nextTimestamp() {
        return Timestamper.next();
    }
}
package net.sf.hibernate.gigacache;
import java.rmi.RemoteException;
import net.sf.hibernate.cache.Cache;
import net.sf.hibernate.cache.CacheException;
import net.sf.hibernate.cache.Timestamper;

import com.j_spaces.core.IJSpace;
import com.j_spaces.dcache.IDCacheMap;
import com.j_spaces.dcache.DCacheSpaceImpl;

public class GigaHibernateCache implements Cache {
    private IDCacheMap cache;
    private IJSpace ijspace;
    private boolean isUsinLocalCache  ;
    
    static boolean debug = Boolean.valueOf(
            (System.getProperty("com.gs.dbcache.debug", "false")))
            .booleanValue();

    public GigaHibernateCache(IDCacheMap cache , IJSpace ijspace,boolean isUsinLocalCache  ) {
        this.cache = cache;
        this.ijspace = ijspace;
        this.isUsinLocalCache   = isUsinLocalCache ;
    }
    public Object get(Object key) throws CacheException {
        Object ret = cache.get(key);
        if (debug)
            say("get from Cache = key:" + key + " value:" + ret);
        return ret;
    }
    public void put(Object key, Object value) throws CacheException {
        if (debug) {
            say("put to Cache - Key :" + key.toString() + " value:"
                    + value.toString());
        }
        cache.put(key, value);
    }
    public void remove(Object key) throws CacheException {
        if (debug)
            say("remove from Cache:" + key);
        cache.remove(key);
    }
    public void clear() throws CacheException {
        if (isUsinLocalCache )
        {
        DCacheSpaceImpl dcacheSpace = (DCacheSpaceImpl) ijspace;
        try {
            dcacheSpace.getLocalSpace().clean();
        } catch (RemoteException e) {
            new CacheException(e);
        }
        }
        else
            cache.clear();
    }
    public void destroy() throws CacheException {
        if (isUsinLocalCache )
        {
        DCacheSpaceImpl dcacheSpace = (DCacheSpaceImpl ) ijspace;
        try {
            dcacheSpace.getLocalSpace().clean();
            dcacheSpace.getRemoteSpace().clean();
        } catch (RemoteException e) {
            new CacheException(e);
        }
        }
        else
            cache.clear();
    }
    public long nextTimestamp() {
        return Timestamper.next();
    }
    public void lock(Object key) throws CacheException {
    }
    public void unlock(Object key) throws CacheException {
    }
    public int getTimeout() {
        return 1000;
    }
    private void say(String mes) {
        System.out.println("GigaDBCache:" + mes);
    }
}

More information about GigaSpaces can be found at:

http://www.gigaspaces.com

      

coWiki