1

We have a two active/active node Wildfly 19 cluster configuration with infinispan (v 9.4.18) invalidation cache.

<invalidation-cache name="opencell-tenant-cache">
    <transaction locking="OPTIMISTIC" mode="NONE"/>
</invalidation-cache>

According to the infinispan documentation, when a cached value change on node1, a InvalidateCommand is send from node 1 to node2, invalidating/removing a key entry from a node2 cache.

What I noticed is that InvalidateCommand is send even on a new key put.

In our application if key is not found in cache, a value will be loaded from a DB and put in a cache. And as both servers are active, I get the following never ending scenario:

Request to Node 1 > Key not found on Node1 cache > Value is loaded from DB and put to Node1 cache > key invalidated on Node2
Request to Node 2 > Key not found on Node2 cache > Value is loaded from DB and put to Node2 cache > key invalidated on Node 1
Request to Node 1 > Key not found on Node1 cache > Value is loaded from DB and put to Node1 cache > key invalidated on Node 2
and so on.

With this scenario, I am invalidating cache constantly, even though data is never changed. I would expect that no invalidation command is send on new key put.

Otherwise what is a practical use of invalidation cache, if same key put after receiving invalidation command will trigger an invalidation again.

Thanks

Andrius
  • 41
  • 2

1 Answers1

0

I would expect that no invalidation command is send on new key put. And what is a new put?

Request to Node 2 > Key not found on Node2 cache <- in your example, Node 2 does not have the key locally; so it is a new put.

Node 2 can fetch the key from Node 2 if you configure a ClusterLoader. See Invalidation Cache Mode Documentation.

If invalidation does not fit your data access, take a look at the other cache modes (like replicated/distributed).

pruivo
  • 1,214
  • 7
  • 7
  • It seems that one need to use Cache.putForExternalRead() when putting a new key to an invalidation cache, so it would not trigger invalidation on other nodes. I would expect that infinispan itself would do such logic :
        If (cache.containsKey(A){
          cache.put(A,B); // sends invalidation
        } else {
          cache.putForExternalRead(A,B); // does not send invalidation
        }
    
    However JPA use invalidation cache for entity L2 cache. And even I dont change any data in DB (all read operations), everytime I change a server, I see invalidation requests between the servers.
    – Andrius Jan 19 '22 at 13:40
  • > I would expect that infinispan itself would do such logic :
     If
    > (cache.containsKey(A){ cache.put(A,B); // sends invalidation } else {
    > cache.putForExternalRead(A,B); // does not send invalidation } 
    This would be more expensive than just invalidating on every put, since containsKey(...) would need to be broadcast, and, if transactional, atomic.
    – Paul Ferraro Feb 22 '22 at 15:20
  • 1. **Cache.putForExternalRead(A,B);** isn't always an option (if you use it as Spring cache for example). 2. **ClusterLoader** is deprecated and going to be removed https://issues.redhat.com/browse/ISPN-11863 https://issues.redhat.com/browse/ISPN-11864 – Petr H Oct 03 '22 at 13:53
  • And **Replicated** mode (probably the best alternative) introduces serialization (performance penalty) that can't be avoided even for local gets it seems. – Petr H Oct 03 '22 at 17:12