public class RemoteStore
extends java.lang.Object
implements java.io.Serializable
A remote store which is used to look for objects that are not found. Remote stores should be linked to a local store with "pull" mode selected.
GeoServer pull replication was introduced in version 5.0 of ScaleOut StateServer. Pull replication differs from push replication in that objects are transmitted across a WAN to remote datacenters as the objects are needed. Furthermore, the frequency that remote sites refresh their copies of an object can be adjusted by setting up a coherency policy that controls how out-of-date a replicated object may become before it's refreshed in a remote datacenter. A loose coherency policy can result in reduced bandwidth usage between sites when compared to push replication, since fewer updates are sent across the link between datacenters.
Version 5.10 of ScaleOut GeoServer® Pro introduces an extension to the notify coherency policy for pull replication across two ScaleOut StateServer stores that combines synchronized access to objects with push replication. This extension ensures that two copies of each object are always maintained, one in each store, while giving applications a single, coherent view of the object’s data. ScaleOut GeoServer Pro automatically handles WAN outages to ensure uninterrupted operations. (See the User Guide for more information.)
In version 5.10.5.350, the notify coherency policy can be configured with no code changes. You can do this through
the soss
command line utility.
For example, soss add_notify remoteStoreName,cacheName,0|1
.
The ``add_notify`` argument consists of three components separated
by commas without spaces:
remoteStoreName
the name of the remote store that is configured for GeoServer pull.
cacheName
the name of the cache which should create objects with "notify" coherency policy.
0|1
the 0 or 1 indicates whether or not the notify policy should override existing coherency policies.
If omitted, the value 0 (do not override existing policies) will be used.
Deletes performed on a remote, unlocked proxy of a replicated object will be pushed across the WAN back to the datacenter containing the master copy of the object. Unlocked updates performed on a local proxy of a replicated object automatically are not pushed across the WAN back to the remote SOSS store containing the master copy of the object. Note that unlocked updates should seldom be performed because the order of updates from multiple threads running at different sites generally cannot be predicted. Hence, updates could be lost if the application does not synchronize updates across multiple sites. Data for which loose coherency policies are appropriate usually are updated only at the master.
Ownership of an object can migrate from datacenter to
datacenter. The datacenter that contains the master copy of an object will
relinquish this ownership if an application in a remote datacenter acquires a
lock on a proxy
of the object (using either NamedCache.acquireLock()
or a locking
NameCache.retrieve()
call).
Because the mastership of an object can migrate from store to store, it is common for GeoServer pull replication to be configured in both directions (that is, Los Angeles would be configured to pull from New York, and New York would be configured to pull from Los Angeles). This allows the master copy of an object to migrate from datacenter to datacenter as needed. GeoServer can also manage pull replication across more than two sites - for example, if three datacenters are involved, then each site will need to be separately configured to pull from the other two. If the remote sites will not be locking any replicated objects then configuring bi-directional replication is not necessary, since the master copy of the object will always remain in the local site.
Bi-directional replication will also need to be configured in situations where the NotifyCoherencyPolicy is used to keep proxy objects synchronized.
Caching API UsageUsing GeoServer pull replication involves interacting with the caching APIs in both the originating and remote stores:
NamedCache.setRemoteStores()
method - this call tells the
ScaleOut server which remote stores it should contact to look for an object
whenever a retrieve request is made for an object that isn't present locally.The CreatePolicy
class is used to specify how the ScaleOut
server should treat an object that is being inserted in the distributed
store - it allows a client application to specify an object's timeout and
dependencies, among other properties. The CreatePolicy
class contains two new
properties to support GeoServer pull replication. When creating an object that
is to be made accessible to remote stores, the CreatePolicy
.allowRemoteAccess
property must be set to true
, and the CreatePolicy
.defaultCoherencyPolicy
property must be set to an implementation of CoherencyPolicy
.
NamedCache nc = CacheFactory.getCache("GeoServer pull sample"); CreatePolicy policy = new CreatePolicy(); policy.setAllowRemoteAccess(true); // remotes sites should poll the master object every 30 seconds for updates: policy.setDefaultCoherencyPolicy(new PollingCoherencyPolicy(TimeSpan.fromSeconds(30))); nc.insert("key1", "Object value 1", policy, true, false);
There are currently two supported implementations of
CoherencyPolicy
available for use that may be assigned to the
DefaultCoherencyPolicy
property:
Please note that the CoherencyPolicy
interface exists to
support the ScaleOut API infrastructure, so application developers should not
create their own custom implementations of CoherencyPolicy
.
To configure replication for all objects created in a
NamedCache, the allowRemoteAccess
and defaultCoherencyPolicy
properties can be configured on NamedCache.setDefaultCreatePolicy()
.
NamedCache nc = CacheFactory.getCache("GeoServer pull sample"); CreatePolicy cp = nc.getDefaultCreatePolicy(); cp.setAllowRemoteAccess(true); cp.setDefaultCoherencyPolicy(new PollingCoherencyPolicy(TimeSpan.fromSeconds(30))); nc.add("key2", "Object value 2");Reading an Object from a Remote Store Preparing the NamedCache
Once an object has been created with a coherency policy and
is marked to allow remote access from the originating store, the object becomes
available for reading and updating by remote stores. Client applications that
need to remotely access a master object must first call the NamedCache.setRemoteStores()
method and pass in a list of remote store names. This list of
names specifies the search order that will be used when a read operation is
performed and the requested key is not found in the store.
NamedCache nc = CacheFactory.getCache("GeoServer pull sample"); List remStores = new LinkedList <RemoteStore >(); remStores.add(new RemoteStore("LosAngeles")); remStores.add(new RemoteStore("Paris")); nc.setRemoteStores(remStores);
Note that the store names specified in the collection must match the names in the GeoServer configuration. Naming of stores must be consistent across datacenters when specifying local store names and remote store names in the SOSS Console and in API calls. In other words, do not call a store "LosAngeles" in one datacenter and then name it "LA" in another.
Passing null
or an empty collection into a NamedCache.setRemoteStores()
call will disable pull replication for that instance of the NamedCache.
Once the search order has been set using NamedCache.setRemoteStores()
,
the SOSS service will check the specified stores for objects when reads are
performed on keys that are not present in the local store. The local store will
go through the specified remote store collection and contact each store in turn
until it is able to locate the desired object. If none of the stores contain
the object then the retrieve call will return null
, indicating that the object
cannot be found.
Once a remote store retrieves an object remotely, the remote store creates a local proxy copy of the object and then returns the proxy value to the calling application. The proxy copy is refreshed according to the coherency policy that was set up on the master object when it was originally created.
Performing the RetrievalIf an object is not present in the store, the NamedCache.retrieve()
method (or a call to NamedCache.getMetadata()
)
will contact remotes stores in order to locate the requested object and create a local proxy
of the object for subsequent calls. Behavior of the client APIs can be adjusted
on a call-by-call basis when reading from proxies of a replicated remote
object.
The ReadOptions parameter that is passed into a retrieve call has a GeoServerReadMode property that controls API behavior when reading replicated objects. This enumeration presents four options:
// Configure access to any remote stores. This step is typically // performed once at application startup: NamedCache nc = CacheFactory.getCache("GeoServer pull sample"); List remStores = new LinkedList <RemoteStore >(); remStores.add(new RemoteStore("LosAngeles")); nc.setRemoteStores(remStores); // Set up options for retrieval. We want to get the value back from the // proxy of the object, if there's one stored locally: ReadOptions options = new ReadOptions(ReadLockingMode.NoLockOnRead, GeoServerReadMode.LocalDoNotThrowOnStaleData); // Perform the retrieval: Object myObj = nc.retrieve("key1", options);
The NamedCache.getMetadata()
call also has an overload that takes
a ReadOptions argument. A NamedCache.getMetadata()
call behaves in exactly the
same was as a normal retrieve call and will result in the local store
contacting remote stores for missing objects and the creation of local proxy
objects.
ReadOptions options = new ReadOptions(ReadLockingMode.NoLockOnRead, GeoServerReadMode.LocalDoNotThrowOnStaleData); // Perform the GetMetadata call: nc.getMetadata("key1", options);
The GeoServerReadMode option can also be configured for all read
calls that are performed by an instance of the NamedCache. Read operations that
do not take a ReadOptions parameter will default to the
behavior specified by the NamedCache defaultGeoServerReadMode property
. This
property defaults to LocalDoNotThrowOnStaleData
.
NamedCache nc = CacheFactory.getCache("GeoServer pull sample"); List remStores = new LinkedList <RemoteStore >(); remStores.add(new RemoteStore("LosAngeles")); nc.setRemoteStores(remStores); // Specify that all read calls should default to forcing remote reads, // unless specified otherwise on a call-by-call basis: nc.setDefaultGeoServerReadMode(GeoServerReadMode.Remote); // Using get() call will honor the defaultGeoServerReadMode // property set above, so we force a remote read with this call instead of hitting // the local proxy: String myObj1 = (String) nc.get("key1"); // We can still override the DefaultGeoServerReadMode on a call-by-call basis // by passing explicit options into a Retrieve or GetMetadata call: ReadOptions options = new ReadOptions(ReadLockingMode.NoLockOnRead, GeoServerReadMode.LocalDoNotThrowOnStaleData); String myObj2 = (String) nc.retrieve("key2", options);Locking and Updating an Object from a Remote Store
Locking an object in ScaleOut StateServer is a common operation that can be performed when a thread in a client application needs to acquire exclusive access to an object in the SOSS server. ScaleOut StateServer supports distributed locks, so when an application acquires a lock on an object, no other application code - regardless of whether it's running in a different thread, process, or machine - will be allowed to acquire a lock on that same object.
ScaleOut GeoServer's pull replication architecture extends the distributed locking model to span datacenters, allowing a single thread on a single machine to acquire a lock so that no other client code across a globally distributed network of caches will be allowed to acquire a lock on that same object.
Pull replication achieves this global locking behavior by allowing
the master copy of an object to migrate from store to store. Locking an object
using the NamedCache.acquireLock
method (or performing a retrieve call with the
lockOnRead
parameter set) from a remote store will cause
the originating store to relinquish control of the master copy of the object,
and the remote store will assume the mastership, at which point the lock will
be acquired for the caller.
Applications that use locking in conjunction with pull replication must take care to establish bi-directional replication when configuring GeoServer - all stores involved in replication must have the ability to pull in an object and take over its mastership in order to perform locking.
Locking of an object is typically performed in conjunction with an update operation - applications lock objects to ensure that no other clients/threads change the object before an update is performed. Not all usage models require locking prior to updates, however. If an update is performed remotely on an unlocked object then the mastership of the object will remain in the originating store. The remote update will push the new value back across the WAN link to the master copy.
Constructor and Description |
---|
RemoteStore(java.lang.String storeName)
Creates an object referencing remote store.
|
Modifier and Type | Method and Description |
---|---|
java.lang.String |
getStoreName()
Gets remote store name.
|