Topic: 刚才找到的一篇关于JCS的文章 |
Print this page |
1.刚才找到的一篇关于JCS的文章 | Copy to clipboard |
Posted by: guansanwu Posted on: 2003-04-01 19:01 JCS Usage in Hibernate Overview JCS is a caching technology built in to Hibernate. The JCS project site can be found at http://jakarta.apache.org/turbine/jcs/ . JCS can be used to store commonly accessed domain objects, avoiding expensive database access. This document is a supplement to the existing Hibernate documentation, looking at loading strategies and their impact on cacheing. Examples Examples given in this document refer to a Country domain object. Country has a many-to-one association with Region and a many-to-many association with CreditCard. Region has a many-to-one association with itself, representing a parent region. Test data used: Country 239 Region 1500 CreditCard 7 Retrieving the Country object Australia will create: 1 Country Object 5 Credit Card Objects 3 Region objects, i.e. Australia is the grandchild of the root Region object. Cached objects may be read-write or read-only. All examples use the read-only syntax. Performance Timings Performance timings were produced in the following environment: Application Server Pentium IV 1.6Ghz 512MB RAM Orion 1.6 Linux 2.4 Database Server Pentium IV 2Ghz 1024MB RAM Oracle 9i Release 2 Linux 2.4 The first time a cacheable query is done, the cache has no effect on speed. On the second and successive queries, the cache will be populated and available to be hit. Timings are given for the LRU memory cache with no timeout. <hibernatedoclet ... /> hibernatedoclet, a module of the xdoclet project (see http://xdoclet.sourceforge.net) can be used to automate the production of Hibernate mapping files. In hibernatedoclet, jcs cache tags can be inserted at the class level, in which case the object is cacheable, or at the method level for the following Hibernate types: set, list, map, bag, array and primitive-array. See http://hibernate.sourceforge.net/hibernate-mapping.dtd for more information. class level /* * @hibernate.class table="COUNTRY" * @hibernate.jcs-cache usage="read-only" */ public class Country { ... The class level tag will make the object cacheable, but not collections representing many to many relationships. method level /** * @hibernate.set role="creditCards" table="COUNTRY_CREDIT_CARD" * @hibernate.jcs-cache usage="read-only" * @hibernate.collection-key column="FK_COUNTRY" * @hibernate.collection-many-to-many class="com.gregluck.domain.CreditCard" column="FK_CREDIT_CARD" */ public Set getCreditCards() { return creditCards; } The method level tag applied to a set, list, map, bag, array or primitive-array will make the collection cacheable. If the jcs-cache tag is added to all collection types in an object, then the entire object is cacheable. As of xdoclet 1.2 beta2, the method level jcs-cache tag is not implemented. Readers should check issue http://opensource.atlassian.com/projects/xdoclet/secure/ViewIssue.jspa?key=XDT-259 for information on whether this has been fixed. A corrected xdt file is included with the bug report. Update: the patch should make it into xdoclet 1.2 beta 3 ++Object Loading Methods The following discussion assumes that <jcs-cache usage=read-only /> tags are set at the class and method level in the Hibernate mapping files for all classes. In our example this is Country, Region and CreditCard. If Region does not have jcs-cache set, its Region member variable will never be cached. Session.load Session.load(...) will attempt to load the object and any member variables from cache. In our Country example, the object graph is 100% cached. Example country = (Country) session.load(Country.class, id); Performance Loading the object graph takes an average of 21ms with cacheing on Loading the object graph takes an average of 56ms with cacheing off Strategies for Use Session.load is the fastest way of loading an object where the id is known. Session.find Session.find(...) uses Hibernate OQL to execute a query. It is translated into SQL and executed against the database. Cacheing is never utilised by Session.find. Example Long id = new Long(5); List countries = session.find( "from country in class com.gregluck.domain.Country where " + "country.id > ? ", id, Hibernate.LONG); This example will load all countries with an id greater than 5. Performance Loading 239 countries takes an average of 137ms with cacheing on or off. Strategies for Use Session.find cannot be used to achieve caching. Session.iterate Session.iterate(...) uses Hibernate OQL to execute a query which returns object ids only. As objects are iterated over they are loaded using session.load transparently. The first part is never cached. The iteration is cached. Example Collection countries = new ArrayList(); session = sessionFactory.openSession(); Iterator i = session.iterate("from country in class com.gregluck.domain.Country"); while (i.hasNext()) { countries.add(i.next()); } This example will load all countries. Performance Loading 239 country object graphs takes an average of 370ms with cacheing off Loading 239 country object graphs takes an average of 76ms with cacheing on Loading 239 country object graphs takes an average of 281ms with cacheing off and lazy loading of the CreditCard set on. Loading 239 country object graphs takes an average of 25ms with cacheing on and lazy loading of the CreditCard set on. Strategies for Use Session.iterate should be used in preference to Session.find to utilise the cache. Additional performance can be achieved by making association collections such as Set load lazily. Set lazy on using lazy="true". An example using hibernate doclet is: * @hibernate.set role="creditCards" table="COUNTRY_CREDIT_CARD" lazy="true" ++Cache Configuration Using cache.ccf JCS is configured in the file cache.ccf. This file must be in the classpath and loadable by this.getClass().getResourceAsStream() by Hibernate. Unfortunately this seems to be problematic for some application servers. In Orion the only thing which seems to work is adding cache.ccf to the jcs.jar and placing jcs.jar in Orion's lib directory. Another Option in Orion is to put the cache.ccf file in ejb-app directory. A cache.ccf file which works with the above examples is: # DEFAULT CACHE REGION (memory cache) jcs.default=DC jcs.default.cacheattributes=org.apache.jcs.engine.CompositeCacheAttributes jcs.default.cacheattributes.MaxObjects=2000 jcs.default.cacheattributes.MemoryCacheName=org.apache.jcs.engine.memory.lru.LRUMemoryCache jcs.default.elementattributes=org.apache.jcs.engine.ElementAttributes jcs.default.elementattributes.IsEternal=false jcs.default.elementattributes.MaxLifeSeconds=24000 jcs.default.elementattributes.IdleTime=180000 jcs.default.elementattributes.IsSpool=false jcs.default.elementattributes.IsRemote=false jcs.default.elementattributes.IsLateral=false #Country Cache jcs.region.com.gregluck.domain.Country=DC jcs.region.com.gregluck.domain.Country.cacheattributes=org.apache.jcs.engine.CompositeCacheAttributes jcs.region.com.gregluck.domain.Country.cacheattributes.MaxObjects=1000 jcs.region.com.gregluck.domain.Country.cacheattributes.MemoryCacheName=org.apache.jcs.engine.memory.lru.LRUMemoryCache jcs.region.com.gregluck.domain.Country.cacheattributes.UseMemoryShrinker=true jcs.region.com.gregluck.domain.Country.cacheattributes.MaxMemoryIdleTimeSeconds=3600 jcs.region.com.gregluck.domain.Country.cacheattributes.ShrinkerIntervalSeconds=60 jcs.region.com.gregluck.domain.Country.elementattributes=org.apache.jcs.engine.ElementAttributes jcs.region.com.gregluck.domain.Country.elementattributes.IsEternal=false jcs.region.com.gregluck.domain.Country.elementattributes.MaxLifeSeconds=240 jcs.region.com.gregluck.domain.Country.elementattributes.IdleTime=180 jcs.region.com.gregluck.domain.Country.elementattributes.IsSpool=false jcs.region.com.gregluck.domain.Country.elementattributes.IsRemote=false jcs.region.com.gregluck.domain.Country.elementattributes.IsLateral=false #Region Cache jcs.region.com.gregluck.domain.Region=DC jcs.region.com.gregluck.domain.Region.cacheattributes=org.apache.jcs.engine.CompositeCacheAttributes jcs.region.com.gregluck.domain.Region.cacheattributes.MaxObjects=1000 jcs.region.com.gregluck.domain.Region.cacheattributes.MemoryCacheName=org.apache.jcs.engine.memory.lru.LRUMemoryCache jcs.region.com.gregluck.domain.Region.cacheattributes.UseMemoryShrinker=true jcs.region.com.gregluck.domain.Region.cacheattributes.MaxMemoryIdleTimeSeconds=3600 jcs.region.com.gregluck.domain.Region.cacheattributes.ShrinkerIntervalSeconds=60 jcs.region.com.gregluck.domain.Region.elementattributes=org.apache.jcs.engine.ElementAttributes jcs.region.com.gregluck.domain.Region.elementattributes.IsEternal=false jcs.region.com.gregluck.domain.Region.elementattributes.MaxLifeSeconds=240 jcs.region.com.gregluck.domain.Region.elementattributes.IdleTime=180 jcs.region.com.gregluck.domain.Region.elementattributes.IsSpool=false jcs.region.com.gregluck.domain.Region.elementattributes.IsRemote=false jcs.region.com.gregluck.domain.Region.elementattributes.IsLateral=false #CreditCard Cache jcs.region.com.gregluck.domain.CreditCard=DC jcs.region.com.gregluck.domain.CreditCard.cacheattributes=org.apache.jcs.engine.CompositeCacheAttributes jcs.region.com.gregluck.domain.CreditCard.cacheattributes.MaxObjects=1000 jcs.region.com.gregluck.domain.CreditCard.cacheattributes.MemoryCacheName=org.apache.jcs.engine.memory.lru.LRUMemoryCache jcs.region.com.gregluck.domain.CreditCard.cacheattributes.UseMemoryShrinker=true jcs.region.com.gregluck.domain.CreditCard.cacheattributes.MaxMemoryIdleTimeSeconds=3600 jcs.region.com.gregluck.domain.CreditCard.cacheattributes.ShrinkerIntervalSeconds=60 jcs.region.com.gregluck.domain.CreditCard.elementattributes=org.apache.jcs.engine.ElementAttributes jcs.region.com.gregluck.domain.CreditCard.elementattributes.IsEternal=false jcs.region.com.gregluck.domain.CreditCard.elementattributes.MaxLifeSeconds=240 jcs.region.com.gregluck.domain.CreditCard.elementattributes.IdleTime=180 jcs.region.com.gregluck.domain.CreditCard.elementattributes.IsSpool=false jcs.region.com.gregluck.domain.CreditCard.elementattributes.IsRemote=false jcs.region.com.gregluck.domain.CreditCard.elementattributes.IsLateral=false # System CACHE REGION (unused) #jcs.system.groupIdCache=DC #jcs.system.groupIdCache.cacheattributes=org.apache.jcs.engine.CompositeCacheAttributes #jcs.system.groupIdCache.cacheattributes.MaxObjects=10000 #jcs.system.groupIdCache.cacheattributes.MemoryCacheName=org.apache.jcs.engine.memory.lru.LRUMemoryCache #Auxiliary CACHE (disk cache) (unused) #jcs.auxiliary.DC=org.apache.jcs.auxiliary.disk.indexed.IndexedDiskCacheFactory #jcs.auxiliary.DC.attributes=org.apache.jcs.auxiliary.disk.indexed.IndexedDiskCacheAttributes #jcs.auxiliary.DC.attributes.DiskPath=cache #Lateral TCP Cache (unused) #jcs.auxiliary.LTCP=org.apache.jcs.auxiliary.lateral.LateralCacheFactory #jcs.auxiliary.LTCP.attributes=org.apache.jcs.auxiliary.lateral.LateralCacheAttributes #jcs.auxiliary.LTCP.attributes.TransmissionTypeName=TCP #jcs.auxiliary.LTCP.attributes.TcpServers=localhost:1111 #jcs.auxiliary.LTCP.attributes.TcpListenerPort=1110 #jcs.auxiliary.LTCP.attributes.PutOnlyMode=false In this file separate regions are set up for Country, Region and CreditCard so that different timeouts can be set. Though not shown, regions can also be set up for collections which are member variables e.g. Country/CreditCard. Manual Manipulation of JCS The Hibernate API is just enough for Hibernate to plug JCS into its existing Cache framework. For programmatic manipulation of caches beyond this, you can use the JCS API. See http://jakarta.apache.org/turbine/jcs/apidocs/index.html . With the API you can obtain a CacheManager, then Caches and manipulate those caches. Obtaining the CompositeCacheManager instance The examples shown use the CompositeCacheManager. It is a singleton within a JVM and can be readily obtained from a static getInstance() method. CompositeCacheManager cacheManager = CompositeCacheManager.getInstance(); Obtaining a Cache You can list caches with String[] names = cacheManager.getCacheNames(); for (int i = 0; i < names.length; i++) { LOG.debug("Cache: " + names[i]); } and obtain a cache using: CompositeCache cache = cacheManager.getCache("com.gregluck.domain.Country"); Emptying a Cache To empty all objects in a cache you can use: cache.removeAll(); |
Powered by Jute Powerful Forum® Version Jute 1.5.6 Ent Copyright © 2002-2021 Cjsdn Team. All Righits Reserved. 闽ICP备05005120号-1 客服电话 18559299278 客服信箱 714923@qq.com 客服QQ 714923 |