[infinispan-dev] Today's topic: eviction
Galder Zamarreño
galder at redhat.com
Wed Nov 27 03:15:14 EST 2013
Comments below:
On Nov 21, 2013, at 7:48 PM, Pedro Ruivo <pedro at infinispan.org> wrote:
> (re: https://issues.jboss.org/browse/ISPN-3048)
> (ps. sorry for the long mail. I hope that is clear)
>
> * Automatic eviction:
>
> I've been writing some scenario involving eviction and concurrent
> operations. This test shows a very reliable eviction but we have a
> problem when passivation is enabled. The passivation phase is ok but
> when we need to activate a key, we have a huge window in which the
> read/write operation does not find the key neither in-memory data
> container neither in the cache loader. This happens because the check
> in-memory data container is not synchronized with the check in cache loader.
>
> Passivation phase works fine, as I said, because it happens inside the
> data container, i.e., the bounded concurrent hash map (BCHM) evict the
> key under the segment lock.
>
> * Manual eviction
>
> I haven't finish my test suite but so far it does not work as expected.
> If you are a backup owner, you are unable to evict any keys (because the
> EvictCommand is handled as a RemoveCommand and the key is not wrapped in
> EntryWrappingInterceptor). In addition, I believe that it has the same
> problems with activation as above.
>
> Also, I believe that passivation phase does not work well because it
> first tries to passivate than it removes from DataContainer. Nothing is
> preventing to passivate an old value, a put occurs and modifies the data
> in DataContainer and finally the EvictCommand removes the new value
> (that is lost).
>
> * New implementation
>
> Since we are stating a new major release, I would like to "propose" the
> following improvements. One aspect of the implementation is the dropping
> of the *Cache[Writer or Loader]Interceptor and the EvictCommand. Also,
> it would add a new method in DataContainer (void evict(K key)) and
> possible change the interface in PersistenceManager.
>
> My idea is based on the current implementation of the BCHM. The BCHM
> implementation is aware of the persistence and it performs internally
> the passivate() and activate() operations. I would like to extend this
> and make it full aware of the PersistenceManager. Also, it would be
> required to have ConcurrentHashMap (CHM) with the same features
>
> Enter in more detail, the (B)CHM.get() will be responsible to load the
> key from persistence (and activate it) if it is not found in-memory.
> Also, it stores the entry in memory. In other hand, the put() stores the
> entry in-memory and in the persistence (if passivation==false) and we
> add an evict(k) to the CHM interface to remove from memory and passivate
> it to persistence a single key.
>
> * Pros
>
> ** solves all the problems :)
> ** remove all the interceptors related to cache writer and cache loader
> => small interceptor chain
> ** remove evict command => lower process time(?)
> ** cache writer and cache loader does not need to have per key lock
> based (however, they should be thread safe)
> ** when passivation==true, we don't loose any key/value (yey)
> ** no need to acquire locks in lock manager (as the current manual
> eviction does)
> ** all the logic for cache loader/writer will be located in a single mode
>
> * Cons
>
> ** difficult to maintain. We have to maintain the code for the (B)CHM
> ** new API and contract for DataContainer interface => it should handle
> all the load/write from cache loader/writer
> ** new API for PersistenceManager
>
> toughs?
I like the idea. I did some work in the past to reduce situations where passivation lead to data loss, so I know the challenges involved in doing this. A tighter integration between the data container and the cache store/load logic would certainly improve things.
>
> Cheers
> Pedro
>
> * Open question in case this is going forward
>
> ** should contains(key) put the entry loaded in-memory (if loaded from
> cache loader)?
As a FYI, in JSR-107, they've made a differentiation between contains/get. Contains just checks the in-memory contents, so it never goes to the cache store, whereas the get() is read-through and so if the entry is not present in memory, it'll load it into memory.
In Infinispan API, contains/get are read-through, but we have a contains method in the cache loader, so don't need to load data.
> ** how iterator(), keys(), values() and entrySet() should behave? should
> they put the entries in memory? And size()?
Long term, we should end up with just iterator(), and that should not load into memory. Keys()/values()/entrySet()/size() are on the way out, so I'd not load stuff into memory.
>
> * API changes
>
> DataContainer
>
> (new) void evict(K key)
>
> PersistenceManager
>
> (new) Entry onRead(K key) //shoud read the key. if passivation, remove
> from loader
> (new) void onWrite(K key, Entry entry) //if passivation, then do
> nothing, else store it
> (new) Entry onRemove(K key) //remove and return old
> (new) void onEvict(K key, Entry entry) //if passivation, then store it
>
> * Some (B)CHM pseudo-code
>
> V get(K key)
> Segment s = segment(key)
> V value = s.get(key)
> if (value == null) {
> s.lock()
> //recheck if s.get(key) is still null
> value = persistenceManager.onLoad(key); //this activates the key if
> needed
> if (value != null) s.put(key, value)
> s.unlock()
> }
> return value
>
> V put(K key, V value)
> Segment s = segment(key)
> s.lock()
> V oldValue = s.get(key)
> persistenceManager.onWrite(key, value) //first try the persistence
> s.put(key, value) //can trigger eviction
> s.unlock()
>
> void evict(K key, V value)
> Segment s = segment(key)
> s.lock()
> persistenceManager.onEvict(key, value) //first try the persistence
> s.remove(key) //remove from memory if peristence is successful (we
> don't wanna loose the value, right?)
> s.unlock()
> _______________________________________________
> infinispan-dev mailing list
> infinispan-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/infinispan-dev
--
Galder Zamarreño
galder at redhat.com
twitter.com/galderz
Project Lead, Escalante
http://escalante.io
Engineer, Infinispan
http://infinispan.org
More information about the infinispan-dev
mailing list