Wednesday, 2 July 2014

Websphere commerce DynaCache Part1


DynaCache is available after the installation of websphere application server .But servlet caching needs to be enabled as shown below from the WAS admin console.
Enabling Web Sphere Application Server DynaCache



Right click on server  and  run  was administrative console.
Go to  menu ->  server -> server types -> websphere application servers -> server1
Go to  Container Settings  ->  Web container settings  ->  web container
Go to  select Enable Servlet caching  -> click apply ->  save


Enable Servlet Caching
Enable Servlet Caching


Cache Monitor is an EAR application provided by IBM for managing the Dyna Cache of the web sphere application server.
 
Configuring Cache Monitor in WCS
Select Applications  ->  click New Application
Select New Enterprise Application
Browse for C:\Program Files (x86)\IBM\SDP\runtimes\base_v7\installableApps
\CacheMonitor.ear
and   click ‘next’ -> next ->  select check box and click ‘finish’ -> save
Restart the server.

CacheMonitor1


CacheMonitor3


CacheMonitor4


CacheMonitor5

CacheMonitor6


CacheMonitor7



CacheMonitor8


CacheMonitor9




Once installed, you can access the cache monitor using the following url:
http://host_name:port/cachemonitor
where your port is the port associated with the host on which you installed the cache monitor application.In order to check the port where  the cache monitor is listening to check SystemOut.log file and look for the below message

[25/12/14 13:11:09:768 IST] 0000000a webcontainer  I com.ibm.ws.wswebcontainer.VirtualHost addWebApplication SRVE0250I: Web Module Dynamic Cache Monitor has been bound to default_host[*:80,*:80,*:443,*:5060,*:5061,*:443].

Try with the below URL  based on the logs.





CacheMonitor10



Cache Configuration  using Cache-spec.xml

Dyna Cache provides  performance improvements for websphere commerce applications by making use of  cachespec.xml .The objects to be cached are specified in cachespec.xml.
Location of cachespec.xml  in WCToolkit\Stores\WebContent\WEB-INF
Server Path  : \Stores.war\WEB-INF\
Servlet\JSP's and commands that extend from CacheableCommand interface can be cached using DynaCache.



There are two types of caching

1. Servlet/JSP Caching
2. Command Cache(Web Services, POJOs and EJBs)

Servlet/JSP Caching
Servlet/JSP results DynaCache can cache any existing whole page or fragment generated by a servlet or JSP. DynaCache matches data foundin the HTTP request header with the cache rules specified in the XML configuration file - cachespec.xml.
Command Cache (Web Services, POJOs and EJBs)
Used to cache dynamic data before it is transformed into a presentable format (that is, HTML). These include EJB and Web service responses. A cacheable command object must inherit from the class com.ibm.websphere.command.cachableCommandImpl for it to work with DynaCache.More details on cachespec.xml  are explained in the below section

Servlet/JSP Caching Example

<class>servlet</class>
<name>/StoreCatalogDisplay.jsp</name>
<property name="save-attributes">false</property>
<property name="store-cookies">false</property>
<timeout>3600</timeout>
<priority>3</priority>

<cache-id>
<component id="storeId" type="parameter">
<required>true</required>
</component>
<component id="catalogId" type="parameter">
<required>true</required>
</component>
</cache-id>
<dependency-id>storeId
<component id="storeId" type="parameter">
<required>true</required>
</component>
</dependency-id>
<invalidation>storeId
<component id="action" type="parameter" ignore-value="true">
<value>update</value>
<required>true</required>
</component>
<component id="storeId" type="parameter">
<required>true</required>
</component>
</invalidation>
</cache-entry>

Once a cache ID is safely stored in the cache, any subsequent requests that match with the cache ID are served from the cache. For e.g. once an entry is created for StoreCatalogDisplay.jsp for the storeID and catalogId and when the same request comes for the same storeID and catalogId the request is served from cache. By doing that the data base calls are avoided and performance is improved.
Command Cache Example
<cache-entry>
<class>command</class>
<sharing-policy>not-shared</sharing-policy>
<name>com.ibm.commerce.catalogmanagement.commands.AddCatalogDescCmdImpl</name>
<name>com.ibm.commerce.catalogmanagement.commands.UpdateCatalogDescCmdImpl</name>
</cache-entry>

Different elements of cachespec.xml is defined as follows

<cache-entry> This element defines a caching rule .This can be many in a cache-spec.xml file.
<Class> defines the type of object we are caching.
<cache-id> element defines a rule for caching an object .
<component> sub-element can appear many times within the <cache-id> element. Each time it specifies how to generate a component of a cache ID.
The <timeout>, <priority>, and <property> sub-elements can be used to control the cache entry expiry, cache eviction policy, and other generic properties for a cached object with an identifier generated by its enclosing <cache-id> element.
<required>This child element value determines whether or not the component must be present in the HTTP
request for a cache match to occur. A true value means it must be present and false means it is optional.
  
Dependency ID

Dependency ID elements are used to ensure related cache items that become out-of-date as a group are all evicted as a group. This process is known as invalidation. Each related cache item shares the same dependency ID, so it only takes one member of the dependency group to get invalidated, for the rest of the group to be evicted.

Dependency ID: Sample cachespec.xml definition

<dependency-id>storeId
<component id="" ignore-value="true" type="pathinfo">
<required>true</required>
<value>/StoreCatalogDisplay</value>
<value>/TopCategoriesDisplay</value>
<value>/CategoryDisplay</value>
<value>/ProductDisplay</value>
</component>
<component id="storeId" type="parameter">
<required>true</required>
</component>
</dependency-id>

Cachespec.xml property definitions

Do-not-cache
This property, when set to “true,” instructs DynaCache to not cache a fragment and not consume it in any parent cache item that incorporates it. The implication of this is that the JSP will be re-executed every time the page is drawn.
do-not-consume
The do-not-consume property works particularly well for situations where only a small portion of a candidate Web page contains personalized information, for e.g. mini shopping cart. In this scenario, you would want to cache the majority of the page, but separate the personalized portion. By using the do-not-consume property, most of a page can be rendered from the cache and completed with a portion that has been cached elsewhere, or not cached at all.So,the parent object’s <cache-entry> would be marked with the property consume-subfragments and the child fragment that contains the personalization content would be marked with the do-not-consume property.
consume-subfragments
Consume-subfragments (CSF) The parent entry, the one marked CSF, includes all the content from all fragments in its cache entry, resulting in one big cache entry that has no includes or forwards, but the content from the whole tree of entries.
save-attributes
When this property is set to false, the request attributes are not saved with the cache entry.
store-cookies
Takes one or more cookie name as its argument which is saved along with the cache object and restored by the servlet cache in the response with a set-cookie header.
ignore-get-post
When the property is set to true the request type is not appended to the cache-id for GET and POST requests .By default the request type is automatically appended to the cache-id for GET and POST requests
delay-invalidations
When this is property is set to true, the commands that are invalidating cached objects based on the invalidation rules in this cache entry invalidate the cache entries after running. By default, the invalidation occurs before the command run.

Fragment cache
Each dynamically included JSP file has to have its own <cache-entry> defined in the cachespec.xml file in order to be served up by the dynamic cache when it receives a request. Otherwise, each dynamically included JSP file will be re-executed for each request. 

Cache whole page excluding certain fragments
In some cases it is practical to exclude certain fragments from being cached with an entire page. Instead of being cached with the full page, the fragments are cached separate. For example, if there is a mini current order page, then the do-not-consume property is used. The parent entry is marked with the property consume-subfragments and the child fragment that contains the personalization area would be marked with this do-not-consume property. With this combination, the performance gain of whole page caching remains intact for the entire page excluding the child fragment that is cached separately apart from its parent.

1) Exclude JSP fragment from cache with out having an entry in cachespec.xml or setting
do-not-consume=true
1. You are caching a JSP in cachespec.xml, let’s call it "parent.jsp".
2. You have configured "parent.jsp" to consume sub-fragments.
3. There is a JSP being included by parent.jsp, let’s call it "child.jsp".
4. The file is being included using the <c:import> tag.
5. You don't want to cache child.jsp at all.
6. You don't want parent.jsp to consume child.jsp into its cache.

Solution to this problem:
Add the following line in child.jsp:
<% ((com.ibm.websphere.servlet.cache.ServletCacheResponse)response).setDoNotConsume(true); %>
This way gets around having to add child.jsp to cachespec.xml and setting do-not-consume=true.


2) Cache Invalidation (To make sure that parent jsp is invalidated when fragment jsp changes)
In particular, I refer to the fragments invalidation. Let's take the following example:
JSP Page (root): page1.jsp
Fragment 1 (1st level child): fragment1.jspf
Fragment 2 (2nd level child): fragment2.jspf
In terms of code, page1.jsp will have something like:
  
<% out.flush() %>
<c:import file="${filedir}page1.jsp"/>
<% out.flush() %>

And so do fragment1.jspf.In addition, cachespec.xml will have the following configuration:
  
<class>servlet</class>
<name>/directory/page1.jsp</name>
<property name="do-not-consume">true</property>
<property name="save-attributes">false</property>
<property name="consume-subfragments">true</property>

If the fragments do not seem to be invalidated properly,in other words, when something changes in the fragments parent(page1.jsp) does not change at all.

In fact, to make this scenario working properly we need to
#1 have the the property consume-subfragments set to true in the parent jsp cache-spec.xml.
#2 add, in the JSP fragments, the following code:
<% ((com.ibm.websphere.servlet.cache.ServletCacheResponse)response)..setDoNotConsume(true); %>
Just in this way, when a fragment changes, the parent will be invalidated.


Replication in DynaCache
Sharing policy 
This sharing policy defines how data is replicated from server to server. By default all cache entries are not shared across a cluster. You override that by specifying the sharing policy for each cache entry you want replicated. You also need to configure replication in your environment via the administration console.When you are preparing your Web site to operate within a cluster and planning to use DynaCache distributed capabilities, you should be aware of particular operational aspects that you can control. The first thing to be aware of is the sharing policy.
<cache-entry>

<class>servlet</class>

<name>/ConsumerDirect/include/MiniShopCartDisplay.jsp </name>

<property name="save-attributes">false</property>

<property name="store-cookies">false</property>

<property name="save-attributes">false</property>

<property name="do-not-consume">true</property>

<sharing-policy>not-shared</sharing-policy>
<cache-id>
<timeout>3600</timeout>
<component id="storeId" type="parameter">
<required>true</required>
</component>
<component id="catalogId" type="parameter">
<required>true</required>
</component>
<component id="DC_userId" type="attribute">
<required>true</required>
</component>
</cache-id>

Sharing policy options
not-shared
Cache entries for this object are not shared among different application servers. These entries can contain non-serializable data. For example, a cached servlet can place non-serializable objects into the request attributes , if the <class> type supports it.
shared-push
Cache entries for this object are automatically distributed to the DynaCaches in other application servers or cooperating Java virtual machines (JVMs).
shared-pull
Cache entries for this object are shared between application servers on demand.
shared-push-pool
Cache entries for this object are shared between application servers on demand.
 

Dyna cache Recommendations 
In-memory cache size tuning:

WebSphere Dynacache is configured with a default size of 2,000 for in-memory cache. On Linux, UNIX and Windows environments, given the constraints of the 32 bit Java™ architecture, it is not recommended that you increase much above than the default as the increased memory footprint might lead to out-of-memory-errors. 
Enable Disk off-load:
Enable disk off-load to allow the caching service to store cache entries on disk when the in-memory cache is full. Given the small number of cache entries that can be stored in memory, most WebSphere Commerce customers will require this feature. 

Enable Cache replication:
If WebSphere Commerce is running in a cluster environment, to ensure consistency across nodes, WebSphere Commerce requires that you define a replication domain.When using replication, you should tune the amount of data that is replicated across the servers by configuring the global replication policy, and the replication policy for each cache entry that is configured in cachespec.xml.

Edge caching:
For Web Server or Edge Server caching, only the URL parameters or cookies can be used as the cache ID.In order to cache WebSphere Commerce store pages the session information is put into session cookies.Store pages content is based on user session information. 
In order to cache these store pages the session information is required as part of the Cache ID. By default the session information(language ID, preferred currency ID, parent Organization, contract ID, and member group) is setup as request attributes by the cache filter.In order to cache outside of the application server this information will be stored as session cookies based on the configuration settings in instanceName.xml.These attributes can be renamed, added, or removed in wc-server.xml.

Enabling edge cookie generation in WC-Server.xml
You can enable cookies by changing the enable attribute to true in the following component:
<component
compClassName="com.ibm.commerce.dynacache.filter.EdgeCacheCookieHelper"
enable="true" name="DynaCacheCookie">
<property
CookieDomain=""
CookiePath="/"
MutipleStores="true"
Timeout="3600" display="false">
<ec name="languageId" value="true"/>
<ec name="currencyId" value="true"/>
<ec name="parentOrg" value="true"/>
<ec name="contractIds" value="true"/>
<ec name="memberGroups" value="true"/>
<ec name="buyerContractIds" value="true"/>
<ec name="userId" value="true"/>
<ec name="userType" value="true"/>
</property>
</component>

By changing the value attribute in the above component, you can select which of the following cookies you want to enable or disable:

WCDC_LANGID (language id)
WCDC_CURRID (currency id)
WCDC_PORG (parent organization)
WCDC_CACHEID1 (contractIds)
WCDC_CACHEID2 (memberGroups)
WCDC_CACHEID3 (buyerContractIds)
WCDC_CACHEID4 (userId)
WCDC_CACHEID5 (userType)

Enabling cookie support
With the capability of caching outside of WebSphere Application Server, it is possible to provide caching for each store.In cachespec.xml the multiple store cache entry includes the store id in the component id. Also, cache-id entries are made for each store.You can use Edge Caching in the following way:
  1. with a single store 
  2. with multiple stores

For use of Edge Caching to cache pages outside of the WebSphere Application Server, esiEnable must be set to true.Verify that the esiEnable property is set to true.The ESI processor is configurable through the WebSphere Web server plug-in configuration file,plugin-cfg.xml which is found in the WAS_installdir/config/cells/ directory.
<Property Name="esiEnable" Value="true"/>
Open cachespec.xml in the Web application archive (WAR) WEB-INF or enterprise bean WEB-INF directory.  Add a property to the cachespec.xml file to enable Edge Caching.
<property name="EdgeCacheable">true</property>

Single store scenario:
Add the following component entries to the cachespec.xml file inside the <cache-entry> tag.
<component id="Component ID" type="cookie">
<required>true</required>
</component>

Multiple store scenario:

Insert a <cache-id> entry for each store into the cachespec.xml with the following structure and   properties.


<!-- StoreCatalogDisplay?storeId=10001 -->
<cache-id>
<component id="" type="pathinfo">
<required>true</required>
<value>/StoreCatalogDisplay</value>
</component>
<component id="storeId" type="parameter">
<required>true</required>
<value>10001</value>
</component>
<component id="catalogId" type="parameter">
<required>true</required>
</component>
<component id="WC_LANGID_10001" type="cookie">
<required>true</required>
</component>
<component id="WC_CACHEID5_10001" type="cookie">
<required>true</required>
</component>
</cache-id>

<!-- StoreCatalogDisplay?storeId=10002 -->
<cache-id>
<component id="" type="pathinfo">
<required>true</required>
<value>/StoreCatalogDisplay</value>
</component>
<component id="storeId" type="parameter">
<required>false</required>
<value>10002</value>
</component>
<component id="catalogId" type="parameter">
<required>true</required>
</component>
<component id="WC_LANGID_10002" type="cookie">
<required>true</required>
</component>
<component id="WC_CACHEID5_10002" type="cookie">
<required>true</required>
</component>
</cache-id>

At run time the cookie generator dynamically produces a cookie named based on this storeId.For example, given the storeId 10001 and an English store the cookie  WC_LANGID_10001=-1  will be generated.

Read More details of Dyna Cache in the post  Websphere commerce DynaCache Part2.


1 comment:

  1. Good website! I truly love how it is easy on my eyes and the data are well written. I am wondering how I could be notified whenever a new post has been made. I have subscribed to your feed which must do the trick! Have a great day!


    Digital Brief Sydney

    ReplyDelete