Question

I'm using Memcached (using spymemcached as client) to cache response received from a remote server. The logic of my program is simple:

  • if the requested resource is cached in Memcached, return the cache immediately;
  • if not, connect to the remote server, cache it, and return the result.

The program is something like,

Object cachedResource = spyMemcachedClient.get(RESOURCE_KEY);
if (cachedResource != null) {
    return cachedResource;
} else {
    Object remoteResource = getTheResourceFromTheRemoteServer();
    spyMemcachedClient.set(RESOURCE_KEY, EXP_TIME, remoteResource);
    return remoteResource;
}

But I notice that since there will be many concurrent requests at the same time, it is possible that two threads both find cachedResource is null, so they both invoke getTheResourceFromTheRemoteServer, which I don't want to.

So, how can I avoid this. Is there any atomic operation like ConcurrentMap.putIfAbsent in spymemcached. (By the way, the program will be deployed on multiple instances, which means that it is not possible to use Java concurrent utils like Lock to achieve that.)

Était-ce utile?

La solution

There is add command in memcached that does what you want (list of commands). To avoid calling twice or more getTheResourceFromTheRemoteServer you should emulate write locks using memcached (combination of add and delete commands). So only a thread that successfully invokes add on same particular key (RESOURCE_KEY_LOCK) should call getTheResourceFromTheRemoteServer and put it into cache. Other threads should wait and call again get(RESOURCE_KEY)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top