2 Replies Latest reply on Aug 22, 2013 5:07 PM by Lukasz Szelag

    Cache preloading before forming a cluster (Infinispan + Spring)

    Lukasz Szelag Newbie

      Hi,

       

      Is there a way to preload (initialize) Infinispan caches before forming a cluster when using Infinispan (5.3.0) + Spring (3.2.3)?

       

      Background:

       

      I've recently replaced EhCache with Infinispan in order to enable distributed cache (EhCache doesn't support clustering in Open Source edition). The application uses Spring cache abstraction to interact with the cache. For some caches where there are heavy reads, cache entries (2 - 4 millons) are preloaded from the database when the application starts up. (Since cache preloading depends on availability of some DAO beans, this happens after the Spring context initializes). Whereas clustering is setup using replication (there are 6 nodes), it is not practical (for performance reasons) to form a cluster and replicate data before caches are preloaded. Even when using asynchronous replication with replication queue, there is an unacceptable performance degradation when populating caches while the cluster is up and running.

       

      Thanks,

      Lukasz

        • 1. Re: Cache preloading before forming a cluster (Infinispan + Spring)
          Lukasz Szelag Newbie

          I attempted to solve this problem by implementing a custom cache loader (a cache loader can be used to preload cache entries before the cluster is formed). However, the missing part is to have Spring create the cache loader instance. This is necessary in my case, as the cache loader needs to access DAO objects that are maintained by Spring. When configuring caches either via XML or programmatically, it is not possible to pass the cache loader instance. Instead, the cache loader is instantiated by Infinispan using the cache loader class name. Is there another way to solve this?

          • 2. Re: Cache preloading before forming a cluster (Infinispan + Spring)
            Lukasz Szelag Newbie

            I finally managed to solve this without using Infinispan-specific loaders, which in my opinion are not intended for this task. In case someone is interested, this is the approach I taken:

             

            1. Integrate Infinispan with Spring using infinispan-spring module

             

            2. Implement a Spring ApplicationListener, which preloads the cache from the database using injected Infinispan's EmbeddedCacheLoader and a custom DAO managed by Spring. (The preloading code should be executed from the onApplicationEvent() method to ensure that Spring container is fully initialized).

             

            The trick is then to use a local mode when storing entries in the cache, i.e:

             

            Cache<String, String> cache = cacheManager.getCache("myCache");

            AdvancedCache<String, String> advancedCache = cache.getAdvancedCache();

             

            advancedCache.withFlags(Flag.CACHE_MODE_LOCAL).put(key, value);

             

            This way any RPC messages will be suppressed (stored entries will not get replicated to other nodes in the cluster).