3 Replies Latest reply on Dec 19, 2007 1:39 PM by genman

    improve s:cache performances

    zerg-spirit

      Hi, I already posted this message in the Seam forums, but I figured it was most probably a topic that would fit here.

      I'm currently working on a big page displaying a topic and every of its children hierarchically.
      Since these topics can have a lot of children, I figured out I should cache my page to enhance my performances.

      I actually managed to cache it, jumping from a poor 40s~ page generation time to a big but-still-not-great enhancement to 6s.
      Thanks to a sysout, I've also noticed that when a cached page is rendered, my backing bean is being used!
      I actually don't understand why it takes so much time, since as far as I understood, the whole page should be cached, so it should basically result to a 'static page', ie. almost an instant loading.

      Here's the code:

      Code:

      <!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      <ui:composition xmlns="http://www.w3.org/1999/xhtml"
      xmlns:s="http://jboss.com/products/seam/taglib"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:rich="http://richfaces.ajax4jsf.org/rich"
      xmlns:a4j="https://ajax4jsf.dev.java.net/ajax"
      xmlns:c="http://java.sun.com/jstl/core"
      template="/layout/template.xhtml">


      <ui:define name="body">
      <s:cache key="#{topicHome.instance}" region="/Topic" enabled="true">
      <h:form>
      <s:link value="#{messages['lrb.message.back_to_main_list']}" view="/Thesaurus.xhtml"/>
      <h:outputText value=" | " />
      <h:inputText value="#{searchTopic}" />
      <h:commandButton value="#{messages['lrb.action.search']}"
      action="#{thesaurusManager.searchTopic()}" />


      <h:commandLink action="#{thesaurusManager.showTopic(topicHome.instance)}"
      value="#{topicHome.instance.name}" />
      <h:commandLink
      action="#{thesaurusManager.selectTopic(topicHome.instance)}"
      value="(#{topicHome.instance.relatedBooks} #{messages['lrb.thesaurus.hits']})"
      rendered="#{topicHome.instance.relatedBooks.intValue() != 0}" />

      <ui:include src="/layout/alphabetLinks.xhtml"/>




      <c:forEach items="#{topicHome.instance.sortedColumnedChildren}"
      var="superList">

      <c:forEach items="#{superList}" var="list">
      <c:forEach items="#{list}" var="t">

      <f:subview >
      <s:link view="/showTopic" value="#{t.name}" propagation="nest"> <f:param name="topicId" value="#{t.id}" /> </s:link>
      (<s:link value="#{t.relatedBooks} #{messages['lrb.thesaurus.hits']}" view="/showBooks" propagation="nest"> <f:param name="topicId" value="#{t.id}"/> </s:link>)
      <ui:include src="/showChild.xhtml">
      <ui:param name="topic" value="#{t}" />
      </ui:include>
      </f:subview>
      </c:forEach>

      </c:forEach>
      </c:forEach>





      </h:form>
      </s:cache>
      </ui:define>

      </ui:composition>




      This page is the main one, the one I surrounded with s:cache tag.
      Then showChild is called recursively to load every children:
      Code:

      <c:forEach items="#{topic.children}" var="t">
      <f:subview>

      <s:link view="/showTopic" value="#{t.name}" propagation="nest"> <f:param name="topicId" value="#{t.id}" /> </s:link> (<s:link value="#{t.relatedBooks} #{messages['lrb.thesaurus.hits']}" view="/showBooks" propagation="nest"> <f:param name="topicId" value="#{t.id}"/> </s:link>)

      <ui:include src="/showChild.xhtml">
      <ui:param name="topic" value="#{t}" />
      </ui:include>


      </f:subview>
      </c:forEach>




      Then, finally, my treecache.xml config file:
      Code:

      <?xml version="1.0" encoding="UTF-8"?>

      <!-- ===================================================================== -->
      <!-- -->
      <!-- PojoCache Service Configuration -->
      <!-- -->
      <!-- ===================================================================== -->



      <!-- Used inside JBoss AS

      -->

      <!-- ==================================================================== -->
      <!-- Defines configuration -->
      <!-- ==================================================================== -->



      <!-- Used inside JBoss AS -->
      jboss:service=Naming
      jboss:service=TransactionManager

      <!--
      Configure the TransactionManager
      org.jboss.cache.DummyTransactionManagerLookup
      -->

      <!--
      Node locking scheme:
      OPTIMISTIC
      PESSIMISTIC (default)
      -->
      PESSIMISTIC

      <!--
      Note that this attribute is IGNORED if your NodeLockingScheme above is OPTIMISTIC.

      Isolation level : SERIALIZABLE
      REPEATABLE_READ (default)
      READ_COMMITTED
      READ_UNCOMMITTED
      NONE
      -->
      REPEATABLE_READ

      <!--
      Valid modes are LOCAL
      REPL_ASYNC
      REPL_SYNC
      INVALIDATION_ASYNC
      INVALIDATION_SYNC
      -->
      LOCAL

      <!-- Name of cluster. Needs to be the same for all clusters, in order
      to find each other
      -->
      Sample-Cluster

      <!-- JGroups protocol stack properties. Can also be a URL,
      e.g. file:/home/bela/default.xml

      -->



      <!-- UDP: if you have a multihomed machine,
      set the bind_addr attribute to the appropriate NIC IP address -->
      <!-- UDP: On Windows machines, because of the media sense feature
      being broken with multicast (even after disabling media sense)
      set the loopback attribute to true -->
      <UDP mcast_addr="228.1.2.5" mcast_port="45577" ip_ttl="64" ip_mcast="true" mcast_send_buf_size="150000"
      mcast_recv_buf_size="80000" ucast_send_buf_size="150000" ucast_recv_buf_size="80000" loopback="false" />
      <PING timeout="2000" num_initial_members="3" up_thread="false" down_thread="false" />
      <MERGE2 min_interval="10000" max_interval="20000" />
      <FD shun="true" up_thread="true" down_thread="true" />
      <VERIFY_SUSPECT timeout="1500" up_thread="false" down_thread="false" />
      <pbcast.NAKACK gc_lag="50" retransmit_timeout="600,1200,2400,4800" up_thread="false" down_thread="false" />
      <pbcast.STABLE desired_avg_gossip="20000" up_thread="false" down_thread="false" />
      <UNICAST timeout="600,1200,2400" window_size="100" min_threshold="10" down_thread="false" />
      <FRAG frag_size="8192" down_thread="false" up_thread="false" />
      <pbcast.GMS join_timeout="5000" join_retry_timeout="2000" shun="true" print_local_addr="true" />
      <pbcast.STATE_TRANSFER up_thread="false" down_thread="false" />




      <!--
      The max amount of time (in milliseconds) we wait until the
      initial state (ie. the contents of the cache) are retrieved from
      existing members in a clustered environment
      -->
      20000

      <!--
      Number of milliseconds to wait until all responses for a
      synchronous call have been received.
      -->
      15000

      <!-- Max number of milliseconds to wait for a lock acquisition -->
      10000

      <!-- Name of the eviction policy class. We have commented it off to disable eviction.
      -->
      org.jboss.cache.aop.eviction.AopLRUPolicy

      <!-- Specific eviction policy configurations. This is LRU -->


      5
      <!-- Cache wide default -->

      5000
      5


      5
      4


      100
      4


      5000
      10000
      1800









      I guess there's something wrong with my config file or something,

      Thanks for your help.

        • 1. Re: improve s:cache performances
          zerg-spirit

          Config file wasn't pasted correctly:

          <?xml version="1.0" encoding="UTF-8"?>
          
          <!-- ===================================================================== -->
          <!-- -->
          <!-- PojoCache Service Configuration -->
          <!-- -->
          <!-- ===================================================================== -->
          
          <server>
          
           <!-- Used inside JBoss AS
           <classpath codebase="./lib" archives="jboss-cache.jar, jgroups.jar"/>
           -->
          
           <!-- ==================================================================== -->
           <!-- Defines configuration -->
           <!-- ==================================================================== -->
          
           <mbean code="org.jboss.cache.aop.PojoCache" name="jboss.cache:service=testPojoCache">
          
           <!-- Used inside JBoss AS -->
           <depends>jboss:service=Naming</depends>
           <depends>jboss:service=TransactionManager</depends>
          
           <!--
           Configure the TransactionManager
           <attribute name="TransactionManagerLookupClass">org.jboss.cache.DummyTransactionManagerLookup</attribute>
           -->
          
           <!--
           Node locking scheme:
           OPTIMISTIC
           PESSIMISTIC (default)
           -->
           <attribute name="NodeLockingScheme">PESSIMISTIC</attribute>
          
           <!--
           Note that this attribute is IGNORED if your NodeLockingScheme above is OPTIMISTIC.
          
           Isolation level : SERIALIZABLE
           REPEATABLE_READ (default)
           READ_COMMITTED
           READ_UNCOMMITTED
           NONE
           -->
           <attribute name="IsolationLevel">REPEATABLE_READ</attribute>
          
           <!--
           Valid modes are LOCAL
           REPL_ASYNC
           REPL_SYNC
           INVALIDATION_ASYNC
           INVALIDATION_SYNC
           -->
           <attribute name="CacheMode">LOCAL</attribute>
          
           <!-- Name of cluster. Needs to be the same for all clusters, in order
           to find each other
           -->
           <attribute name="ClusterName">Sample-Cluster</attribute>
          
           <!-- JGroups protocol stack properties. Can also be a URL,
           e.g. file:/home/bela/default.xml
           <attribute name="ClusterProperties"></attribute>
           -->
          
           <attribute name="ClusterConfig">
           <config>
           <!-- UDP: if you have a multihomed machine,
           set the bind_addr attribute to the appropriate NIC IP address -->
           <!-- UDP: On Windows machines, because of the media sense feature
           being broken with multicast (even after disabling media sense)
           set the loopback attribute to true -->
           <UDP mcast_addr="228.1.2.5" mcast_port="45577" ip_ttl="64" ip_mcast="true" mcast_send_buf_size="150000"
           mcast_recv_buf_size="80000" ucast_send_buf_size="150000" ucast_recv_buf_size="80000" loopback="false" />
           <PING timeout="2000" num_initial_members="3" up_thread="false" down_thread="false" />
           <MERGE2 min_interval="10000" max_interval="20000" />
           <FD shun="true" up_thread="true" down_thread="true" />
           <VERIFY_SUSPECT timeout="1500" up_thread="false" down_thread="false" />
           <pbcast.NAKACK gc_lag="50" retransmit_timeout="600,1200,2400,4800" up_thread="false" down_thread="false" />
           <pbcast.STABLE desired_avg_gossip="20000" up_thread="false" down_thread="false" />
           <UNICAST timeout="600,1200,2400" window_size="100" min_threshold="10" down_thread="false" />
           <FRAG frag_size="8192" down_thread="false" up_thread="false" />
           <pbcast.GMS join_timeout="5000" join_retry_timeout="2000" shun="true" print_local_addr="true" />
           <pbcast.STATE_TRANSFER up_thread="false" down_thread="false" />
           </config>
           </attribute>
          
          
           <!--
           The max amount of time (in milliseconds) we wait until the
           initial state (ie. the contents of the cache) are retrieved from
           existing members in a clustered environment
           -->
           <attribute name="InitialStateRetrievalTimeout">20000</attribute>
          
           <!--
           Number of milliseconds to wait until all responses for a
           synchronous call have been received.
           -->
           <attribute name="SyncReplTimeout">15000</attribute>
          
           <!-- Max number of milliseconds to wait for a lock acquisition -->
           <attribute name="LockAcquisitionTimeout">10000</attribute>
          
           <!-- Name of the eviction policy class. We have commented it off to disable eviction.
           -->
           <attribute name="EvictionPolicyClass">org.jboss.cache.aop.eviction.AopLRUPolicy</attribute>
          
           <!-- Specific eviction policy configurations. This is LRU -->
           <attribute name="EvictionPolicyConfig">
           <config>
           <attribute name="wakeUpIntervalSeconds">5</attribute>
           <!-- Cache wide default -->
           <region name="/_default_">
           <attribute name="maxNodes">5000</attribute>
           <attribute name="timeToLiveSeconds">5</attribute>
           </region>
           <region name="/aop">
           <attribute name="maxNodes">5</attribute>
           <attribute name="timeToLiveSeconds">4</attribute>
           </region>
           <region name="/pojo">
           <attribute name="maxNodes">100</attribute>
           <attribute name="timeToLiveSeconds">4</attribute>
           </region>
           <region name="/Topic">
           <attribute name="maxNodes">5000</attribute>
           <attribute name="timeToLiveSeconds">10000</attribute>
           <attribute name="maxAgeSeconds">1800</attribute>
           </region>
           </config>
           </attribute>
           </mbean>
          
          </server>


          • 2. Re: improve s:cache performances
            manik

            Sorry about the late response on this. Your config file looks fine to me. Which backing bean do you see SEAM accessing on page refreshes? And does it access all the same methods as when you have caching disabled?

            • 3. Re: improve s:cache performances
              genman

              And a hint: I would probably turn on debug logging for Seam and JBoss Cache, then access the page after you're certain it has been cached then look at the progression of time stamps. You can often discern the call flow and find the hot spots.

              You eviction configuration seems a little aggressive. Lots of short TTLs.