views:

1829

answers:

9

Hi everyone.

I am searching for a java framework that would allow me to share a cache between multiple JVMs.

What I would need is something like Hazelcast but without the "distributed" part. I want to be able to add an item in the cache and have it automatically synced to the other "group member" cache. If possible, I'd like the cache to be sync'd via a reliable multicast (or something similar).

I've looked at Shoal but sadly the "Distributed State Cache" seems like an insufficient implementation for my needs.

I've looked at JBoss Cache but it seems a little overkill for what I need to do.

I've looked at JGroups, which seems to be the most promising tool for what I need to do. Does anyone have experiences with JGroups ? Preferably if it was used as a shared cache ?

Any other suggestions ?

Thanks !

EDIT : We're starting tests to help us decide between Hazelcast and Infinispan, I'll accept an answer soon.

EDIT : Due to a sudden requirements changes, we don't need a distributed map anymore. We'll be using JGroups for a low level signaling framework. Thanks everyone for you help.

+1  A: 

Memcached has several Java Clients.

John Meagher
I am not working on a web server. I suppose that the problem here is the term "cache" which is not really what I'm looking for. I need a shared data structure ;)
GuiSim
Memcached doesn't have anything to do with web servers. It is the type of thing you are looking for.
John Meagher
+4  A: 

Have you considered Terracotta? Might be overkill: http://www.terracotta.org/web/display/orgsite/Data+Caching

There was a JSR in the area of caching a while ago, do any of the following fit the bill: http://java-source.net/open-source/cache-solutions/jcache ?

I personally used FKache a few years ago and it worked well, but I didn't use it in distributed mode.

Is it important that it's a distributed cache with local copies of data? There's also the JavaSpaces stuff if it's shared memory you need...

Dan Gravell
I considered using Terracotta and plan to use it as a last resort as it is, as you stated, overkill.
GuiSim
Not sure I understand the sentiment here. I'm biased of course - since I work for Terracotta - but using Terracotta to do simple caching is in fact extremely easy and should provide you with excellent performance.It is as simple as marking a ConcurrentHashMap as clustered and you have a synchronized cache. See here for an example: http://www.terracotta.org/web/display/orgsite/Recipe?recipe=concurrenthashmapAnd if you want/need eviction, you can get that from an add-on library: http://www.terracotta.org/web/display/docs/Cache+Evictor
Taylor Gautier
My only little problem with Terracotta is that it requires a server to work. It's not 100% P2P. I know I haven't mentioned it in my question, so +1 for the answer :)
GuiSim
Fair enough - but P2P has a host of issues also. I am obviously biased towards Terracotta considering I work there, that said, solutions based on UDP, multicast and P2P in my experience never work well in production. They require switch level and OS level configuration and tuning for any reasonable level of scale, and beyond 4 nodes, P2P breaks down as replicate everywhere doesn't work. So in the end, for production solutions invariably turn off multicasting, switch to TCP replication, and use the equivalent of a server based topology. But in dev, they certainly seem nice :)
Taylor Gautier
Thanks a lot for the input Taylor. Sadly, as it is often the case in software development, the choice between P2P vs Client/Server is not mine to take :(I'll let my boss know however. We've used Terracotta on other projects (that did not require P2P) in the past, maybe that'll help ;)
GuiSim
A: 

My option is Java Caching System from Apache, it has support of TCP Lateral Cache which in my opinion is the feature you need.

victor hugo
Thanks for the suggestion but, from the documentation : "[...]The two local caches could potentially have different versions of the same item. Like most caches, this is intended for high get and low put utilization, and this occurrence would hint at improper usage".. Once again I suspect that the term "cache" is probably not the right word to use in my situation. I will need to put data in the "cache" as often as I need to read it.
GuiSim
+1  A: 

How about this?

Have a local ConcurrentHashMap as your local cache. Create a Hazelcast distributed map/cache. Start listening for the distributed map events and update your local ConcurrentHashMap.

Now local caches on each member will be the same. Auto-synched.

import java.util.Map; 
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.EntryListener;
import com.hazelcast.core.EntryEvent; 
import java.util.concurrent.ConcurrentHashMap;

public class Sample implements ItemListener, EntryListener {
        Map localCache = new ConcurrentHashMap ();

        public static void main(String[] args) { 
                Sample sample = new Sample();
                Map   map   = Hazelcast.getMap   ("default"); 
                //listen for all added/updated/removed entries
                map.addEntryListener (sample, true);  
        } 

        public void entryAdded(EntryEvent event) {
             localCache.put(event.getKey(), event.getValue());            
        }

        public void entryRemoved(EntryEvent event) {
             localCache.remove(event.getKey());            
        }

        public void entryUpdated(EntryEvent event) {
             localCache.put(event.getKey(), event.getValue());            
        }       
}
Talip Ozturk
java.util.Map does not have a method called " addEntryListener " ..
GuiSim
you are right. it was supposed to be:com.hazelcast.core.IMap map = Hazelcast.getMap ("default");I will actually put an ReplicatedMap implementation into Hazelcast directly to make life a lot easier.
Talip Ozturk
Alright, thanks Talip ! :)
GuiSim
+1  A: 

After some more searching, I found JGroup's ReplicatedHashMap. It has not been thoroughly tested but it seems like an excellent start. It fills all my requirements without giving me too much features I don't need. It's also quite flexible. I'm still searching for the "perfect" answer though :)

Thanks for your answers.

GuiSim
JBossCache is essentially an industrial-strength implementation of ReplicatedHashMap. It uses the same underlying JGroups transport mechanism.
skaffman
+2  A: 

Have you considered Infinispan - http://www.jboss.org/infinispan/ ? The API is very simple and based on a standard (JSR-107). The usage is also very simple

CacheManager manager = new DefaultCacheManager(
                GlobalConfiguration.getClusteredDefault() );

Cache cache = manager.getCache();

cache.put("key", "value");

--Hardy

Hardy
Another very promising solution. Thanks !
GuiSim
+1  A: 

I've used a few technologies in this area, I can highly recommend JBoss Cache as the best choice for what you're trying to do. It uses JGroups as its transport, but provides a higher-level transactional abstraction. Out-of-the-box it gives you a distributed tree-node structure.

edit: Oh, and JBossCache is independent of JBoss Application Server, you can use it in any environment. If anything, it works better outside of JBossAS than it does inside it.

skaffman
A: 

You need NCache .

It is a distributed cache solution that allows you use any cache toplogy that suits your need. NCache lets you use Partitioned cache, where each cached item is partitioned across different servers, Replicated cache that keeps a copy of each item on every cache server, mirrored and client cache.

It also lets you use data expiration, eviction, read/write-through caching and more.

With NCache, you get high availability of data and you also get best performance even at peak load times.

You can get free version of NCache which has limited features or you may get the full-feature version to evaluate for free for two months. Download Ncache from here

james
A: 

http://ehcache.org/ is very good and light cache. It can be shared between multiple JVMs. Internally it can use JGroups.

Andrew Fink