Ehcache Cache Technology

Source: Internet
Author: User

Java cache framework ehcache is a pure Java in-process cache framework with fast and lean features. It is the default cacheprovider in hibernate.

Main features include:

1. Fast.

2. Simple.

3. Multiple cache policies

4. There are two levels of cache data: memory and disk, so there is no need to worry about capacity issues

5. the cached data will be written to the disk during the VM restart process.

6. distributed cache can be implemented through RMI, pluggable API, and other methods

7. Listening interfaces with cache and cache manager

8. Supports multiple cache manager instances and multiple cache regions of one instance

9. Provides hibernate cache implementation

10. etc.

 

Ehcache is an open source project from SourceForge (http://ehcache.sourceforge.net/). It is also a simple and fast cache component implemented in pure Java. Ehcache supports memory and disk caching, multiple elimination algorithms such as LRU, LFU, and FIFO, and distributed cache. It can be used as a cache plug-in for hibernate. It also provides a filter-based Cache, which can cache the response content and use gzip compression to increase the response speed.

Basic ehcache API usage
First, we will introduce the cachemanager class. It is mainly responsible for reading the configuration file. By default, it reads ehcache. xml under classpath, and creates and manages cache objects according to the configuration file.
// Use the default configuration file to create cachemanager
Cachemanager manager = cachemanager. Create ();
// You can use manager to generate a cache object with the specified name.
Cache cache = manager. getcache ("democache ");
// Use manager to remove the cache object with the specified name
Manager. removecache ("democache ");
You can call Manager. removalall () to remove all caches. You can disable cachemanager by calling the shutdown () method of manager.
With the cache object, you can perform some basic cache operations, such:
// Add an element to the cache
Element element = new element ("key", "value ");
Cache. Put (element );
// Retrieve elements from the cache
Element element = cache. Get ("key ");
Element. getvalue ();
// Remove an element from the cache
Cache. Remove ("key ");
You can directly use the above API to cache data objects. Note that cache objects must be serializable. In the following sections, I will introduce the integrated use of ehcache and spring and hibernate.

Configuration File
Cache configuration named democache in the configuration file ehcache. xml:
<Cache name = "democache"
Maxelementsinmemory = "10000"
Eternal = "false"
Overflowtodisk = "true"
Timetoidleseconds = "300"
Timetoliveseconds = "600"
Memorystoreevictionpolicy = "LFU"/>

Meanings of configuration parameters:
Maxelementsinmemory: Maximum number of objects that can be created in the cache
Eternal: whether the cached object is permanent. If yes, the timeout setting is ignored and the object never expires.
Timetoidleseconds: the cache data passivation time, that is, the maximum time interval between two access times before an element disappears, which is valid only when the element is not permanently resident, if the value is 0, it means that the element can pause for an infinite period of time.
Timetoliveseconds: The survival time of cached data, that is, the maximum time interval between an element construction and extinction. This is only valid when the element is not permanently resident, if the value is 0, it means that the element can pause for an infinite period of time.
Overflowtodisk: whether to enable disk cache when the memory is insufficient.
Memorystoreevictionpolicy: The elimination algorithm after the cache is full. The LRU and FIFO algorithms are not described here. LFU algorithms directly eliminate objects that are rarely used and retain frequently accessed objects in the memory. This algorithm is applicable to most website projects.
If the application needs to configure multiple caches with different names and parameters, you can modify the configuration file accordingly and add the required cache configuration.

Integrate ehcache with spring APO
First, place the ehcache. xml configuration file under classpath. Add the following cachemanager configuration in the spring configuration file:
<Bean id = "cachemanager"
Class = "org. springframework. cache. ehcache. ehcachemanagerfactorybean">
</Bean>
Configure democache:
<Bean id = "democache" class = "org. springframework. cache. ehcache. ehcachefactorybean">
<Property name = "cachemanager" ref = "cachemanager"/>
<Property name = "cachename">
<Value> democache </value>
</Property>
</Bean>
Next, write an interceptor class that implements the org. aopalliance. Intercept. methodinterceptor interface. With the interceptor, You can selectively configure the bean method to be cached. If the called method is configured as a cache, the interceptor generates a cache key for the method and checks whether the results returned by the method are cached. If the request has been cached, the cached result is returned. Otherwise, the intercepted method is executed again and the result is cached for the next call. The Code is as follows:
Public class methodcacheinterceptor implements methodinterceptor,
Initializingbean {

Private cache;

/**
* Set the cache name
*/
Public void setcache (Cache cache ){
This. cache = cache;
}

/**
* Check whether necessary parameters are provided.
*/
Public void afterpropertiesset () throws exception {
Assert. notnull (cache,
"A cache is required. Use setcache (cache) to provide one .");
}

/**
*
* If a method can be cached, its results will be cached. The returned results of the method must be serializable)
*/
Public object invoke (methodinvocation Invocation) throws throwable {
String targetname = invocation. getthis (). getclass (). getname ();
String methodname = invocation. getmethod (). getname ();
Object [] arguments = invocation. getarguments ();
Object result;

String cachekey = getcachekey (targetname, methodname, arguments );
Element element = NULL;
Synchronized (this ){
Element = cache. Get (cachekey );

If (element = NULL ){
// Call the actual method
Result = invocation. Proceed ();
Element = new element (cachekey, (serializable) result );
Cache. Put (element );
}
}
Return element. getvalue ();
}

/**
* Generate cachekey: targetname. methodname. argument0.argument1...
*/
Private string getcachekey (string targetname, string methodname,
Object [] arguments ){
Stringbuffer sb = new stringbuffer ();
SB. append (targetname). append ("."). append (methodname );
If (arguments! = NULL) & (arguments. length! = 0 )){
For (INT I = 0; I <arguments. length; I ++ ){
SB. append ("."). append (arguments [I]);
}
}
Return sb. tostring ();
}
}
Synchronized (this) code implements the synchronization function. Why must I synchronize data? The get and put operations of the cache object are synchronized. If the cached data comes from the database query, if this synchronization code is not available, when the key does not exist or the object corresponding to the key has expired, in the case of multi-thread concurrent access, many threads will re-execute this method, because it is expensive to re-query the database, and a large number of concurrent queries in an instant will put a lot of pressure on the database server. So the synchronization code here is very important.

Continue to configure the interceptor and Bean:
<Bean id = "methodcacheinterceptor" class = "com. xiebing. utils. Interceptor. methodcacheinterceptor">
<Property name = "cache">
<Ref local = "democache"/>
</Property>
</Bean>
<Bean id = "methodcachepointcut" class = "org. springframework. AOP. Support. regexpmethodpointcutadvisor">
<Property name = "advice">
<Ref local = "methodcacheinterceptor"/>
</Property>
<Property name = "patterns">
<List>
<Value>. * mymethod </value>
</List>
</Property>
</Bean>

<Bean id = "myservicebean"
Class = "com. xiebing. ehcache. Spring. myservicebean">
</Bean>

<Bean id = "myservice" class = "org. springframework. AOP. Framework. proxyfactorybean">
<Property name = "target">
<Ref local = "myservicebean"/>
</Property>
<Property name = "interceptornames">
<List>
<Value> methodcachepointcut </value>
</List>
</Property>
</Bean>

Myservicebean is the bean that implements the business logic. The returned results of mymethod () in the method must be cached. In this way, the mymethod () method of myservicebean will be searched from the cache first, and then the database will be queried. The AOP method greatly improves the system flexibility. By modifying the configuration file, you can cache the method results. All the operations on the cache are encapsulated in the interceptor implementation.

Cachingfilter
Using Spring AOP for integration, You can flexibly cache the returned result objects of methods. Cachingfilter can Cache HTTP Response content. In this way, the granularity of the cached data is relatively coarse, for example, the entire page is cached. It is easy to use and efficient. Its disadvantage is that it is not flexible enough and the degree of reuse is not high.
Ehcache uses the simplepagecachingfilter class to implement filter caching. This class is inherited from cachingfilter and has the calculatekey () method that generates the cache key by default. This method uses the URI of the HTTP request and the query condition to form the key. You can also implement a filter by yourself, inherit from the cachingfilter class, and overwrite the calculatekey () method to generate a custom key.
In my project, many pages use Ajax. To ensure that the JS request data is not cached by the browser, each request carries a random number parameter I. If simplepagecachingfilter is used, the keys generated each time are different, and the cache is meaningless. In this case, we will overwrite the calculatekey () method.

To use simplepagecachingfilter, first Add the following configuration in the configuration file ehcache. xml:
<Cache name = "simplepagecachingfilter" maxelementsinmemory = "10000" Eternal = "false"
Overflowtodisk = "false" timetoidleseconds = "300" timetoliveseconds = "600"
Memorystoreevictionpolicy = "LFU"/>
The name attribute must be simplepagecachingfilter. Modify the Web. xml file and add a filter configuration:
<Filter>
<Filter-Name> simplepagecachingfilter </filter-Name>
<Filter-class> net. SF. ehcache. constructs. Web. Filter. simplepagecachingfilter </filter-class>
</Filter>
<Filter-mapping>
<Filter-Name> simplepagecachingfilter </filter-Name>
<URL-pattern>/test. jsp </url-pattern>
</Filter-mapping>

Next we will write a simple test. jsp file for testing. The time displayed within 600 seconds will not change every time the cached page is refreshed. The Code is as follows:
<%
Out. println (new date ());
%>

The data output by cachingfilter is compressed by gzip Based on the accept-encoding header sent by the browser. After the author's test, the compressed gzip data volume is 1/4 of the original data volume, and the speed is 4-5 times the original data volume. Therefore, the cache and compression are very effective.
When using gzip compression, pay attention to two issues:
1. the filter adopts the system default encoding for gzip compression. For Chinese webpages using GBK encoding, you must set the language of the operating system to zh_cn.gbk. Otherwise, garbled characters may occur.
2. By default, cachingfilter will determine whether to perform gzip Compression Based on the value of the accept-encoding parameter contained in the request header sent by the browser. Although IE6/7 supports gzip compression, this parameter is not included in the request. To perform gzip compression on IE6/7, you can inherit the cachingfilter to implement your own filter, and then override the acceptsgzipencoding method in the specific implementation.

Implementation reference:
Protected Boolean acceptsgzipencoding (httpservletrequest request ){
Final Boolean IE6 = headercontains (request, "User-Agent", "MSIE 6.0 ");
Final Boolean IE7 = headercontains (request, "User-Agent", "MSIE 7.0 ");
Return acceptsencoding (request, "gzip") | IE6 | IE7;
}

Use of ehcache in hibernate
Ehcache can be used as the second-level cache of hibernate. Add the following settings to hibernate. cfg. xml:
<Prop key = "hibernate. cache. provider_class">
Org. hibernate. cache. ehcacheprovider
</Prop>
Then, add the following format information to each domain of the hibernate ing file that needs to be cached:
<Cache Usage = "read-write | nonstrict-read-write | read-only"/>
For example:
<Cache Usage = "read-write"/>
Add a cache configuration in the configuration file ehcache. XML, where name is the class name of the domain.
<Cache name = "domain. Class. Name"
Maxelementsinmemory = "10000"
Eternal = "false"
Timetoidleseconds = "300"
Timetoliveseconds = "600"
Overflowtodisk = "false"
/>

Ehcache monitoring
In addition to the functions of cache, during actual system operation, we will pay more attention to the memory size occupied by each cache object and the cache hit rate. With this data, we can optimize the cache configuration parameters and system configuration parameters to optimize the system performance. Ehcache provides convenient APIs for us to call to obtain monitoring data. The main methods include:

// Obtain the number of cached objects
Cache. getsize ();
// Obtain the memory occupied by the cache object
Cache. getmemorystoresize ();
// Obtain the number of cache read hits
Cache. getstatistics (). getcachehits ()
// Get the number of missed cache reads
Cache. getstatistics (). getcachemisses ()

Distributed cache
Ehcache 1.2 supports distributed caching. Distributed cache mainly solves the problem of data synchronization between different servers in the cluster environment. The specific configuration is as follows:

Add the following content to the configuration file ehcache. xml:
<Cachemanagerpeerproviderfactory
Class = "net. SF. ehcache. Distribution. rmicachemanagerpeerproviderfactory"
Properties = "peerdiscovery = automatic, multicastgroupaddress = 230.0.0.1, multicastgroupport = 4446"/>

<Cachemanagerpeerlistenerfactory
Class = "net. SF. ehcache. Distribution. rmicachemanagerpeerlistenerfactory"/>

In addition, you need to add
<Cacheeventlistenerfactory class = "net. SF. ehcache. Distribution. rmicachereplicatorfactory"/>
For example:
<Cache name = "democache"
Maxelementsinmemory = "10000"
Eternal = "true"
Overflowtodisk = "true">
<Cacheeventlistenerfactory class = "net. SF. ehcache. Distribution. rmicachereplicatorfactory"/>
</Cache>

Summary
Ehcache is an excellent Java-based Cache implementation. It is simple, easy to use, and has complete functions, and can be easily integrated with popular open-source frameworks such as spring and hibernate. Using ehcache can reduce the access pressure on the database server in the website project, increase the Website access speed, and improve the user experience.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.