I have a case where I need to frequently update and retrieve values of a map. This variable should have the same keys and values throughout all four servers. If one server updates the Map, it should be reflective in the other servers.
I believe I should be caching this..
Can I have some example codes in how I should be achieving this ?
Thank you.
You need a distributed cache. Choosing one is another issue...
see here.
Example of using EhCache - here.
I would suggest to use any distributed cache for it, i.e. Hazelcast implementation for distributed map
You could setup a Hazelcast cluster and implement MapStore
Also you will need to configure Hazelcast clients on each tomcat server. This clients will load distributed map and take care of syncing the data.
Hazelcast has a great documentation and plenty of examples so it should be easy for you to deal with it.
Related
In my application i would like to have two cache maps
One for distributed cache(should be available in all instances of the tcp/ip network for global access
and another for application specific cache should be available only for this instance.
How to configure this?
Can anyone guide me?
Thanks in advance.
You could just use a regular ConcurrentHashMap since IMap in a single instance of Hazelcast is basically a local jvm process that extends it. but if you still need to use Hazelcast specific features on that single instance, you can just set it up as a single member cluster by disabling all join mechanisms.
Background]
- There are two java applications (A and B), and they can only communicate via Oracle DB
- A and B share the same database table
- A and B stores the data in cache
Problem]
If A performs simple transaction (insert/update/delete), the cache in A is updated. Also, the cache in B should be updated automatically!
Current Status]
Two solutions I found and tried
- Solution1) Using DatabaseChangeListener
- Solution2) Using Socket Programming
Question]
The solution will be used for company, and I would like to know if there is anything that I can improve my solutions.
1) What could be disadvantages if I use DatabaseChangeListener?
2) What could be disadvantages if I use socket programming? (Maybe it's too low-level that developer cannot maintain due to company policy?)
3) I heard there are 3rd party cache that also supports synchronization. Am I correct?
Please let me know if you need more information!
Thank you very much in advance!
[EDIT]
If would be much appreciated if you can leave a comment when you down-vote this. I would like to know how I can improve this question with your feedback! Thank you
Your question appears every now and then with slightly different aspects. One useful answer to that is here: Guava Cache, how to block access while doing removal
About using the DatabaseChangeListener:
Although you are fine with oracle, I would discourage the use of vendor specific interfaces. For me, it would be okay to use, if it is an performance optimization, but I would never use vendor specific interfaces for basic functionality.
Second, the usage of the change listener may still lead to dirty reads.
About "distributed caches" as veritas suggested:
There is a difference between distributed caches and clustered caches. Distributed caches spread (aka distribute) the cached data on different nodes, clustered caches are caches for clustered applications that keep track of data consistency within the cluster. A distributed cache usually is a clustered cache, but not the other way around. For a general idea on the topic I recommend the infinispan documentation on clustering as an intro: http://infinispan.org/docs/7.0.x/user_guide/user_guide.html#_clustering
Wrap up:
A clustered cache implementation is the thing you need. However, if you want data consistency, you still need to carefully design your transaction handling.
You can, of course, also do socket communication yourself and send simple object invalidate messages to the other applications. The challenging part is the error handling. When was the invalidate successful? Is there a timeout for the other nodes to acknowledge? When to drop a node and maintain a cluster state at all?
I will suggest for the 3rd Party Cache, if you have many similar use cases or many tables need to be updated .
Please read about terracotta Distributed Cache.
It gives exactly what you want.
You can also look for hazelcast or memcached
In Java, I have a HashMap containing objects (which can be serializable, if it helps). Elsewhere on a network, I have another HashMap in another copy of the application that I would like to stay in sync with the first.
For example if on computer A, someone runs myMap.put("Hello", "World"); and on computer B, someone runs myMap.put("foo", "bar");, then after some time delay for changes to propagate, both computers would have mayMap.get("Hello") == "World" and mayMap.get("foo") == "bar".
Is this requirement met by an existing facility in the Java language, a library, or some other program? If this is already a "solved problem" it would be great not to have to write my own code for this.
If there are multiple ways of achieving this I would prefer, in priority order:
Changes are guaranteed to propagate 100% of the time (doesn't matter how long it takes)
Changes propagate rapidly
Changes propagate with minimal bandwidth use between computers.
(Note: I have had trouble searching for solutions as results are dominated by questions about synchronizing access to a Map from multiple threads in the same application. This is not what my question is about.)
You could look at the hazelcast in-memory database.
It's an open source solution designed for distributed architectures.
It maps really well to your problem since the hazelcast IMap extends java.util.Map.
Link: Hazelcast IMap
what you are trying to do is call clustering between two node
here i have some solution
you can achieve your requirement using serialization make your map
serializable read and write state of map in each interval of time
and sync it.this is core and basic way to achieve your
functionality.but by using serialization you have to manually manage
sync of map(i.e you have to do code for that)
Hazelcast open source distributed caching mechanism hazelcast
is best api and have reach libarary to achive cluster environment
and share data between different node
coherence web also provide mechanism to achieve clustering by
Oracle
Ehcache is a cache library introduced in 2003 to improve
performance by reducing the load on underlying resources. Ehcache is
not for both general-purpose caching and caching Hibernate
(second-level cache), data access objects, security credentials, and
web pages. It can also be used for SOAP and RESTful server caching,
application persistence, and distributed caching
among all of above Hazelcast is best api go through it will sure help you
Currently we have 2 app severs, each has application level cache and has centralized database server. To keep both servers app cache in sync we have set up JMS broker in between. On cache clear on one server which sends message to JMS, since other is registered so it will get the message and clears the perticular entry based on message content.
Since this messaging system adds latency in clearing the cache entry, for some amount of time there will be inconsistency between application level caches.
So we thought of having centralized cache server to avoid all this extra work to done to keep all caches in sync.
We are thinking of using Ehcache/Terracotta or Hazelcast, these cache hold resultsets, locks info, and some system specific varaibles.
Please suggest best cache solution for us.
I probably can't suggest the best solution for you but I'll try to give some ideas:
Hazelcast: offers very easy to use distributed map (and lot's of other things worth to have a look at - distributed SQL Query is very neat):
Map<String, Object> map = Hazelcast.getMap("xxx");
and you are done. Work on the map using standard API's. Hazelcast config/setup is quite easy (compared to Ehcache/TC). The monitoring webapp is also easy to use and helpful but there are things missing. Performance should be more than sufficient for a small cluster (like your 2 servers).
Ehcache/Terracotta: would introduce a new infrastructure component to your setup (Terracotta Server) - may be a downside. Using this setup is in my experience quite intense in terms of things to learn and try out. The promise is enterprise class level performance and monitoring facilities.
If you don't have extreme high performance requirements I personally would go for Hazelcast and avoid the complexity of Ehcache/TC.
We have been using centralized Memcached server (as Hibernate 2nd level cache and other caching requirement) and its working well for us. We are using Memcached with XMemcached client and so far its working without any problem.
We have a web application that loads a User object from database. Its a high volume application with thousands of concurrent users so we're looking at ways to cache the User objects to minimise database load.
Currently using ehcache but are looking at memcached to lower the memory requirements of the application, and make it more scaleable.
Problem we are currently having with using memcached is the cpu load that serializing the User instance brings. We're looking at ways to speed up the serialization, but ar also considering if we could use a smaller ehcache cache backed by memcached server.
Has anyone had any experience using ehcache backed by memcached (ie. first look in ehcache, if user not there, look in memcache, if not there look in database)?
Any downsides to this kind of approach?
If you're willing to move away from Ehcache, you could consider Infinispan, which now includes integration with memcache. It's a bit more of a faff to get working than Ehcache, but not too much.
Starting with version 4.1, Infinispan distribution contains a server module that implements the memcached text protocol. This allows memcached clients to talk to one or several Infinispan backed memcached servers. These servers could either be working standalone just like memcached does where each server acts independently and does not communicate with the rest, or they could be clustered where servers replicate or distribute their contents to other Infinispan backed memcached servers, thus providing clients with failover capabilities.
It does make sense to do what you're suggesting. We've experienced the same issue with memcached in that the overhead to serialize objects back and forth isn't worth using it alone for a high volume application. Having a local cache reduces load on the application side while memcached reduces load on the database side. The downside comes with the additional complexity of writing two layers of caches and maintaining cache coherency. I'd try to minimize where you need to use it.
Infinispan can store objects as instances and minimize serialization overhead, also instead of replicating the data on each node it can distribute data to make better usage of your memory, or you can limit the amount of entries to keep in memory.
You can also have it just send invalidation messages to other nodes when you update a value, instead of sending the serialized values around.
In addition, for when it still needs to serialize it uses a very efficient Marshaller instead of Java's serialization, and since version 5 you can plug in your custom Externalizers to customize the wire format of some types to give it a extra push (generally not needed, but nice to have).
In case you where looking at memcached for other reasons as well, be aware that Infinispan also "speaks" the memcached text protocol so if you have other clients around you can still integrate with it.
You could pretty simply overwrite net.sf.ehcache.Cache.createDiskStore()
new Cache(..) {
protected Store createDiskStore() {
if (isDiskStore()) {
// default: return DiskStore.create(this, diskStorePath);
MemcachedStore store = new MemcachedStore(..);
getCacheConfiguration().addConfigurationListener(store);
return store;
} else {
return null;
}
}
}
MemcachedStore is a custom implementation of net.sf.ehcache.store.Store that you'll have to do yourself. That's not to trivial, but then again, starting from DiskStore shouldn't be too difficult.
You can't replace the DiskStore in ehcache because its final. You can implement a new OffHeapStore and plugin it in like that. This is how BigMemory works. There is an Apache project called DirectMemory doing the same thing.
See my post here for more detail:
http://forums.terracotta.org/forums/posts/list/0/8833.page#40635
This article specifies how we can use in-process cache in front of distributed cache in spring application by define our own MultiTieredCacheManager and MultiTieredCache:
Multi Tiered Caching - Using in-process Cache in front of Distributed Cache