Reputation: 1492
I've a client application requesting some information from a url every 1 second.
In the server (a servlet & JSP application), in order to avoid DB access when it's not necessary, it's been implemented the next solution. Here's a snippet:
//a static HashMap where we save the last record inserted in db
public static Map<Long, Long> VALUES = new HashMap<Long, Long>();
// A lastRecordRead sent by the client
if (VALUES.get(id) != lastRecordRead) {
//Access the database to get some information
//cause the last value read is different from the last record inserted
...
}else{
//Do nothing
//It's not necessary access DB cause the parameters match
}
This was working as expected in development environment.
The problem comes when we have a clustered environment. We have the server deployed in two nodes (using jboss), each one with its own HashMap, and its own values. So depending on the node we attack, we can get different values...
¿Is there any way to share this HashMap between the two nodes? I was looking for some answer where I don't need to keep the 2 maps updated, meaning not calls between nodes...
Any kind of help would be appreciated.
EDIT: I'm now playing with HazelCast, and it seems so easy that I'm afraid I'm doing something wrong...
In my server I'm using now HazelCast instead of the HasMap:
public static Map<Long, Long> VALUES = (Hazelcast.newHazelcastInstance(new Config())).getMap("VALUES");
When records are inserted:
if (((VALUES.get(id) == null)||(VALUES.get(id) < lastIdInserted))) {
VALUES.put(id, lastIdInserted);
}
When the server is called by the client app:
// A lastRecordRead sent by the client
if (VALUES.get(id) != lastRecordRead) {
//Access the database to get some information
//cause the last value read is different from the last record inserted
...
}else{
//Do nothing
//It's not necessary access DB cause the parameters match
}
And I think, that's all. Could anyone confirm if this is ok or am I missing something..? Is this solution truly populating all over the nodes? I've been doing tests with 2 tomcats and it does work, but would it work with differents ips?
Upvotes: 0
Views: 3745
Reputation: 1745
You have two options:
...and tons of others.
Use 'publisher-subscriber' concept and update each HashMap instance by events. This is typically implemented with some JMS broker:
http://docs.oracle.com/cd/E19717-01/819-7759/aerbk/index.html https://www.rabbitmq.com/tutorials/tutorial-three-java.html
The choice depends on your needs: for fastest read and seek, without networking delays but with slow updates - use second option. This is good solution for data that is not changing frequently: geographical names, addresses and so on.
As general case - use fist one.
Upvotes: 4
Reputation: 7335
Are you sure that going to the database is an overhead that you can't afford? If you use the database then you can be sure that locking and concurrent access will be handled correctly. Using a HashMap means that you have to handle concurrent read and write access yourself, which could significantly add to your design, build and test effort.
Are you sure this isn't a premature optimization?
Upvotes: 0
Reputation: 9655
You need to use Distributed HashMap. There are some frameworks out there. hazelcast is one example. You can use Hazelcast community version (free).
You can also use Redisson (distributed computing) too: https://github.com/mrniko/redisson
Upvotes: 2