ignite-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "HEWA WIDANA GAMAGE, SUBASH" <Subash.HewaWidanaGam...@fmr.com>
Subject RE: Ignite Cluster: Cache Misses happening for existing keys
Date Thu, 13 Sep 2018 12:06:41 GMT
Thank you for the prompt response.

I agree there’s a race condition here. But the problem of the suggestion is, “getNewValue()”
will get called even for cache hits. This getNewValue eventually calling some backend legacy
API and the caching layer is setup to reduce the load for it.

From: Вячеслав Коптилин [mailto:slava.koptilin@gmail.com]
Sent: Thursday, September 13, 2018 4:08 AM
To: user@ignite.apache.org
Subject: Re: Ignite Cluster: Cache Misses happening for existing keys

This email is from an external source - exercise caution regarding links and attachments.
Please visit cybersecurity.fmr.com/phishing/ to learn more.

Hello,

Your code contains the following obvious race:

    String value = cache.get(key);
    if (value == null) {
        cache.put(key, getNewValue());
        LOG.info("Cache put key={} ", key);
    }

It's easy to imagine that two threads managed to execute get() method and got null value before
put() operation is called.

Please try to modify the code as follows:

    if (cache.putIfAbsent(key, getNewValue())) {

        LOG.info("Cache put key={} ", key);

    }

    else {

        LOG.info("Cache hit key={}", key);

    }



[1] https://ignite.apache.org/releases/latest/javadoc/org/apache/ignite/IgniteCache.html#putIfAbsent-K-V-



Thanks,

S.

чт, 13 сент. 2018 г. в 6:29, HEWA WIDANA GAMAGE, SUBASH <Subash.HewaWidanaGamage@fmr.com<mailto:Subash.HewaWidanaGamage@fmr.com>>:
Hi all,
We’re observing this in a 3 node server cluster(3 separate JVMs, in 3 separate VMs within
same datacenter, node to node latency is 2-3 milliseconds within the network).

As with following code is wrapped inside an http API, and that API is getting called by a
5000 users ramping up(60seconds) forever, hitting 3 nodes in a round robin manner.

With this, for same cache key, I could see more than one “Cache put key=” log appearing
with in 15mins window(actually I am getting this duplicate put logs after 2-3mins of the load
test)..

For the SAME cache key, there cannot be more than one put within 15mins. Based on cache size,
it’s well below eviction size, and since it’s well within the expiry window, looks to
me some timing issue when replicating the cache between the nodes.

Time between same key cache put logs is about 8-12 seconds usually.  Am I doing something
wrong here ? Any way we can make a cache.put operation synchronously complete only upon a
full node replication (not quite sure whether it helps though)?

Version: Ignite 1.9

Code to create the cache

IgniteConfiguration cfg = new IgniteConfiguration();
cfg.setDiscoverySpi(getDiscoverySpi()); // static ip list on tcp discovery
cfg.setClientMode(false);
cfg.setIncludeEventTypes(EventType.EVT_NODE_SEGMENTED,EventType.EVT_NODE_FAILED);
Ignite ignite = Ignition.start(cfg);

ignite.events().localListen(event -> {
    LOG.info("Cache event received: {} ", event);
    return true;},EventType.EVT_NODE_SEGMENTED, EventType.EVT_NODE_FAILED);


CacheConfiguration<String,String> cc  = new CacheConfiguration<>();
cc.setName("mycache1");
cc.setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(new Duration(TimeUnit.MINUTES, 15)));
cc.setCacheMode(CacheMode.REPLICATED);
  LruEvictionPolicy evictionPolicy = new LruEvictionPolicy();
  evictionPolicy.setMaxMemorySize(500 * 1024 * 1024);
cc.setEvictionPolicy(evictionPolicy);

IgniteCache<String,String> cache = ignite.getOrCreateCache(cc);


Code to cache operations.(following method can be accessed by multiple threads at the same
time)


private static String processKey(String key) {
    String value = cache.get(key);
    if (value == null) {
        cache.put(key, getNewValue());
        LOG.info("Cache put key={} ", key);
    } else {
        LOG.info("Cache hit key={}", key);
    }
    return value;
}



Mime
View raw message