 | This documentation applies to the Push Replication Pattern 2.1.1. The latest Push Replication Pattern documentation is available here. |
The Push Replication Pattern
This is an example implementation of Push Replication between two or more Coherence data grids.
The Push Replication Pattern advocates that;
- Operations (such as insert, update and delete) occurring on Data in one Location should be pushed to one or more Devices, each Device being capable of optimistically replicating the said Operations (in the order in which the said Operations originally occurred) in another Receiving Location.
- If a Receiving Location is unavailable or uncontactable for some reason, the Operations to be replicated at the said Location will be queued and executed (in the original order) at a later point in time.
This implementation of the Push Replication Pattern additionally advocates that;
- The Data on which Operations occur are standard Coherence Cache Entries.
- The Operations are called EntryOperations.
- A Location is a Coherence Cluster.
- A Location may act as both a sender of Operations and receiver of Operations. That is, multi-way multi-location push replication is permitted.
- A Device is a class that implements the BatchPublisher interface.
|
Outline
Rationale
The purpose of this pattern is to provide extensible, flexible, high-performance, highly-available and scalable infrastructure to support the replication of EntryOperations occurring in one Coherence Cluster to one or more possibly globally distributed other Coherence Clusters.
While this naturally forms a "hub-and-spoke" architecture of federated Coherence Clusters, by configuring each Coherence Cluster as a "hub" and a "spoke", multi-way push replication may be achieved. |
Implementation Discussion
 | Before you start
The Push Replication Pattern makes extensive use of the Store and Forward Messaging Pattern as infrastructure to capture EntryOperations and deliver them in-order of occurrence to BatchPublishers. Consequently it is advised that you make yourself familiar with the Store and Forward Messaging Pattern (and it's implementation) to understand the implementation of this pattern. |
The Push Replication Pattern is an extension of the Store and Forward Messaging Pattern. The implementation provides several new Coherence CacheStore implementations, namely the PublishingCacheStore (for "hub-and-spoke" push replication) and the SafePublishingCacheStore (for "multi-way" push replication), that are used to capture cache mutation operations (like insert, update and delete) on cache entries.
After such operations are captured (represented as EntryOperations) they are sent to the messaging layer (implemented using the Store and Forward Messaging Pattern) for distribution to specialized TopicSubscriptions called PublishingSubscriptions.
When PublishingSubscriptions receive the EntryOperations from the messaging layer, an internal event (captured by a backing-map-listener executing in the same JVM in which the PublishingSubscription is being managed by Coherence) signals to a PublishingService to commence publishing the currently queued EntryOperations with a BatchPublisher implementation (provided by the said PublishingSubscription ). How the ultimate publishing occurs depends on the implementation of the BatchPublisher.
The following diagram provides an overview of the push replication process through the various layers of the system.

The following section provides an example use of the push replication pattern, including establishing publishers.
Example
Step 1: Configuring a Cache (with a PublishingCacheStore)
As push replication occurs on a cache-by-cache basis, the first step in making use of this pattern is configuring your application cache(s) to use an appropriate PublishingCacheStore implementation. For the "hub-and-spoke" model, where one cluster is a "master" and the other clusters are "spokes", you should use a PublishingCacheStore. For multi-way push replication, your cache(s) should be configured to use a SafePublishingCacheStore.
By default, the Push Replication cache configuration (coherence-pushreplicationpattern-[pof-]cache-config.xml) defines a "publishing-*" mapping to a distributed-scheme that is configured to use a PublishingCacheStore. Consequently any cache name prefixed with "publishing-" will automatically support Push Replication.
String cacheName = "publishing-cache";
NamedCache namedCache = CacheFactory.getCache(cacheName);
When your application first accesses a "publishing-*" based scheme (which in turn creates the PublishingCacheStore), the underlying messaging infrastructure will be created to support Push Replication. This includes establishing a Topic that is named exactly the same as your cache. In this case, a Topic called "publishing-cache" will be created in the messaging layer.
From here on any operation that mutates the "publishing-cache" will have the said operation captured and sent (as an EntryOperation) to the "publishing-cache" Topic, after which the operation will be forwarded in-order to the Subscriptions on the said Topic.
Step 2: Registering a BatchPublisher with a PublishingSubscription to perform Push Replication
Until a PublishingSubscription is registered on a Topic, no publishing will occur. To create a PublishingSubscription for a Topic we use the Store and Forward Messaging Pattern layer.
MessagingSession messagingSession = DefaultMessagingSession.getInstance();
PublishingSubscription publishingSubscription = new DefaultPublishingSubscription(cacheName, "my-publishing-subscription", new BatchPublisherAdapter(new StdErrPublisher(), 5000, 10)));
messagingSession.createTopicSubscription(publishingSubscription);
A standard implementation of a PublishingSubscription is provided by the DefaultPublishingSubscription class. The first parameter is the name of the cache (which is used for the Topic), the second is the name of the subscription (all subscriptions may have a unique identity) and the last parameter specifies the BatchPublisher implementation to use.
There are essentially two forms of publishers; those that support "batching" and those that don't. By default, the Push Replication pattern only works with BatchPublishers. Consequently to use a non-batching publisher (ie: an implementation of the Publisher interface), an adapter has been provided. The package com.oracle.coherence.pushreplication.publishers provides numerous implementations of Publishers and BatchPublishers together with adapters to convert between them.
Step 3: Using a publishing- cache.*
Once you've established appropriate PublishingSubscriptions for each cache on which you would like to Push Replicate, you may simply use the said cache(s) as regular caches (as they are!).
namedCache.put("australian-welcome", "Gudday");
namedCache.put("regular-welcome", "Hello");
namedCache.put("french-welcome", "Bonjour");
Frequently Asked Questions
How can the Push Replication be monitored on a subscription-by-subscription basis?
Like the Command Pattern and Store and Forward Messaging Patterns, this pattern is JMX ready. By simply enabling JMX on the Coherence Cluster, each of the PublishingServices will be presented in the JMX tree, detailing current replication state and statistics.
How do I enable Push Replication to one or more (remote) Coherence Clusters?
In order to publish to a remote cluster, you must;
- Configure and enable one or more proxies on the remote cluster(s).
- Ensure that the members of the remote cluster(s) have the Push Replication Pattern (and dependencies) in the class path
- Configure and enable one or more Remote Invocation Services in the "hub" with the addresses of the remote cluster proxy members (of it you're using Coherence 3.4+, use an AddressProvider). An example scheme is defined in the coherence-pushreplicationpattern-cache-config.xml file.
- Create appropriate RemoteInvocationPublisher subscriptions for each cache (as follows).
messagingSession.createTopicSubscription(
new DefaultPublishingSubscription(cacheName,
"my-remote-subscription",
new RemoteInvocationPublisher("RemoteSiteInvocationService",
new BatchPublisherAdapter(new CachePublisher(cacheName)),
10000, 100, 10000)));
How are conflicts resolved when replicating EntryOperations in remote clusters?
The current implementation assumes it is safe to perform optimistically perform all EntryOperations remotely. The next release of this pattern will demonstrate the use of a pluggable ConflictResolver that may be used to reconcile and resolve all conflicts.
References and Additional Information