3 Replies Latest reply on Mar 17, 2010 7:03 AM by Alex Reshetnyak

    JBoss Cache usage: direct gets vs ordinary gets

    Alex Reshetnyak Newbie

      Hi all.

       

      JBoss Cache provides access to data stored in it by API
      (cache.get(...), node.get(..)) and direct access by SPI
      (cacheSPI.peek(...), nodeSPI.getDirect(...)). What is the difference?
      Get operation invokes interceptor chain and also performs "visit"
      command, so node is marked as being used for eviction to save it in
      memory.
      Peek/getDirect operation omits cache mechanisms so data is returned
      quickly, but not marked as being in use.
      Currently we were using ordinary get operations, but faced a serious
      performance decrease in multi-thread environment (1700->400tps, see
      result below). The reason of it is BlockingQueue used in JBoss Cache
      for storing events (marking node as being used, so eviction saves it
      in memory). Using Peek/getDirect there is practically no decrease, but
      some eviction issues can be. Let's see on example.
      1. Put node /a to cache. Accessing it with get method rather often
      will trigger a visit event, so node will always remain in cache (in
      RAM).
      2. Put node /a to cache. Accessing it with Peek/getDirect will not
      trigger an event, so node will be evicted when it's age is greater
      than configured value (timeToLive). So, i.e. 120s it will be evicted
      and on next access will be read from store (DB).

      So what "evil" will be smaller?

       

      Without use Peek/getDirect operatio to getting data from cache the many threads in our benchmark have state "wait".

      These threads is locken in org.jboss.cache.RegionImpl.registerEvictionEvent, see screan shot

      !!_thread_dump.png

      Result of Query benchmark:

      Threads              1                 2               3
      10 thread      ~1720tps     ~1760tps
      300threads   ~1750tps      ~390tps      1660tps

      1. Standalone configuration with Linked cache
      2. JBoss Cache-based configuration (current one)
      3. JBoss Cache-based configuration (current one), but with patched
      jcr.core, using peek/getDirect methods.

       

      The JBossCache configuration :

      <?xml version="1.0" encoding="UTF-8"?>
      <jbosscache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:jboss:jbosscache-core:config:3.1">
      
         <locking isolationLevel="READ_COMMITTED" useLockStriping="false" concurrencyLevel="50000" lockParentForChildInsertRemove="false"
            lockAcquisitionTimeout="20000" />
      
         <clustering mode="replication" clusterName="${jbosscache-cluster-name}">
            <stateRetrieval timeout="20000" fetchInMemoryState="false" />
            <jgroupsConfig multiplexerStack="jcr.benchmark.stack" />
            <sync />
         </clustering>
      
         <!-- Eviction configuration -->
         <eviction wakeUpInterval="2000">
            <default algorithmClass="org.jboss.cache.eviction.LRUAlgorithm"
               actionPolicyClass="org.exoplatform.services.jcr.impl.dataflow.persistent.jbosscache.ParentNodeEvictionActionPolicy"
               eventQueueSize="1000000">
               <property name="maxNodes" value="1000000" />
               <property name="timeToLive" value="900000" />
            </default>
         </eviction>
      </jbosscache>
      
        • 1. Re: JBoss Cache usage: direct gets vs ordinary gets
          Nicolas Filotto Novice
          Another possible workaround, if it cannot be solved by JBoss Cache itself, will be to use the ExpirationAlgorithm that cans ignore NodeVisitedEvents but it would mean that no other eviction algorithms can be used to better fit the customer requirements which is a big regression for us and the code will have to be reviewed in order to add the EXPIRATION_KEY everywhere it is needed.
          • 2. Re: JBoss Cache usage: direct gets vs ordinary gets
            Manik Surtani Master
            The queue blocks as it fills up.  Usually what you do is (a) increase the queue size or (b) increase how often the eviction thread runs.  Currently your eviction wakeup is large (2000 millis), you may want to drop this to 500 millis or something if you have a lot of threads accessing the cache. 
            • 3. Re: JBoss Cache usage: direct gets vs ordinary gets
              Alex Reshetnyak Newbie

              Hi, Manik Surtani.

              Thanks for the quick response.

               

              We was tested our Query benchmark with eviction wakeup interval equal 500 and 2000.

              Result of Query benchmark with different  eviction wakeup interval :

              Threads           1                 2                3                   4
              300threads   ~407tps      ~458tps      ~1947tps       ~2593tps

              1. JBoss Cache-based configuration (current one) with wakeUpInterval="2000".
              2. JBoss Cache-based configuration (current one) with wakeUpInterval="500".
              3. JBoss Cache-based configuration (current one) with wakeUpInterval="2000", but with patched
              jcr.core, using peek/getDirect methods.
              4. JBoss Cache-based configuration (current one) with wakeUpInterval="500", but with patched
              jcr.core, using peek/getDirect methods.

              After  drop eviction wakeUpInterval to 500, we have increase performance to :
              - JCR  :  ~12%
              - JCR (patched jcr.core, using peek/getDirect methods)  :  ~33%