Setting Up Servers for an Inline Cache

See The Inline Cache for an introductory description of an inline cache. The implementation of an inline cache requires custom code deployed on the GemFire servers to interact with the backend data store for read misses and for writes.

The custom code always implements a cache loader for read misses. The custom code and configuration setup differs for writes. A write-behind implementation uses an asynchronous event queue (AEQ) and an AEQ listener. A write-through implementation uses a cache writer.

Implement a Cache Loader for Read Misses

An app’s get operation is a cache read. If the desired entry is in the region, it is a cache hit, and the value is quickly returned to the app. If the desired entry is not in the region, it is a cache miss. For an inline cache, that value is acquired from the backend data store. You implement the CacheLoader interface to handle cache misses. Each cache miss invokes the CacheLoader.load method. The CacheLoader.load method must acquire and return the value for the specified key. See the Pivotal GemFire API Documentation for the interface’s details.

inline read misses

The value returned from the CacheLoader.load method will be put into the region and then returned to the waiting app, completing the app’s get operation. Since the app blocks while waiting for the result of the get operation, design the CacheLoader.load method to acquire the value as quickly as possible.

The CacheLoader implementation must be thread-safe. You will deploy the implementation to the servers during configuration.

The CacheLoader.load method queries the backend data store for the desired entry. That communication between the server process and the backend data store requires a connection, and establishing a connection is likely to use a set of credentials. You provide a custom implementation of the CacheLoader.initialize method to establish the connection.

You specify the credentials during configuration with the gfsh create region command by adding the JSON description to the --cache-loader option. The credentials will be passed as parameters to the invoked CacheLoader.initialize method as part of the CacheLoader instance construction.

Implement an Asynchronous Event Queue and Cache Listener for Write Behind

An app’s put operation is a cache write. For a write-behind implementation, the value is placed into the region, and it will also be asynchronously written to the backend data store, allowing the app’s write operation to complete without waiting for the backend-data-store write to complete.

An asynchronous event queue (AEQ) to queue the write events together with an implementation of the AsyncEventListener interface provides the desired behavior. See the Pivotal GemFire API Documentation for the interface’s details.

inline cache server interactions

With a configured AEQ, all put operations first create or update the entry in the hosted region on the server and then add the event to the AEQ.

You provide a custom implementation of the AsyncEventListener interface. Your AsyncEventListener.processEvents method’s task is to iterate through the events in the AEQ, writing each newly created or updated entry in the AEQ to the backend data store. The AsyncEventListener.processEvents method is invoked when either the AEQ holds a configured quantity of events, or a configured quantity of time has elapsed since the earliest entry entered the AEQ.

The communication between the server process and the backend data store to do the writes requires a connection, and establishing a connection is likely to use a set of credentials. You provide a custom implementation of the AsyncEventListener.initialize method to establish the connection.

You specify the credentials during configuration in the gfsh create async-event-queue command with the --listener-param option as described in Configure Using gfsh for Write Behind. The credentials will be passed as parameters to the invoked AsyncEventListener.initialize method as part of AsyncEventListener instance construction.

Your configuration will specify the AEQ as persistent, such that it does not lose queued backend-data-store writes across unexpected server restarts.

Implement a Cache Writer for Write Through

An app’s put operation is a cache write. For a write-through implementation, the value will be written to the backend data store prior to being placed into the region. After both writes, the app’s put operation completes.

An implementation of the CacheWriter interface implementation provides the correct behavior for write through. See the Pivotal GemFire API Documentation for the interface’s details. You provide a custom implementation of the CacheWriter.beforeCreate method to handle backend-data-store writes for put operations that add a new entry to the region. You provide a custom implementation of the CacheWriter.beforeUpdate method to handle backend-data-store writes for put operations that modify an existing entry in the region. You provide a custom implementation of CacheWriter.beforeDestroy, as appropriate, to handle an update of the backend data store for a region operation that removes an entry.

The CacheWriter implementation must be thread-safe. You will deploy the implementation to the servers during configuration.

inline cache server interactions

Communication between the server process and the backend data store to do the writes requires a connection, and establishing a connection is likely to use a set of credentials. You provide a custom implementation of the CacheWriter.initialize method to establish the connection.

Specify the credentials in the gfsh create region command during configuration as described in Configure Using gfsh for Write Through. Add the JSON description to the --cache-writer option. The credentials will be passed as parameters to the invoked CacheWriter.initialize method as part of the CacheWriter instance construction.

Configure Using gfsh for Write Behind

Follow this procedure to deploy your custom implementations of the interfaces to the servers, create the AEQ, and configure the region to use the AEQ and the deployed interface implementations.

  1. Follow the directions in Connect with gfsh over HTTPS to connect to the cluster with a role that is able to manage both the cluster and the data.

  2. Deploy the cache loader and the AEQ listener code to the servers within the PCC service instance:

    gfsh>deploy --jars=/path/to/MyLoader.jar,/path/to/MyListener.jar
    
  3. Create the AEQ, assigning a name for the AEQ (called WB-AEQ in this example), specifying the AEQ listener, and specifying the AEQ listener’s parameters:

    gfsh>create async-event-queue --id=WB-AEQ \
      --parallel=true --persistent \
      --listener=com.myCompany.MyListener \
      --listener-param=url#jdbc:db2:SAMPLE,username#admin,password#gobbledeegook
    

    The persistence of the AEQ uses the default disk store, since no disk store is specified in this command.

  4. Create the region, specifying the cache loader, the AEQ listener, and the assigned AEQ name.

    gfsh>create region --name=myRegion --type=PARTITION_REDUNDANT \
      --cache-loader=com.myCompany.MyLoader{'url':'jdbc:db2:SAMPLE','username':'admin',password:'gobbledeegook'}
      --cache-listener=com.myCompany.MyListener
      --async-event-queue-id=WB-AEQ
    

Configure Using gfsh for Write Through

Follow this procedure to deploy your custom implementations of the interfaces to the servers, and configure the region to use the deployed interface implementations.

  1. Follow the directions in Connect with gfsh over HTTPS to connect to the cluster with a role that is able to manage both the cluster and the data.

  2. Deploy the cache loader and the cache writer code to the servers within the PCC service instance:

    gfsh>deploy --jars=/path/to/MyLoader.jar,/path/to/MyWriter.jar
    
  3. Create the region, specifying the cache loader and the cache writer:

    gfsh>create region --name=myRegion --type=PARTITION_REDUNDANT \
      --cache-loader=com.myCompany.MyLoader{'url':'jdbc:db2:SAMPLE','username':'admin',password:'gobbledeegook'}
      --cache-writer=com.myCompany.MyWriter{'url':'jdbc:db2:SAMPLE','username':'admin',password:'gobbledeegook'}