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 <
[email protected]>:

> 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;
> }
>
>
>
>
>
>
>

Reply via email to