net.sf.ehcache.distribution |
This package is for cache replication.
Overview
Problems with Instance Caches in a Clustered Environment
Many production applications are deployed in clusters. If each application maintains its own cache, then updates
made to one cache will not appear in the others. A workaround for web based applications is to use sticky sessions,
so that a user, having established a session on one server, stays on that server for the rest of the session. A
workaround for transaction processing systems using Hibernate is to do a session.refresh on each persistent object
as part of the save. session.refresh explicitly reloads the object from the database, ignoring any cache values.
Replicated Cache
Another solution is to replicate data between the caches to keep them consistent. This is sometimes called cache
coherency. Applicable operations include:
- put
- update (put which overwrites an existing entry)
- remove
Replicated Cache Terms
Replicated Cache - a cache instance that notifies others when its contents change
Notification - a mechanism to replicate changes
Topology - a layout for how replicated caches connect with and notify each other
Notification Strategies
The best way of notifying of put and update depends on the nature of the cache.
If the Element is not available
anywhere else then the Element itself should form the payload of the notification. An example is a cached web page.
This notification strategy is called copy.
Where the cached data is available in a database, there are two choices. Copy as before, or invalidate the data. By
invalidating the data, the application tied to the other cache instance will be forced to refresh its cache from the
database, preserving cache coherency. Only the Element key needs to be passed over the network.
ehcache supports notification through copy and invalidate, selectable per cache.
Topology Choices
Peer Cache Replicator
Each replicated cache instance notifies every other cache instance when its contents change. This requires n-1
notifications per change, where n is the number of cache instances in the cluster.
Centralised Cache Replicator
Each replicated cache instance notifies a master cache instance when its contents change. The master cache then
notifies the other instances. This requires n-1
notifications per change, where n is the number of cache instances in the cluster.
ehcache uses a peer replication topology. It adds a twist with CachePeerProvider, an interface which supplies a list
of cache instance peers, so as to handle peers entering and leaving the cluster. Some ideas for peer provider
implementations are: configuration time list, multicast discovery, application specific cluster list.
Replication Drawbacks and Solutions in ehcache's implementation
Some potentially significant obstacles have to be overcome if replication is to provide a net benefit.
Chatty Protocol
n-1 notifications need to happen each time a a cache instance change occurs. A very large amount of network traffic
can be generated.
ehcache will buffer changes to lower chattiness.
Redundant Notifications
The cache instance that initiated the change should not receive its own notifications. To do so would add additional
overhead. Also, notifications should not endlessly go back and forth as each cache listener gets changes caused by
a remote replication.
ehcache CachePeerProvider indentifies the local cache instance and excludes it from the notification list. Each Cache
has a GUID. That GUID can be compared with list of cache peers and the local peer excluded.
Infinite notifications are prevented by having each CacheReplicatorListener call putQuiet and removeQuite methods
on their decorated caches, so as not to nofify listeners.
Potential for Inconsisent Data
Timing scenarios, race conditions, delivery and reliability constraints, and concurrent updates to the same cached
data can cause inconsistency (and thus a lack of coherency) across the cache instancies.
Acknowledgement: Much of the material here was drawn from Data Access Patterns, by Clifton Nock.
|
Java Source File Name | Type | Comment |
CacheManagerPeerListener.java | Interface | A listener for updates, which controls remote cache peers. |
CacheManagerPeerListenerFactory.java | Class | An abstract factory for creating cache manager peer listeners. |
CacheManagerPeerProvider.java | Interface | Provides a discovery service to locate
CachePeer RMI listener peers for a Cache. |
CacheManagerPeerProviderFactory.java | Class | An abstract factory for creating peers. |
CachePeer.java | Interface | An interface for a cache peer to which updates are made remotely. |
CacheReplicator.java | Interface | |
ConfigurableRMIClientSocketFactory.java | Class | Default socket timeouts are unlikely to be suitable for cache replication. |
EventMessage.java | Class | An Event Message, in respect of a particular cache. |
EventMessageTest.java | Class | |
JVMUtil.java | Class | |
ManualRMICacheManagerPeerProvider.java | Class | A provider of Peer RMI addresses based off manual configuration. |
ManualRMIPeerProviderTest.java | Class | |
MulticastKeepaliveHeartbeatReceiver.java | Class | Receives heartbeats from any
MulticastKeepaliveHeartbeatSender s out there. |
MulticastKeepaliveHeartbeatSender.java | Class | Sends heartbeats to a multicast group containing a compressed list of URLs. |
MulticastRMICacheManagerPeerProvider.java | Class | A peer provider which discovers peers using Multicast.
Hosts can be in three different levels of conformance with the Multicast specification (RFC1112), according to the requirements they meet.
- Level 0 is the "no support for IP Multicasting" level.
|
MulticastRMIPeerProviderTest.java | Class | Multicast tests. |
PayloadUtil.java | Class | This class provides utility methods for assembling and disassembling a heartbeat payload. |
PayloadUtilTest.java | Class | |
RemoteCacheException.java | Class | A Cache Exception in the distribution mechanism. |
RemoteDebugger.java | Class | A distributed testing tool for manual distributed testing of ehcache on cluster nodes. |
RMIAsynchronousCacheReplicator.java | Class | Listens to
net.sf.ehcache.CacheManager and
net.sf.ehcache.Cache events and propagates those to
CachePeer peers of the Cache asynchronously.
Updates are guaranteed to be replicated in the order in which they are received.
While much faster in operation than
RMISynchronousCacheReplicator , it does suffer from a number
of problems. |
RMIBootstrapCacheLoader.java | Class | |
RMIBootstrapCacheLoaderFactory.java | Class | |
RMIBootstrapCacheLoaderTest.java | Class | |
RMICacheManagerPeerListener.java | Class | A cache server which exposes available cache operations remotely through RMI.
It acts as a Decorator to a Cache. |
RMICacheManagerPeerListenerFactory.java | Class | Builds a listener based on RMI. |
RMICacheManagerPeerListenerTest.java | Class | |
RMICacheManagerPeerProvider.java | Class | A provider of Peer RMI addresses. |
RMICacheManagerPeerProviderFactory.java | Class | |
RMICacheManagerPeerTest.java | Class | |
RMICachePeer.java | Class | An RMI based implementation of CachePeer . |
RMICacheReplicatorFactory.java | Class | Creates an RMICacheReplicator using properties. |
RMICacheReplicatorTest.java | Class | Tests replication of Cache events
Note these tests need a live network interface running in multicast mode to work
If running involving RMIAsynchronousCacheReplicator individually the test will fail because
the VM will gobble up the SoftReferences rather than allocating more memory. |
RMIDistributedCacheTest.java | Class | |
RMISynchronousCacheReplicator.java | Class | Listens to
net.sf.ehcache.CacheManager and
net.sf.ehcache.Cache events and propagates those to
CachePeer peers of the Cache. |