Contents

1 Preface
1.1 Version
1.2 Audience
1.3 Printing
1.4 Acknowledgements
1.5 About the ehcache name and logo
2 Introduction
2.1 About Caches
2.2 Why caching works
2.2.1 Locality of Reference
2.2.2 The Long Tail
2.3 Will an Application Benefit from Caching?
2.3.1 Speeding up CPU bound Applications
2.3.2 Speeding up I/O bound Applications
2.3.3 Increased Application Scalability
2.4 How much will an application speed up with Caching?
2.4.1 The short answer
2.4.2 Applying Amdahl's Law
2.4.2.1 Persistent Object Relational Caching
2.4.2.2 Web Page Caching
2.4.2.3 Web Page Fragment Caching
2.4.3 Cache Efficiency
2.4.4 Cluster Efficiency
2.4.5 A cache version of Amdahl's law
2.4.6 Web Page example
3 Getting Started
3.1 General Purpose Caching
3.2 Hibernate
3.3 Java EE Servlet Caching
3.4 JCache style caching
3.5 Spring, Cocoon, Acegi and other frameworks
4 Features
4.1 Fast and Light Weight
4.1.1 Fast
4.1.2 Simple
4.1.3 Small foot print
4.1.4 Minimal dependencies
4.2 Scalable
4.2.1 Provides Memory and Disk stores for scalabilty into gigabytes
4.2.2 Scalable to hundreds of caches
4.2.3 Tuned for high concurrent load on large multi-cpu servers
4.2.4 Multiple CacheManagers per virtual machine
4.3 Complete
4.3.1 Supports Object or Serializable caching
4.3.2 Support cache-wide or Element-based expiry policies
4.3.3 Provides LRU, LFU and FIFO cache eviction policies
4.3.4 Provides Memory and Disk stores
4.3.5 Distributed
4.4 Standards Based
4.4.1 Full implementation of JSR107 JCACHE API
4.5 Extensible
4.5.1 Listeners may be plugged in
4.5.2 Peer Discovery, Replicators and Listeners may be plugged in
4.5.3 Cache Extensions may be plugged in
4.5.4 Cache Loaders may be plugged in
4.5.5 Cache Exception Handlers may be plugged in
4.6 Application Persistence
4.6.1 Persistent disk store which stores data between VM restarts
4.6.2 Flush to disk on demand
4.7 Listeners
4.7.1 CacheManager listeners
4.7.2 Cache event listeners
4.8 JMX Enabled
4.9 Distributed Caching
4.9.1 Peer Discovery
4.9.2 Reliable Delivery
4.9.3 Synchronous Or Asynchronous Replication
4.9.4 Copy Or Invalidate Replication
4.9.5 Transparent Replication
4.9.6 Extensible
4.9.7 Bootstrapping from Peers
4.10 Java EE and Applied Caching
4.10.1 Blocking Cache to avoid duplicate processing for concurrent operations
4.10.2 SelfPopulating Cache for pull through caching of expensive operations
4.10.3 Java EE Gzipping Servlet Filter
4.10.4 Cacheable Commands
4.10.5 Works with Hibernate
4.11 High Quality
4.11.1 High Test Coverage
4.11.2 Automated Load, Limit and Performance System Tests
4.11.3 Specific Concurrency Testing
4.11.4 Production tested
4.11.5 Fully documented
4.11.6 Trusted by Popular Frameworks
4.11.7 Conservative Commit policy
4.11.8 Full public information on the history of every bug
4.11.9 Responsiveness to serious bugs
4.12 Open Source Licensing
4.12.1 Apache 2.0 license
5 Key Ehcache Concepts
5.1 Key Ehcache Classes
5.1.1 CacheManager
5.1.1.1 CacheManager Creation Modes
5.1.1.1.1 Singleton Mode
5.1.1.1.2 Instance Mode
5.1.1.1.3 Mixed Singleton and Instance Mode
5.1.2 Ehcache
5.1.3 Element
5.2 Cache Usage Patterns
5.2.1 Direct Manipulation
5.2.2 Self Populating
6 Cache Configuration
6.1 ehcache.xsd
6.2 ehcache-failsafe.xml
6.3 ehcache.xml and other configuration files
7 Storage Options
7.1 Memory Store
7.1.1 Memory Use, Spooling and Expiry Strategy
7.2 DiskStore
8 Cache Eviction Algorithms
8.1 Eviction
8.1.1 Supported MemoryStore Eviction Algorithms
8.1.2 MemoryStore Eviction Algorithms
8.1.2.1 Least Recently Used (LRU)
8.1.2.2 Less Frequently Used (LFU)
8.1.2.3 First In First Out (FIFO)
8.1.3 DiskStore Eviction Algorithms
9 Code Samples
9.1 Using the CacheManager
9.1.1 Singleton versus Instance
9.1.2 Ways of loading Cache Configuration
9.1.3 Adding and Removing Caches Programmatically
9.1.4 Shutdown the CacheManager
9.2 Using Caches
9.2.1 Obtaining a reference to a Cache
9.2.2 Performing CRUD operations
9.2.3 Disk Persistence on demand
9.2.4 Obtaining Cache Sizes
9.2.5 Obtaining Statistics of Cache Hits and Misses
9.3 Creating a new cache from defaults
9.4 Creating a new cache with custom parameters
9.5 Registering CacheStatistics in an MBeanServer
9.6 Browse the JUnit Tests
10 Java Requirements, Dependencies and Maven POM snippet
10.1 Java Requirements
10.2 Mandatory Dependencies
10.2.1 Commons Logging
10.2.2 Backport Concurrent
10.3 Optional Dependencies
10.3.1 JMX
10.3.2 Commons collections
10.4 Maven pom.xml snippet
11 Logging And Debugging
11.1 Commons Logging
11.2 Logging Philosophy
11.3 Remote Network debugging and monitoring for Distributed Caches
12 Garbage Collection
12.1 Detecting Garbage Collection Problems
12.2 Garbage Collection Tuning
12.3 Distributed Caching Garbage Collection Tuning
13 JMX Management and Monitoring
13.1 JMX Overview
13.2 Dependencies
13.3 MBeans
13.4 JMX Remoting
13.5 ObjectName naming scheme
13.6 The Management Service
13.7 JConsole Example
13.8 JMX Tutorial
14 Class loading and Class Loaders
14.1 Plugin class loading
14.2 Loading of ehcache.xml resources
15 Performance Considerations
15.1 DiskStore
15.2 Replication
16 Cache Decorators
16.1 Creating a Decorator
16.2 Accessing the decorated cache
16.2.1 Using CacheManager to access decorated caches
16.3 Built-in Decorators
16.3.1 BlockingCache
16.3.2 SelfPopulatingCache
16.3.3 Caches with Exception Handling
17 Shutting Down Ehcache
17.1 The shutdown hook
17.2 When to use the shutdown hook
17.3 What the shutdown hook does
17.4 When a shutdown hook will run, and when it will not
17.5 If ehcache is shutdown dirty
18 Java EE Servlet Caching
18.1 CachingFilter
18.2 SimplePageCachingFilter
18.3 PageFragmentCachingFilter
18.4 SimplePageFragmentCachingFilter
19 The Design of distributed ehcache
19.1 Acknowledgements
19.2 Problems with Instance Caches in a Clustered Environment
19.3 Replicated Cache
19.4 Distributed Cache Terms
19.5 Notification Strategies
19.6 Topology Choices
19.6.1 Peer Cache Replicator
19.6.2 Centralised Cache Replicator
19.7 Discovery Choices
19.7.1 Multicast Discovery
19.7.2 Static List
19.8 Delivery Mechanism Choices
19.8.1 Custom Socket Protocol
19.8.2 Multicast Delivery
19.8.3 JMS Topics
19.8.4 RMI RMI is the default RPC mechanism in Java.
19.8.5 JXTA
19.8.6 JGroups
19.8.7 The Default Implementation
19.9 Replication Drawbacks and Solutions in ehcache's implementation
19.9.1 Chatty Protocol
19.9.2 Redundant Notifications
19.9.3 Potential for Inconsisent Data
19.9.4 Synchronous Delivery
19.9.5 Update via Invalidation
20 Distributed Caching
20.1 Suitable Element Types
20.2 Peer Discovery
20.2.1 Automatic Peer Discovery
20.2.1.1 Example
20.2.2 Manual Peer Discovery
20.2.2.1 Example
20.3 Configuring a CacheManagerPeerListener
20.4 Configuring CacheReplicators
20.5 Common Problems
20.5.1 Tomcat on Windows
20.5.2 Multicast Blocking
20.5.3 Multicast Not Progagating Far Enough or Propagating Too Far
21 Design of the ehcache constructs package
21.1 Acknowledgements
21.2 The purpose of the Constructs package
21.3 Caching meets Concurrent Programming
21.4 What can possibly go wrong?
21.4.1 Safety Failures
21.4.2 Liveness Failures
21.5 The constructs
21.5.1 Blocking Cache
21.5.2 SelfPopulatingCache
21.5.3 CachingFilter
21.5.4 SimplePageCachingFilter
21.5.5 PageFragmentCachingFilter
21.5.6 SimplePageFragmentCachingFilter
21.5.7 AsynchronousCommandExecutor
21.6 Real-life problems in the constructs package and their solutions
21.6.1 The Blocking Cache Stampede
21.6.2 The Blank Page problem
21.6.3 Blocking Cascade
22 CacheManager Event Listeners
22.1 Configuration
22.2 Implementing a CacheManagerEventListenerFactory and CacheManagerEventListener
23 Cache Loaders
23.1 Declarative Configuration
23.2 Implementing a CacheLoaderFactory and CacheLoader
23.3 Programmatic Configuration
24 Cache Event Listeners
24.1 Configuration
24.2 Implementing a CacheEventListenerFactory and CacheEventListener
25 Cache Exception Handlers
25.1 Declarative Configuration
25.2 Implementing a CacheExceptionHandlerFactory and CacheExceptionHandler
25.3 Programmatic Configuration
26 Cache Extensions
26.1 Declarative Configuration
26.2 Implementing a CacheExtensionFactory and CacheExtension
26.3 Programmatic Configuration
27 Hibernate Caching
27.1 Setting ehcache as the cache provider
27.1.1 Using the ehcache provider from the ehcache project
27.1.2 Using the Hibernate ehcache provider
27.1.3 Programmatic setting of the Hibernate Cache Provider
27.2 Hibernate Mapping Files
27.2.1 read-write
27.2.2 nonstrict-read-write
27.2.3 read-only
27.3 Hibernate Doclet
27.4 Configuration with ehcache.xml
27.4.1 Domain Objects
27.4.2 Hibernate
27.4.3 Collections
27.4.4 Hibernate CacheConcurrencyStrategy
27.4.5 Queries
27.4.6 StandardQueryCache
27.4.7 UpdateTimestampsCache
27.4.8 Named Query Caches
27.4.9 Using Query Caches
27.4.10 Hibernate CacheConcurrencyStrategy
27.5 Hibernate Caching Performance Tips
27.5.1 In-Process Cache
27.5.2 Object Id
27.5.3 Session.load
27.5.4 Session.find and Query.find
27.5.5 Session.iterate and Query.iterate
28 JSR107 (JCACHE) Support
28.1 JSR107 Implementation
28.2 Using JCACHE
28.2.1 Creating JCaches
28.2.1.1 Creating a JCache using an ehcache decorator
28.2.1.2 Creating a JCache from an existing Cache in Ehcache's CacheManager
28.2.1.3 Adding a JCache to Ehcache's CacheManager
28.2.1.4 Creating a JCache using the JCache CacheManager
28.2.2 Getting a JCache
28.2.3 Using a JCache
28.3 Problems and Limitations in the early draft of JSR107
28.3.1 net.sf.jsr107cache.CacheManager
28.3.2 net.sf.jsr107cache.CacheFactory
28.3.3 net.sf.jsr107cache.Cache
28.3.4 net.sf.jsr107cache.CacheEntry
28.3.5 net.sf.jsr107cache.CacheStatistics
28.3.6 net.sf.jsr107cache.CacheListener
28.3.7 net.sf.jsr107cache.CacheLoader
28.4 Other Areas
28.4.1 JMX
29 Tomcat Issues and Best Practices
29.1 Tomcat Known Issues
29.1.1 If I restart/reload a web application in Tomcat that has a CacheManager that is part of a cluster, the CacheManager is unable to rejoin the cluster. If I set logging for net.sf.ehcache.distribution to FINE I see the following exception: "FINE: Unable to lookup remote cache peer for .... Removing from peer list. Cause was: error unmarshalling return; nested exception is: java.io.EOFException.
29.1.2 In development, there appear to be classloader memory leak as I continually redeploy my web application.
29.1.3 I get net.sf.ehcache.CacheException: Problem starting listener for RMICachePeer ... java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: java.net.MalformedURLException: no protocol: Files/Apache. What is going on?
29.1.4 Multiple Host Entries in Tomcat's server.xml stops replication from occurring
30 Building from Source
30.1 Building Approach
30.2 Building an ehcache distribution from source
30.3 Running Tests for Ehcache
30.4 Building the Site
30.5 Deploying a release
30.5.1 Sourceforge Release
30.5.2 Central Maven Repository
31 Frequently Asked Questions
31.1 Does ehcache run on JDK1.3?
31.2 Can you use more than one instance of ehcache in a single VM?
31.3 Can you use ehcache with Hibernate and outside of Hibernate at the same time?
31.4 What happens when maxElementsInMemory is reached? Are the oldest items are expired when new ones come in?
31.5 Is it thread safe to modify Element values after retrieval from a Cache?
31.6 Can non-Serializable objects be stored in a cache?
31.7 Why is there an expiry thread for the DiskStore but not for the MemoryStore?
31.8 What elements are mandatory in ehcache.xml?
31.9 Can I use ehcache as a memory cache only?
31.10 Can I use ehcache as a disk cache only?
31.11 Where is the source code? The source code is distributed in the root directory of the download.
31.12 How do you get statistics on an Element without affecting them?
31.13 How do you get WebSphere to work with ehcache?
31.14 Do you need to call CacheManager.getInstance().shutdown() when you finish with ehcache?
31.15 Can you use ehcache after a CacheManager.shutdown()?
31.16 I have created a new cache and its status is STATUS_UNINITIALISED. How do I initialise it?
31.17 Is there a simple way to disable ehcache when testing?
31.18 Is there a Maven bundle for ehcache?
31.19 How do I dynamically change Cache attributes at runtime?
31.20 I get net.sf.ehcache.distribution.RemoteCacheException: Error doing put to remote peer. Message was: Error unmarshaling return header; nested exception is: java.net.SocketTimeoutException: Read timed out. What does this mean.
31.21 Should I use this directive when doing distributed caching? cacheManagerEventListenerFactory class="" properties=""/
31.22 What is the minimum config to get distributed caching going?
31.23 How can I see if distributed caching is working?
31.24 Why can't I run multiple applications using ehcache on one machine?
31.25 How many threads does ehcache use, and how much memory does that consume?
31.26 I am using Tomcat 5, 5.5 or 6 and I am having a problem. What can I do?
31.27 I am using Java 6 and getting a java.lang.VerifyError on the Backport Concurrent classes. Why?
31.28 How do I get a memory only cache to persist to disk between VM restarts?
32 About the ehcache name and logo
Index

1 PrefaceContents

This is a book about ehcache, a widely used open source Java cache. Ehcache has grown in size and scope since it was introduced in October 2003. As people used it they often noticed it was missing a feature they wanted. Over time, the features that were repeatedly asked for, and make sense for a Cache, have been added.

Ehcache is now used for Hibernate caching, data access object caching, security credential caching, web caching, application persistence and distributed caching. The biggest issue faced by Ehcache users at the time of writing is understanding when and how to use these features.

1.1 VersionContents

This book is for Ehcache version 1.4.0.

1.2 AudienceContents

The intended audience for this book is developers who use ehcache. It should be able to be used to start from scratch, get up and running quickly, and also be useful for the more complex options.

Ehcache is about performance and load reduction of underlying resources. Another natural audience is performance specialists.

It is also intended for application and enterprise architects. Some of the features of ehcache, such as distributed caching and Java EE caching, are alternatives to be considered along with other ways of solving those problems. This book discusses the trade-offs in ehcache's approach to help make a decision about appropriateness of use.

1.3 PrintingContents

The PDF is designed to be printed, with blank pages deliberately left to maintiain book conventions.

1.4 AcknowledgementsContents

Ehcache has had many contributions in the form of forum discussions, feature requests, bug reports, patches and code commits.

Rather than try and list the many hundreds of people who have contributed to ehcache in some way it is better to link to the web site where contributions are acknowledged in the following ways:

1.5 Contents

images/ehcache_logo

Adam Murdoch (an all round top Java coder) came up with the name in a moment of inspiration while we were stuck on the SourceForge project create page. Ehcache is a palindrome. He thought the name was wicked cool and we agreed.

The logo is similarly symmetrical, and is evocative of the diagram symbol for a doubly-linked list. That structure lies at the heart of ehcache.

2 IntroductionContents

Ehcache is a cache library. Before getting into ehcache, it is worth stepping back and thinking about caching generally.

2.1 About CachesContents

Wiktionary defines a cache as A store of things that will be required in future, and can be retrieved rapidly. That is the nub of it.

In computer science terms, a cache is a collection of temporary data which either duplicates data located elsewhere or is the result of a computation. Once in the cache, the data can be repeatedly accessed inexpensively.

2.2 Why caching worksContents

2.2.1 Locality of ReferenceContents

While ehcache concerns itself with Java objects, caching is used throughout computing, from CPU caches to the DNS system. Why? Because many computer systems exhibit locality of reference. Data that is near other data or has just been used is more likely to be used again.

2.2.2 The Long TailContents

Chris Anderson, of Wired Magazine, coined the term The Long Tail to refer to Ecommerce systems. The idea that a small number of items may make up the bulk of sales, a small number of blogs might get the most hits and so on. While there is a small list of popular items, there is a long tail of less popular ones.

images/longtail

The Long Tail

The Long Tail is itself a vernacular term for a Power Law probability distribution. They don't just appear in ecommerce, but throughout nature. One form of a Power Law distribution is the Pareto distribution, commonly know as the 80:20 rule.

This phenomenon is useful for caching. If 20% of objects are used 80% of the time and a way can be found to reduce the cost of obtaining that 20%, then the system performance will improve.

2.3 Will an Application Benefit from Caching?Contents

The short answer is that it often does, due to the effects noted above.

The medium answer is that it often depends on whether it is CPU bound or I/O bound. If an application is I/O bound then then the time taken to complete a computation depends principally on the rate at which data can be obtained. If it is CPU bound, then the time taken principally depends on the speed of the CPU and main memory.

While the focus for caching is on improving performance, it it also worth realizing that it reduces load. The time it takes something to complete is usually related to the expense of it. So, caching often reduces load on scarce resources.

2.3.1 Speeding up CPU bound ApplicationsContents

CPU bound applications are often sped up by:

2.3.2 Speeding up I/O bound ApplicationsContents

Many applications are I/O bound, either by disk or network operations. In the case of databases they can be limited by both.

There is no Moore's law for hard disks. A 10,000 RPM disk was fast 10 years ago and is still fast. Hard disks are speeding up by using their own caching of blocks into memory.

Network operations can be bound by a number of factors:

2.3.3 Increased Application ScalabilityContents

The flip side of increased performance is increased scalability. Say you have a database which can do 100 expensive queries per second. After that it backs up and if connections are added to it it slowly dies.

In this case, caching may be able to reduce the workload required. If caching can cause 90 of that 100 to be cache hits and not even get to the database, then the database can scale 10 times higher than otherwise.

2.4 How much will an application speed up with Caching?Contents

2.4.1 The short answerContents

The short answer is that it depends on a multitude of factors being:

The long answer, unfortunately, is complicated and mathematical. It is considered next.

2.4.2 Applying Amdahl's LawContents

Amdahl's law, after Gene Amdahl, is used to find the system speed up from a speed up in part of the system.

    1 / ((1 - Proportion Sped Up) + Proportion Sped Up / Speed up)

The following examples show how to apply Amdahl's law to common situations. In the interests of simplicity, we assume:

2.4.2.1 Persistent Object Relational Caching

A Hibernate Session.load() for a single object is about 1000 times faster from cache than from a database.

A typical Hibernate query will return a list of IDs from the database, and then attempt to load each. If Session.iterate() is used Hibernate goes back to the database to load each object.

Imagine a scenario where we execute a query against the database which returns a hundred IDs and then load each one.

The query takes 20% of the time and the roundtrip loading takes the rest (80%). The database query itself is 75% of the time that the operation takes. The proportion being sped up is thus 60% (75% * 80%).

The expected system speedup is thus:

    1 / ((1 - .6) + .6 / 1000)

    = 1 / (.4 + .006)

    = 2.5 times system speedup

2.4.2.2 Web Page Caching

An observed speed up from caching a web page is 1000 times. Ehcache can retrieve a page from its SimplePageCachingFilter in a few ms.

Because the web page is the end result of a computation, it has a proportion of 100%.

The expected system speedup is thus:

        1 / ((1 - 1) + 1 / 1000)

        = 1 / (0 + .001)

        = 1000 times system speedup

2.4.2.3 Web Page Fragment Caching

Caching the entire page is a big win. Sometimes the liveness requirements vary in different parts of the page. Here the SimplePageFragmentCachingFilter can be used.

Let's say we have a 1000 fold improvement on a page fragment that taking 40% of the page render time.

The expected system speedup is thus:

        1 / ((1 - .4) + .4 / 1000)

        = 1 / (6 + .004)

        = 1.6 times system speedup

2.4.3 Cache EfficiencyContents

In real life cache entrie do not live forever. Some examples that come close are "static" web pages or fragments of same, like page footers, and in the database realm, reference data, such as the currencies in the world.

Factors which affect the efficiency of a cache are:

liveness
how live the data needs to be. The less live the more it can be cached
proportion of data cached
what proportion of the data can fit into the resource limits of the machine. For 32 bit Java systems, there was a hard limit of 2GB of address space. While now relaxed, garbage collection issues make it harder to go a lot large. Various eviction algorithms are used to evict excess entries.
Shape of the usage distribution
If only 300 out of 3000 entries can be cached, but the Pareto distribution applies, it may be that 80% of the time, those 300 will be the ones requested. This drives up the average request lifespan.
Read/Write ratio
The proportion of times data is read compared with how often it is written. Things such as the number of rooms left in a hotel will be written to quite a lot. However the details of a room sold are immutable once created so have a maximum write of 1 with a potentially large number of reads.

Ehcache keeps these statistics for each Cache and each element, so they can be measured directly rather than estimated.

2.4.4 Cluster EfficiencyContents

Also in real life, we generally do not find a single server?

Assume a round robin load balancer where each hit goes to the next server.

The cache has one entry which has a variable lifespan of requests, say caused by a time to live. The following table shows how that lifespan can affect hits and misses.

 Server 1    Server 2   Server 3    Server 4

  M             M           M           M
  H             H           H           H
  H             H           H           H
  H             H           H           H
  H             H           H           H
  ...           ...         ...         ...

The cache hit ratios for the system as a whole are as follows:

Entry
Lifespan  Hit Ratio   Hit Ratio  Hit Ratio   Hit Ratio
in Hits   1 Server    2 Servers  3 Servers   4 Servers

2          1/2           0/2         0/2         0/2
4          3/4           2/4         1/4         0/4
10         9/10          8/10        7/10        6/10
20         19/20         18/20       17/20       16/10
50         49/50         48/50       47/20       46/50

The efficiency of a cluster of standalone caches is generally:

    (Lifespan in requests - Number of Standalone Caches) / Lifespan in requests

Where the lifespan is large relative to the number of standalone caches, cache efficiency is not much affected.

However when the lifespan is short, cache efficiency is dramatically affected.

(To solve this problem, ehcache supports distributed caching, where an entry put in a local cache is also propagated to other servers in the cluster.)

2.4.5 A cache version of Amdahl's lawContents

From the above we now have:

 1 / ((1 - Proportion Sped Up * effective cache efficiency) +
 (Proportion Sped Up  * effective cache efficiency)/ Speed up)

effective cache efficiency = cache efficiency * cluster efficiency

2.4.6 Web Page exampleContents

Applying this to the earlier web page cache example where we have cache efficiency of 35% and average request lifespan of 10 requests and two servers:

  cache efficiency = .35

  cluster efficiency = .(10 - 1) / 10
                     = .9

  effective cache efficiency = .35 * .9
                             = .315

        1 / ((1 - 1 * .315) + 1 * .315 / 1000)

        = 1 / (.685 + .000315)

        = 1.45 times system speedup

What if, instead the cache efficiency is 70%; a doubling of efficiency. We keep to two servers.

  cache efficiency = .70

  cluster efficiency = .(10 - 1) / 10
                     = .9

  effective cache efficiency = .70 * .9
                             = .63

        1 / ((1 - 1 * .63) + 1 * .63 / 1000)

        = 1 / (.37 + .00063)

        = 2.69 times system speedup

What if, instead the cache efficiency is 90%; a doubling of efficiency. We keep to two servers.

  cache efficiency = .90

  cluster efficiency = .(10 - 1) / 10
                     = .9

  effective cache efficiency = .9 * .9
                             = .81

        1 / ((1 - 1 * .81) + 1 * .81 / 1000)

        = 1 / (.19 + .00081)

        = 5.24 times system speedup

Why is the reduction so dramatic? Because Amdahl's law is most sensitive to the proportion of the system that is sped up.

3 Getting StartedContents

Ehcache can be used directly. It can also be used with the popular Hibernate Object/Relational tool. Finally, it can be used for Java EE Servlet Caching.

This quick guide gets you started on each of these. The rest of the documentation can be explored for a deeper understanding.

3.1 General Purpose CachingContents

3.2 HibernateContents

3.3 Java EE Servlet CachingContents

3.4 JCache style cachingContents

Ehcache contains an early draft implementation of JCache contained in the net.sf.ehcache.jcache package.

See the JSR107 chapter for usage.

3.5 Spring, Cocoon, Acegi and other frameworksContents

Usually, with these, you are using ehcache without even realising it. The first steps in getting more control over what is happening are:

4 FeaturesContents

4.1 Fast and Light WeightContents

4.1.1 FastContents

Over the years, various performance tests have shown ehcache to be one of the fastest Java caches. Ehcache's threading is designed for large, high concurrency systems.

Extensive performance tests in the test suite keep ehcache's performance consistent between releases.

As an example, some guys have created a java cache test tool called cache4j_perfomance_tester.

The results for ehcache-1.1 and ehcache-1.2 follow.

 
  ehcache-1.1

  [java] ---------------------------------------------------------------
  [java] java.version=1.4.2_09
  [java] java.vm.name=Java HotSpot(TM) Client VM
  [java] java.vm.version=1.4.2-54
  [java] java.vm.info=mixed mode
  [java] java.vm.vendor="Apple Computer, Inc."
  [java] os.name=Mac OS X
  [java] os.version=10.4.5
  [java] os.arch=ppc
  [java] ---------------------------------------------------------------
  [java] This test can take about 5-10 minutes. Please wait ...
  [java] ---------------------------------------------------------------
  [java] |GetPutRemoveT |GetPutRemove |Get |
  [java] ---------------------------------------------------------------
  [java] cache4j 0.4 |9240 |9116 |5556 |
  [java] oscache 2.2 |33577 |30803 |8350 |
  [java] ehcache 1.1 |7697 |6145 |3395 |
  [java] jcs 1.2.7.0 |8966 |9455 |4072 |
  [java] ---------------------------------------------------------------

  ehcache-1.2
  [java] ---------------------------------------------------------------
  [java] java.version=1.4.2_09
  [java] java.vm.name=Java HotSpot(TM) Client VM
  [java] java.vm.version=1.4.2-54
  [java] java.vm.info=mixed mode
  [java] java.vm.vendor="Apple Computer, Inc."
  [java] os.name=Mac OS X
  [java] os.version=10.4.5
  [java] os.arch=ppc
  [java] ---------------------------------------------------------------
  [java] This test can take about 5-10 minutes. Please wait ...
  [java] ---------------------------------------------------------------
  [java] |GetPutRemoveT |GetPutRemove |Get |
  [java] ---------------------------------------------------------------
  [java] cache4j 0.4 |9410 |9053 |5865 |
  [java] oscache 2.2 |28076 |30833 |8031 |
  [java] ehcache 1.2 |8753 |7072 |3479 |
  [java] jcs 1.2.7.0 |8806 |9522 |4097 |
  [java] ---------------------------------------------------------------

4.1.2 SimpleContents

Many users of ehcache hardly know they are using it. Sensible defaults require no initial configuration.

The API is very simple and easy to use, making it possible to get up and running in minutes. See the Code Samples for details.

4.1.3 Small foot printContents

Ehcache 1.2 is 110KB making it convenient to package.

4.1.4 Minimal dependenciesContents

Commons logging and collections are the only dependencies for most JDKs.

4.2 ScalableContents

4.2.1 Provides Memory and Disk stores for scalabilty into gigabytesContents

The largest ehcache installations use memory and disk stores in the gigabyte range. Ehcache is tuned for these large sizes.

4.2.2 Scalable to hundreds of cachesContents

The largest ehcache installations use hundreds of caches.

4.2.3 Tuned for high concurrent load on large multi-cpu serversContents

There is a tension between thread safety and performance. Ehcache's threading started off coarse-grained, but has increasingly made use of ideas from Doug Lea to achieve greater performance. Over the years there have been a number of scalability bottlenecks identified and fixed.

4.2.4 Multiple CacheManagers per virtual machineContents

Ehcache 1.2 introduced multiple CacheManagers per virtual machine. This enables completely difference ehcache.xml configurations to be applied.

4.3 CompleteContents

4.3.1 Supports Object or Serializable cachingContents

As of ehcache-1.2 there is an API for Objects in addition to the one for Serializable. Non-serializable Objects can use all parts of ehcache except for DiskStore and replication. If an attempt is made to persist or replicate them they are discarded and a WARNING level log message emitted.

The APIs are identical except for the return methods from Element. Two new methods on Element: getObjectValue and getKeyValue are the only API differences between the Serializable and Object APIs. This makes it very easy to start with caching Objects and then change your Objects to Seralizable to participate in the extra features when needed. Also a large number of Java classes are simply not Serializable.

4.3.2 Support cache-wide or Element-based expiry policiesContents

Time to lives and time to idles are settable per cache. In addition, from ehcache-1.2.1, overrides to these can be set per Element.

4.3.3 Provides LRU, LFU and FIFO cache eviction policiesContents

Ehcache 1.2 introduced Less Frequently Used and First In First Out caching eviction policies. These round out the eviction policies.

4.3.4 Provides Memory and Disk storesContents

Ehcache, like most of the cache solutions, provides high performance memory and disk stores.

4.3.5 DistributedContents

Flexible, extensible, high performance distributed caching. The default implementation supports cache discovery via multicast or manual configuration. Updates are delivered either asynchronously or synchronously via custom RMI connections. Additional discovery or delivery schemes can be plugged in by third parties.

See the Distributed Caching documentation for more feature details.

4.4 Standards BasedContents

4.4.1 Full implementation of JSR107 JCACHE APIContents

Ehcache offers the the most complete implementation of JSR107 JCACHE to date.

Because JCACHE has not yet been released the JCACHE API that Ehcache implements has been released as net.sf.jsr107cache.

Implementers can code to the JCACHE API which will create portability to other caching solutions in the future.

The maintainer of ehcache, Greg Luck, is on the expert committee for JSR107.

4.5 ExtensibleContents

4.5.1 Listeners may be plugged inContents

Ehcache 1.2 provides CacheManagerEventListener and CacheEventListener interfaces. Implementations can be plugged in and configured in ehcache.xml.

4.5.2 Peer Discovery, Replicators and Listeners may be plugged inContents

Distributed caching, introduced in ehcache 1.2 involves many choices and tradeoffs. The ehcache team believe that one size will not fit all. Implementers can use built-in mechanisms or write their own. A plugin development guide is included for this purpose.

4.5.3 Cache Extensions may be plugged inContents

Create your own Cache Extensions, which hold a reference to a cache and are bound to its lifecycle.

4.5.4 Cache Loaders may be plugged inContents

Create your own Cache Loaders, which are general purpose asynchronous methods for loading data into caches, or use them in pull-through configuration.

4.5.5 Cache Exception Handlers may be plugged inContents

Create an Exception Handler which is invoked if any Exception occurs on a cache operation.

4.6 Application PersistenceContents

4.6.1 Persistent disk store which stores data between VM restartsContents

With ehcache 1.1 in 2004, ehcache was the first open source Java cache to introduce persistent storage of cache data on disk on shutdown. The cached data is then accessible the next time the application runs.

4.6.2 Flush to disk on demandContents

With ehcache 1.2, the flushing of entries to disk can be executed with a cache.flush() method whenever required, making it easier to use ehcache

4.7 ListenersContents

4.7.1 CacheManager listenersContents

Register Cache Manager listeners through the CacheManagerEventListener interface with the following event methods:

4.7.2 Cache event listenersContents

Register Cache Event Listeners through the CacheEventListener interfaces, which provides a lot of flexibility for post-processing of cache events. The methods are:

4.8 JMX EnabledContents

Ehcache is JMX enabled. You can monitor and manage the following MBeans:

See the net.sf.ehcache.management package.

See http://weblogs.java.net/blog/maxpoon/archive/2007/06/extending_the_n_2.html for an online tutorial.

4.9 Distributed CachingContents

Ehcache 1.2 introduced a full-featured, fine-grained distributed caching mechanism for clusters.

4.9.1 Peer DiscoveryContents

Peer discovery may be either manually configured or automatic, using multicast. Multicast is simple, and adds and removes peers automatically. Manual configuration gives fine control and is useful for situations where multicast is blocked.

4.9.2 Reliable DeliveryContents

The built-in delivery mechanism uses RMI with custom sockets over TCP, not UDP.

4.9.3 Synchronous Or Asynchronous ReplicationContents

Replication can be set to synchronous Or asynchronous, per cache.

4.9.4 Copy Or Invalidate ReplicationContents

Replication can be set to copy or invalidate, per cache, as is appropriate.

4.9.5 Transparent ReplicationContents

No programming changes are required to make use of replication. Only configuration in ehcache.xml.

4.9.6 ExtensibleContents

Distributed caching, introduced in ehcache 1.2 involves many choices and tradeoffs. The ehcache team believe that one size will not fit all. Implementers can use built-in mechanisms or write their own. A plugin development guide is included for this purpose.

4.9.7 Bootstrapping from PeersContents

Distributed caches enter and leave the cluster at different times. Caches can be configured to bootstrap themselves from the cluster when they are first initialized.

An abstract factory, BootstrapCacheLoaderFactory has been defined along with an interface BootstrapCacheLoader along with an RMI based default implementation.

4.10 Java EE and Applied CachingContents

High quality implementations for common caching scenarios and patterns.

4.10.1 Blocking Cache to avoid duplicate processing for concurrent operationsContents

A cache which blocks subsequent threads until the first read thread populates a cache entry.

4.10.2 SelfPopulating Cache for pull through caching of expensive operationsContents

SelfPopulatingCache - a read-through cache. A cache that populates elements as they are requested without requiring the caller to know how the entries are populated. It also enables refreshes of cache entries without blocking reads on the same entries.

4.10.3 Java EE Gzipping Servlet FilterContents

4.10.4 Cacheable CommandsContents

This is the trusty old command pattern with a twist: asynchronous behaviour, fault tolerance and caching. Creates a command, caches it and then attempts to execute it.

4.10.5 Works with HibernateContents

Tested with Hibernate2.1.8 and Hibernate3.1.3, which can utilise all of the new features except for Object API and multiple session factories each using a different ehcache CacheManager.

A new net.sf.ehcache.hibernate.EhCacheProvider makes those additional features available to Hibernate-3.1.3. A version of the new provider should make it into the Hibernate3.2 release.

4.11 High QualityContents

4.11.1 High Test CoverageContents

The ehcache team believe that the first and most important quality measure is a well designed and comprehensive test suite.

Ehcache has a relatively high 86% test coverage of source code. This has edged higher over time. Clover enforces the test coverage. Most of the missing 14% is logging and exception paths.

4.11.2 Automated Load, Limit and Performance System TestsContents

The ehcache JUnit test suite contains some long-running system tests which place high load on different ehcache subsystems to the point of failure and then are back off to just below that point. The same is done with limits such as the amount of Elements that can fit in a given heap size. The same is also done with performance testing of each subsystem and the whole together. The same is also done with network tests for cache replication.

The tests serve a number of purposes:

4.11.3 Specific Concurrency TestingContents

Ehcache also has concurrency testing, which typically uses 50 concurrent threads hammering a piece of code. The test suites are also run on multi-core or multi-cpu machines so that concurrency is real rather than simulated. Additionally, every concurrency related issue that has ever been anticipated or resulted in a bug report has a unit test which prevents the condition from recurring. There are no reported issues that have not been reproduced in a unit test.

Concurrency unit tests are somewhat difficult to write, and are often overlooked. The team considers these tests a major factor in ehcache's quality.

4.11.4 Production testedContents

Ehcache came about in the first place because of production issues with another open source cache.

Final release versions of ehcache have been production tested on a very busy e-commerce site, supporting thousands of concurrent users, gigabyte size caches on large multi-cpu machines. It has been the experience of the team that most threading issues do not surface until this type of load has been applied. Once an issue has been identified and investigated a concurrency unit test can then be crafted.

4.11.5 Fully documentedContents

A core belief held by the project team is that a project needs good documentation to be useful.

In ehcache, this is manifested by:

4.11.6 Trusted by Popular FrameworksContents

Ehcache is used extensively. See the Who is Using? page, or browse Google.

4.11.7 Conservative Commit policyContents

Projects like Linux maintain their quality through a restricted change process, whereby changes are submitted as patches, then reviewed by the maintainer and included, or modified. Ehcache follows the same process.

4.11.8 Full public information on the history of every bugContents

Through the SourceForge project bug tracker, the full history of all bugs are shown, including current status. We take this for granted in an open source project, as this is typically a feature that all open source projects have, but this transparency makes it possible to gauge the quality and riskiness of a library, something not usually possible in commercial products.

4.11.9 Responsiveness to serious bugsContents

The ehcache team is serious about quality. If one user is having a problem, it probably means others are too, or will have. The ehcache team use ehcache themselves in production. Every effort will be made to provide fixes for serious production problems as soon as possible. These will be committed to trunk. From there an affected user can apply the fix to their own branch.

4.12 Open Source LicensingContents

4.12.1 Apache 2.0 licenseContents

Ehcache's original Apache1.1 copyright and licensing was reviewed and approved by the Apache Software Foundation, making ehcache suitable for use in Apache projects. ehcache-1.2 is released under the updated Apache 2.0 license.

The Apache license is also friendly one, making it safe and easy to include ehcache in other open source projects or commercial products.

5 Key Ehcache ConceptsContents

5.1 Key Ehcache ClassesContents

javadoc/net/sf/ehcache/package

Top Level Package Diagram

Ehcache consists of a CacheManager, which manages caches. Caches contain elements, which are essentially name value pairs. Caches are physically implemented either in-memory, or on disk.

5.1.1 CacheManagerContents

javadoc/net/sf/ehcache/CacheManager

CacheManager Class Diagram

The CacheManager comprises Caches which in turn comprise Elements.

Creation of, access to and removal of caches is controlled by the CacheManager.

5.1.1.1 CacheManager Creation Modes

CacheManager supports two creation modes: singleton and instance.

5.1.1.1.1 Singleton Mode

Ehcache-1.1 supported only one CacheManager instance which was a singleton. CacheManager can still be used in this way using the static factory methods.

5.1.1.1.2 Instance Mode

From ehcache-1.2, CacheManager has constructors which mirror the various static create methods. This enables multiple CacheManagers to be created and used concurrently. Each CacheManager requires its own configuration.

If the Caches under management use only the MemoryStore, there are no special considerations. If Caches use the DiskStore, the diskStore path specified in each CacheManager configuration should be unique. When a new CacheManager is created, a check is made that there are no other CacheManagers using the same diskStore path. If there are, a CacheException is thrown. If a CacheManager is part of a cluster, there will also be listener ports which must be unique.

5.1.1.1.3 Mixed Singleton and Instance Mode

If an application creates instances of CacheManager using a constructor, and also calls a static create method, there will exist a singleton instance of CacheManager which will be returned each time the create method is called together with any other instances created via constructor. The two types will coexist peacefully.

5.1.2 EhcacheContents

javadoc/net/sf/ehcache/Ehcache

Ehcache Interface Diagram

All caches implement the Ehcache interface. A cache has a name and attributes. Each cache contains Elements.

A Cache in ehcache is analogous to a cache region in other caching systems.

Cache elements are stored in the MemoryStore. Optionally they also overflow to a DiskStore.

5.1.3 ElementContents

javadoc/net/sf/ehcache/Element

Element Class Diagram

An element is an atomic entry in a cache. It has a key, a value and a record of accesses. Elements are put into and removed from caches. They can also expire and be removed by the Cache, depending on the Cache settings.

As of ehcache-1.2 there is an API for Objects in addition to the one for Serializable. Non-serializable Objects can use all parts of ehcache except for DiskStore and replication. If an attempt is made to persist or replicate them they are discarded without error and with a DEBUG level log message.

The APIs are identical except for the return methods from Element. Two new methods on Element: getObjectValue and getKeyValue are the only API differences between the Serializable and Object APIs. This makes it very easy to start with caching Objects and then change your Objects to Seralizable to participate in the extra features when needed. Also a large number of Java classes are simply not Serializable.

5.2 Cache Usage PatternsContents

Caches can be used in different ways. Each of these ways follows a cache usage pattern. Ehcache supports the following:

5.2.1 Direct ManipulationContents

Here, to put something in the cache you do cache.put(Element element) and to get something from the cache you do cache.get(Object key).

You are aware you are using a cache and you are doing so consciously.

5.2.2 Self PopulatingContents

Here, you just do gets to the cache using cache.get(Object key). The cache itself knows how to populate an entry.

See the SelfPopulatingCache for more on this pattern.

6 Cache ConfigurationContents

Caches can be configured in ehcache either declaratively, in xml, or by creating them programmatically and specifying their parameters in the constructor.

While both approaches are fully supported it is generally a good idea to separate the cache configuration from runtime use. There are also these benefits:

This chapter covers XML declarative configuration. See the Code samples for programmatic configuration.

Ehcache is redistributed by lots of projects. They may or may not provide a sample ehcache XML configuration file. If one is not provided, download ehcache from http://ehcache.sf.net. It, and the ehcache.xsd is provided in the distribution.

6.1 ehcache.xsdContents

Ehcache configuration files must be comply with the ehcache XML schema, ehcache.xsd, reproduced below.

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="ehcache" >
    <xs:complexType>
        <xs:sequence>
            <xs:element ref="diskStore"/>
            <xs:element minOccurs="0" maxOccurs="1"
                        ref="cacheManagerEventListenerFactory"/>
            <xs:element minOccurs="0" maxOccurs="1"
                        ref="cacheManagerPeerProviderFactory"/>
            <xs:element minOccurs="0" maxOccurs="1"
                        ref="cacheManagerPeerListenerFactory"/>
            <xs:element ref="defaultCache"/>
            <xs:element maxOccurs="unbounded" ref="cache"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>
<xs:element name="diskStore">
    <xs:complexType>
        <xs:attribute name="path" use="optional" />
    </xs:complexType>
</xs:element>
<xs:element name="cacheManagerEventListenerFactory">
    <xs:complexType>
        <xs:attribute name="class" use="required"/>
        <xs:attribute name="properties" use="optional"/>
        <xs:attribute name="propertySeparator" use="optional"/>
    </xs:complexType>
</xs:element>
<xs:element name="cacheManagerPeerProviderFactory">
    <xs:complexType>
        <xs:attribute name="class" use="required"/>
        <xs:attribute name="properties" use="optional"/>
        <xs:attribute name="propertySeparator" use="optional"/>
    </xs:complexType>
</xs:element>
<xs:element name="cacheManagerPeerListenerFactory">
    <xs:complexType>
        <xs:attribute name="class" use="required"/>
        <xs:attribute name="properties" use="optional"/>
        <xs:attribute name="propertySeparator" use="optional"/>
    </xs:complexType>
</xs:element>
<!-- add clone support for addition of cacheExceptionHandler. Important! -->
<xs:element name="defaultCache">
    <xs:complexType>
        <xs:sequence>
            <xs:element minOccurs="0" maxOccurs="unbounded" ref="cacheEventListenerFactory"/>
            <xs:element minOccurs="0" maxOccurs="unbounded" ref="cacheExtensionFactory"/>
            <xs:element minOccurs="0" maxOccurs="1" ref="bootstrapCacheLoaderFactory"/>
            <xs:element minOccurs="0" maxOccurs="1" ref="cacheExceptionHandlerFactory"/>
            <xs:element minOccurs="0" maxOccurs="1" ref="cacheLoaderFactory"/>
        </xs:sequence>
        <xs:attribute name="diskExpiryThreadIntervalSeconds" use="optional" type="xs:integer"/>
        <xs:attribute name="diskSpoolBufferSizeMB" use="optional" type="xs:integer"/>
        <xs:attribute name="diskPersistent" use="optional" type="xs:boolean"/>
        <xs:attribute name="eternal" use="required" type="xs:boolean"/>
        <xs:attribute name="maxElementsInMemory" use="required" type="xs:integer"/>
        <xs:attribute name="memoryStoreEvictionPolicy" use="optional" type="xs:string"/>
        <xs:attribute name="overflowToDisk" use="required" type="xs:boolean"/>
        <xs:attribute name="timeToIdleSeconds" use="optional" type="xs:integer"/>
        <xs:attribute name="timeToLiveSeconds" use="optional" type="xs:integer"/>
        <xs:attribute name="maxElementsOnDisk" use="optional" type="xs:integer"/>
    </xs:complexType>
</xs:element>
<xs:element name="cache">
    <xs:complexType>
        <xs:sequence>
            <xs:element minOccurs="0" maxOccurs="unbounded" ref="cacheEventListenerFactory"/>
            <xs:element minOccurs="0" maxOccurs="unbounded" ref="cacheExtensionFactory"/>
            <xs:element minOccurs="0" maxOccurs="1" ref="bootstrapCacheLoaderFactory"/>
            <xs:element minOccurs="0" maxOccurs="1" ref="cacheExceptionHandlerFactory"/>
            <xs:element minOccurs="0" maxOccurs="1" ref="cacheLoaderFactory"/>
        </xs:sequence>
        <xs:attribute name="diskExpiryThreadIntervalSeconds" use="optional" type="xs:integer"/>
        <xs:attribute name="diskSpoolBufferSizeMB" use="optional" type="xs:integer"/>
        <xs:attribute name="diskPersistent" use="optional" type="xs:boolean"/>
        <xs:attribute name="eternal" use="required" type="xs:boolean"/>
        <xs:attribute name="maxElementsInMemory" use="required" type="xs:integer"/>
        <xs:attribute name="memoryStoreEvictionPolicy" use="optional" type="xs:string"/>
        <xs:attribute name="name" use="required" type="xs:string"/>
        <xs:attribute name="overflowToDisk" use="required" type="xs:boolean"/>
        <xs:attribute name="timeToIdleSeconds" use="optional" type="xs:integer"/>
        <xs:attribute name="timeToLiveSeconds" use="optional" type="xs:integer"/>
        <xs:attribute name="maxElementsOnDisk" use="optional" type="xs:integer"/>
    </xs:complexType>
</xs:element>
<xs:element name="cacheEventListenerFactory">
    <xs:complexType>
        <xs:attribute name="class" use="required"/>
        <xs:attribute name="properties" use="optional"/>
        <xs:attribute name="propertySeparator" use="optional"/>
    </xs:complexType>
</xs:element>
<xs:element name="bootstrapCacheLoaderFactory">
    <xs:complexType>
        <xs:attribute name="class" use="required"/>
        <xs:attribute name="properties" use="optional"/>
        <xs:attribute name="propertySeparator" use="optional"/>
    </xs:complexType>
</xs:element>
<xs:element name="cacheExtensionFactory">
    <xs:complexType>
        <xs:attribute name="class" use="required"/>
        <xs:attribute name="properties" use="optional"/>
        <xs:attribute name="propertySeparator" use="optional"/>
    </xs:complexType>
</xs:element>
<xs:element name="cacheExceptionHandlerFactory">
    <xs:complexType>
        <xs:attribute name="class" use="required"/>
        <xs:attribute name="properties" use="optional"/>
        <xs:attribute name="propertySeparator" use="optional"/>
    </xs:complexType>
</xs:element>
<xs:element name="cacheLoaderFactory">
    <xs:complexType>
        <xs:attribute name="class" use="required"/>
        <xs:attribute name="properties" use="optional"/>
        <xs:attribute name="propertySeparator" use="optional"/>
    </xs:complexType>
</xs:element>
</xs:schema>

6.2 ehcache-failsafe.xmlContents

If the CacheManager default constructor or factory method is called, ehcache looks for a file called ehcache.xml in the top level of the classpath. Failing that it looks for ehcache-failsafe.xml in the classpath. ehcache-failsafe.xml is packaged in the ehcache jar and should always be found.

ehcache-failsafe.xml provides an extremely simple default configuration to enable users to get started before they create their own ehcache.xml.

If it used ehcache will emit a warning, reminding the user to set up a proper configuration.

The meaning of the elments and attributes are explained in the section on ehcache.xml. --- ehcache diskStore path="java.io.tmpdir"/ defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" maxElementsOnDisk="10000000" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" / /ehcache ---

6.3 ehcache.xml and other configuration filesContents

If the CacheManager default constructor or factory method is called, ehcache looks for a file called ehcache.xml in the top level of the classpath.

The non-default creation methods allow a configuration file to be specified which can be called anything.

One XML configuration is required for each CacheManager that is created. It is an error to use the same configuration, because things like directory paths and listener ports will conflict. Ehcache will attempt to resolve conflicts and will emit a warning reminding the user to configure a separate configuration for multiple CacheManagers with conflicting settings.

The sample ehcache.xml, which is included in the ehcache distribution is reproduced below:

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                            xsi:noNamespaceSchemaLocation="ehcache.xsd">

    <!--
    CacheManager Configuration
    ==========================
    An ehcache.xml corresponds to a single CacheManager.

    See instructions below or the ehcache schema (ehcache.xsd) on how to configure.

    DiskStore configuration
    =======================

    Sets the path to the directory where cache files are created.

    If the path is a Java System Property it is replaced by its value in the
    running VM.

    The following properties are translated:
    * user.home - User's home directory
    * user.dir - User's current working directory
    * java.io.tmpdir - Default temp file path

    Subdirectories can be specified below the property e.g. java.io.tmpdir/one
    -->
    <diskStore path="java.io.tmpdir"/>

    <!--
    CacheManagerEventListener
    =========================
    Specifies a CacheManagerEventListenerFactory, be used to create a CacheManagerPeerProvider,
    which is notified when Caches are added or removed from the CacheManager.

    The attributes of CacheManagerEventListenerFactory are:
    * class - a fully qualified factory class name
    * properties - comma separated properties having meaning only to the factory.

    Sets the fully qualified class name to be registered as the CacheManager event listener.

    The events include:
    * adding a Cache
    * removing a Cache

    Callbacks to listener methods are synchronous and unsynchronized. It is the responsibility
    of the implementer to safely handle the potential performance and thread safety issues
    depending on what their listener is doing.

    If no class is specified, no listener is created. There is no default.
    -->
    <cacheManagerEventListenerFactory class="" properties=""/>


    <!--
    CacheManagerPeerProvider
    ========================
    (Enable for distributed operation)

    Specifies a CacheManagerPeerProviderFactory which will be used to create a
    CacheManagerPeerProvider, which discovers other CacheManagers in the cluster.

    The attributes of cacheManagerPeerProviderFactory are:
    * class - a fully qualified factory class name
    * properties - comma separated properties having meaning only to the factory.

    Ehcache comes with a built-in RMI-based distribution system with two means of discovery of
    CacheManager peers participating in the cluster:
    * automatic, using a multicast group. This one automatically discovers peers and detects
      changes such as peers entering and leaving the group
    * manual, using manual rmiURL configuration. A hardcoded list of peers is provided at
      configuration time.

    Configuring Automatic Discovery:
    Automatic discovery is configured as per the following example:
    <cacheManagerPeerProviderFactory
                        class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
                        properties="peerDiscovery=automatic, multicastGroupAddress=230.0.0.1,
                                    multicastGroupPort=4446, timeToLive=32"/>

    Valid properties are:
    * peerDiscovery (mandatory) - specify "automatic"
    * multicastGroupAddress (mandatory) - specify a valid multicast group address
    * multicastGroupPort (mandatory) - specify a dedicated port for the multicast heartbeat
      traffic
    * timeToLive - specify a value between 0 and 255 which determines how far the packets will
      propagate.

      By convention, the restrictions are:
      0   - the same host
      1   - the same subnet
      32  - the same site
      64  - the same region
      128 - the same continent
      255 - unrestricted

    Configuring Manual Discovery:
    Manual discovery is configured as per the following example:
    <cacheManagerPeerProviderFactory class=
                          "net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
                          properties="peerDiscovery=manual,
                          rmiUrls=//server1:40000/sampleCache1|//server2:40000/sampleCache1
                          | //server1:40000/sampleCache2|//server2:40000/sampleCache2"
                          propertySeparator="," />

    Valid properties are:
    * peerDiscovery (mandatory) - specify "manual"
    * rmiUrls (mandatory) - specify a pipe separated list of rmiUrls, in the form
                            //hostname:port

    The hostname is the hostname of the remote CacheManager peer. The port is the listening
    port of the RMICacheManagerPeerListener of the remote CacheManager peer.

    -->
    <cacheManagerPeerProviderFactory
            class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
            properties="peerDiscovery=automatic,
                        multicastGroupAddress=230.0.0.1,
                        multicastGroupPort=4446, timeToLive=1"
            propertySeparator=","
            />


    <!--
    CacheManagerPeerListener
    ========================
    (Enable for distributed operation)

    Specifies a CacheManagerPeerListenerFactory which will be used to create a
    CacheManagerPeerListener, which
    listens for messages from cache replicators participating in the cluster.

    The attributes of cacheManagerPeerListenerFactory are:
    class - a fully qualified factory class name
    properties - comma separated properties having meaning only to the factory.

    Ehcache comes with a built-in RMI-based distribution system. The listener component is
    RMICacheManagerPeerListener which is configured using
    RMICacheManagerPeerListenerFactory. It is configured as per the following example:

    <cacheManagerPeerListenerFactory
        class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
        properties="hostName=fully_qualified_hostname_or_ip,
                    port=40001,
                    socketTimeoutMillis=120000"
                    propertySeparator="," />

    All properties are optional. They are:
    * hostName - the hostName of the host the listener is running on. Specify
      where the host is multihomed and you want to control the interface over which cluster
      messages are received. Defaults to the host name of the default interface if not
      specified.
    * port - the port the listener listens on. This defaults to a free port if not specified.
    * socketTimeoutMillis - the number of ms client sockets will stay open when sending
      messages to the listener. This should be long enough for the slowest message.
      If not specified it defaults 120000ms.

    -->
    <cacheManagerPeerListenerFactory
            class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"/>


    <!--
    Cache configuration
    ===================

    The following attributes are required.

    name:
    Sets the name of the cache. This is used to identify the cache. It must be unique.

    maxElementsInMemory:
    Sets the maximum number of objects that will be created in memory

        maxElementsOnDisk:
    Sets the maximum number of objects that will be maintained in the DiskStore
        The default value is zero, meaning unlimited.

    eternal:
    Sets whether elements are eternal. If eternal,  timeouts are ignored and the
    element is never expired.

    overflowToDisk:
    Sets whether elements can overflow to disk when the memory store
    has reached the maxInMemory limit.

    The following attributes and elements are optional.

    timeToIdleSeconds:
    Sets the time to idle for an element before it expires.
    i.e. The maximum amount of time between accesses before an element expires
    Is only used if the element is not eternal.
    Optional attribute. A value of 0 means that an Element can idle for infinity.
    The default value is 0.

    timeToLiveSeconds:
    Sets the time to live for an element before it expires.
    i.e. The maximum time between creation time and when an element expires.
    Is only used if the element is not eternal.
    Optional attribute. A value of 0 means that and Element can live for infinity.
    The default value is 0.

    diskPersistent:
    Whether the disk store persists between restarts of the Virtual Machine.
    The default value is false.

    diskExpiryThreadIntervalSeconds:
    The number of seconds between runs of the disk expiry thread. The default value
    is 120 seconds.

    diskSpoolBufferSizeMB:
    This is the size to allocate the DiskStore for a spool buffer. Writes are made
    to this area and then asynchronously written to disk. The default size is 30MB.
    Each spool buffer is used only by its cache. If you get OutOfMemory errors consider
    lowering this value. To improve DiskStore performance consider increasing it. Trace level
    logging in the DiskStore will show if put back ups are occurring.

    memoryStoreEvictionPolicy:
    Policy would be enforced upon reaching the maxElementsInMemory limit. Default
    policy is Least Recently Used (specified as LRU). Other policies available -
    First In First Out (specified as FIFO) and Less Frequently Used
    (specified as LFU)

    Cache elements can also contain sub elements which take the same format of a factory class
    and properties. Defined sub-elements are:

    * cacheEventListenerFactory - Enables registration of listeners for cache events, such as
      put, remove, update, and expire.

    * bootstrapCacheLoaderFactory - Specifies a BootstrapCacheLoader, which is called by a
      cache on initialisation to prepopulate itself.

    * cacheExtensionFactory - Specifies a CacheExtension, a generic mechansim to tie a class
      which holds a reference to a cache to the cache lifecycle.

    * cacheExceptionHandlerFactory - Specifies a CacheExceptionHandler, which is called when
      cache exceptions occur.

    * cacheLoaderFactory - Specifies a CacheLoader, which can be used both asynchronously and
      synchronously to load objects into a cache.

    RMI Cache Replication

    Each cache that will be distributed needs to set a cache event listener which replicates
    messages to the other CacheManager peers. For the built-in RMI implementation this is done
    by adding a cacheEventListenerFactory element of type RMICacheReplicatorFactory to each
    distributed cache's configuration as per the following example:

    <cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
         properties="replicateAsynchronously=true,
         replicatePuts=true,
         replicateUpdates=true,
         replicateUpdatesViaCopy=true,
         replicateRemovals=true
         asynchronousReplicationIntervalMillis=<number of milliseconds"
         propertySeparator="," />

    The RMICacheReplicatorFactory recognises the following properties:

    * replicatePuts=true|false - whether new elements placed in a cache are
      replicated to others. Defaults to true.

    * replicateUpdates=true|false - whether new elements which override an
      element already existing with the same key are replicated. Defaults to true.

    * replicateRemovals=true - whether element removals are replicated. Defaults to true.

    * replicateAsynchronously=true | false - whether replications are
      asynchronous (true) or synchronous (false). Defaults to true.

    * replicateUpdatesViaCopy=true | false - whether the new elements are
      copied to other caches (true), or whether a remove message is sent. Defaults to true.

    * asynchronousReplicationIntervalMillis=<number of milliseconds> - The asynchronous
      replicator runs at a set interval of milliseconds. The default is 1000. The minimum
      is 10. This property is only applicable if replicateAsynchronously=true


    Cluster Bootstrapping

    The RMIBootstrapCacheLoader bootstraps caches in clusters where RMICacheReplicators are
    used. It is configured as per the following example:

    <bootstrapCacheLoaderFactory
        class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory"
        properties="bootstrapAsynchronously=true, maximumChunkSizeBytes=5000000"
        propertySeparator="," />

    The RMIBootstrapCacheLoaderFactory recognises the following optional properties:

    * bootstrapAsynchronously=true|false - whether the bootstrap happens in the background
      after the cache has started. If false, bootstrapping must complete before the cache is
      made available. The default value is true.

    * maximumChunkSizeBytes=<integer> - Caches can potentially be very large, larger than the
      memory limits of the VM. This property allows the bootstraper to fetched elements in
      chunks. The default chunk size is 5000000 (5MB).


    Cache Exception Handling

    By default, most cache operations will propagate a runtime CacheException on failure. An
    interceptor, using a dynamic proxy, may be configured so that a CacheExceptionHandler can
    be configured to intercept Exceptions. Errors are not intercepted.

    It is configured as per the following example:

      <cacheExceptionHandlerFactory class="com.example.ExampleExceptionHandlerFactory"
                                      properties="logLevel=FINE"/>

    Caches with ExceptionHandling configured are not of type Cache, but are of type Ehcache only,
    and are not available using CacheManager.getCache(), but using CacheManager.getEhcache().


    Cache Loader

    A default CacheLoader may be set which loads objects into the cache through asynchronous and
    synchronous methods on Cache. This is different to the bootstrap cache loader, which is used
    only in distributed caching.

    It is configured as per the following example:

        <cacheLoaderFactory class="com.example.ExampleCacheLoaderFactory"
                                      properties="type=int,startCounter=10"/>

    Cache Extension

    CacheExtensions are a general purpose mechanism to allow generic extensions to a Cache.
    CacheExtensions are tied into the Cache lifecycle.

    CacheExtensions are created using the CacheExtensionFactory which has a
    <code>createCacheCacheExtension()</code> method which takes as a parameter a
    Cache and properties. It can thus call back into any public method on Cache, including, of
    course, the load methods.

    Extensions are added as per the following example:

         <cacheExtensionFactory class="com.example.FileWatchingCacheRefresherExtensionFactory"
                             properties="refreshIntervalMillis=18000, loaderTimeout=3000,
                                         flushPeriod=whatever, someOtherProperty=someValue ..."/>

    -->


    <!--
    Mandatory Default Cache configuration. These settings will be applied to caches
    created programmtically using CacheManager.add(String cacheName).

    The defaultCache has an implicit name "default" which is a reserved cache name.
    -->
    <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            overflowToDisk="true"
            diskSpoolBufferSizeMB="30"
            maxElementsOnDisk="10000000"
            diskPersistent="false"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU"
            />

    <!--
    Sample caches. Following are some example caches. Remove these before use.
    -->

    <!--
    Sample cache named sampleCache1
    This cache contains a maximum in memory of 10000 elements, and will expire
    an element if it is idle for more than 5 minutes and lives for more than
    10 minutes.

    If there are more than 10000 elements it will overflow to the
    disk cache, which in this configuration will go to wherever java.io.tmp is
    defined on your system. On a standard Linux system this will be /tmp"
    -->
    <cache name="sampleCache1"
           maxElementsInMemory="10000"
           maxElementsOnDisk="1000"
           eternal="false"
           overflowToDisk="true"
           diskSpoolBufferSizeMB="20"
           timeToIdleSeconds="300"
           timeToLiveSeconds="600"
           memoryStoreEvictionPolicy="LFU"
            />


    <!--
    Sample cache named sampleCache2
    This cache has a maximum of 1000 elements in memory. There is no overflow to disk, so 1000
    is also the maximum cache size. Note that when a cache is eternal, timeToLive and
    timeToIdle are not used and do not need to be specified.
    -->
    <cache name="sampleCache2"
           maxElementsInMemory="1000"
           eternal="true"
           overflowToDisk="false"
           memoryStoreEvictionPolicy="FIFO"
            />


    <!--
    Sample cache named sampleCache3. This cache overflows to disk. The disk store is
    persistent between cache and VM restarts. The disk expiry thread interval is set to 10
    minutes, overriding the default of 2 minutes.
    -->
    <cache name="sampleCache3"
           maxElementsInMemory="500"
           eternal="false"
           overflowToDisk="true"
           timeToIdleSeconds="300"
           timeToLiveSeconds="600"
           diskPersistent="true"
           diskExpiryThreadIntervalSeconds="1"
           memoryStoreEvictionPolicy="LFU"
            />


    <!--
    Sample distributed cache named sampleDistributedCache1.
    This cache replicates using defaults.
    It also bootstraps from the cluster, using default properties.
    -->
    <cache name="sampleDistributedCache1"
           maxElementsInMemory="10"
           eternal="false"
           timeToIdleSeconds="100"
           timeToLiveSeconds="100"
           overflowToDisk="false">
        <cacheEventListenerFactory
                class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"/>
        <bootstrapCacheLoaderFactory
                class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory"/>
    </cache>


    <!--
    Sample distributed cache named sampleDistributedCache2.
    This cache replicates using specific properties.
    It only replicates updates and does so synchronously via copy
    -->
    <cache name="sampleDistributedCache2"
           maxElementsInMemory="10"
           eternal="false"
           timeToIdleSeconds="100"
           timeToLiveSeconds="100"
           overflowToDisk="false">
        <cacheEventListenerFactory
                class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
                properties="replicateAsynchronously=false, replicatePuts=false,
                            replicateUpdates=true, replicateUpdatesViaCopy=true,
                            replicateRemovals=false"/>
    </cache>

    <!--
    Sample distributed cache named sampleDistributedCache3.
    This cache replicates using defaults except that the asynchronous replication
    interval is set to 200ms.
    -->
    <cache name="sampleDistributedCache3"
           maxElementsInMemory="10"
           eternal="false"
           timeToIdleSeconds="100"
           timeToLiveSeconds="100"
           overflowToDisk="false">
        <cacheEventListenerFactory
                class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
                properties="asynchronousReplicationIntervalMillis=200"/>
    </cache>




</ehcache>

7 Storage OptionsContents

Ehcache has two stores:

7.1 Memory StoreContents

The MemoryStore is always enabled. It is not directly manipulated, but is a component of every cache.

7.1.1 Memory Use, Spooling and Expiry StrategyContents

All caches specify their maximum in-memory size, in terms of the number of elements, at configuration time.

When an element is added to a cache and it goes beyond its maximum memory size, an existing element is either deleted, if overflowToDisk is false, or evaluated for spooling to disk, if overflowToDisk is true. In the latter case, a check for expiry is carried out. If it is expired it is deleted; if not it is spooled. The eviction of an item from the memory store is based on the MemoryStoreEvictionPolicy setting specified in the configuration file.

memoryStoreEvictionPolicy is an optional attribute in ehcache.xml introduced since 1.2. Legal values are LRU (default), LFU and FIFO.

LRU, LFU and FIFO eviction policies are supported. LRU is the default, consistent with all earlier releases of ehcache.

7.2 DiskStoreContents

The DiskStore provides a disk spooling facility.