Implementing Delta Propagation
By default, delta propagation is enabled in your distributed system. When enabled, delta propagation is used for objects that implement
org.apache.geode.Delta. You program the methods to store and extract delta information for your entries and to apply received delta information.
- Study your object types and expected application behavior to determine which regions can benefit from using delta propagation. Delta propagation does not improve performance for all data and data modification scenarios. See When to Avoid Delta Propagation.
- For each region where you are using delta propagation, choose whether to enable cloning using the delta propagation property
cloning-enabled. Cloning is disabled by default. See Delta Propagation Properties.
- If you do not enable cloning, review all associated listener code for dependencies on
EntryEvent.getOldValue. Without cloning, GemFire modifies the entry in place and so loses its reference to the old value. For delta events, the
getNewValueboth return the new value.
- For every class where you want delta propagation, implement
org.apache.geode.Deltaand update your methods to support delta propagation. Exactly how you do this depends on your application and object needs, but these steps describe the basic approach:
- If the class is a plain old Java object (POJO), wrap it for this implementation and update your code to work with the wrapper class.
- Define as transient any extra object fields that you use to manage delta state. This can help performance when the full object is distributed. Whenever standard Java serialization is used, the transient keyword indicates to Java to not serialize the field.
- Study the object contents to decide how to handle delta changes. Delta propagation has the same issues of distributed concurrency control as the distribution of full objects, but on a more detailed level. Some parts of your objects may be able to change independent of one another while others may always need to change together. Send deltas large enough to keep your data logically consistent. If, for example, field A and field B depend on each other, then your delta distributions should either update both fields or neither. As with regular updates, the fewer producers you have on a data region, the lower your likelihood of concurrency issues.
- In the application code that puts entries, put the fully populated object into the local cache. Even though you are planning to send only deltas, errors on the receiving end could cause GemFire to request the full object, so you must provide it to the originating put method. Do this even in empty producers, with regions configured for no local data storage. This usually means doing a get on the entry unless you are sure it does not already exist anywhere in the distributed region.
- Change each field’s update method to record information about the update. The information must be sufficient for
toDeltato encode the delta and any additional required delta information when it is invoked.
hasDeltato report on whether a delta is available.
toDeltato create a byte stream with the changes to the object and any other information
fromDeltawill need to apply the changes. Before returning from
toDelta, reset your delta state to indicate that there are no delta changes waiting to be sent.
fromDeltato decode the byte stream that
toDeltacreates and update the object.
- Make sure you provide adequate synchronization to your object to maintain a consistent object state. If you do not use cloning, you will probably need to synchronize on reads and writes to avoid reading partially written updates from the cache.This synchronization might involve
fromData, and other methods that access or update the object. Additionally, your implementation should take into account the possibility of concurrent invocations of
fromDeltaand one or more of the object’s update methods.