Search code examples
javaproduction-environment

Shared java HashMap in a clustered environment


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?


Solution

  • 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