Add caching.adoc documenting the auto-configuration of Apache Geode or Pivotal GemFire as a caching provider in Spring's Cache Abstraction.

This commit is contained in:
John Blum
2018-06-22 02:27:50 -07:00
parent 23ccb41075
commit a2d3dea59b
2 changed files with 211 additions and 0 deletions

View File

@@ -0,0 +1,210 @@
[[geode-caching-provider]]
== Caching with Apache Geode or Pivotal GemFire
One of the easiest ways to get started using Apache Geode or Pivotal GemFire in your Spring Boot applications
is to use either Apache Geode or Pivotal GemFire as a {spring-framework-docs}/integration.html#cache-store-configuration[_caching provider_]
({spring-framework-docs}/integration.html#cache-store-configuration-gemfire[see also]) in {spring-framework-docs}/integration.html#cache[Spring's Cache Abstraction].
TIP: See the _Spring Data for Apache Geode Reference Guide_ for more details on the
{spring-data-geode-docs-html}/#apis:spring-cache-abstraction[support] and {spring-data-geode-docs-html}/#bootstrap-annotation-config-caching[configuration]
of Apache Geode or Pivotal GemFire as a _caching provider_ in _Spring's Cache Abstraction_.
Indeed, caching can be an effective software design pattern to avoid the cost of invoking a potentially,
expensive operation when, given the same input, the operation yields the same output every time. Make sure you
fully understanding the {spring-framework-docs}/integration.html#cache-strategies[concepts] behind _Spring's Cache Abstraction_
before you continue.
You can also refer to the relevant section on {spring-boot-docs-html}/#boot-features-caching[Caching]
in Spring Boot's Reference Guide. Spring Boot even provides _auto-configuration_ support for a few,
simple {spring-boot-docs-html}/#_supported_cache_providers[_caching providers_] out-of-the-box.
However, if you need the proven power of an enterprise-class caching solution, with strong consistency,
high availability and multi-site (WAN) capabilities, then you should consider http://geode.apache.org/[Apache Geode]
or https://pivotal.io/pivotal-gemfire[Pivotal GemFire]. Additionally, https://pivotal.io/[Pivotal Software, Inc.]
offers Pivotal GemFire as a service, known as https://pivotal.io/platform/services-marketplace/data-management/pivotal-cloud-cache[Pivotal Cloud Cache (PCC)],
when deploying and running your Spring Boot applications in https://pivotal.io/platform[Pivotal Cloud Foundry (PCF)].
Spring's {spring-framework-docs}/integration.html#cache-annotations[declarative, annotation-based caching] makes it easy
to get started with caching, which is as simple as annotating your application service components with
the appropriate annotation.
TIP: Spring's declarative, annotation-based caching also {spring-framework-docs}/integration.html#cache-jsr-107[supports]
JCache (JSR-107) annotations.
For example, suppose you want to cache the result for determining a person's eligibility when applying for a loan:
[source,java]
----
@Service
class LoanApplicationService {
@Cacheable("EligibilityDecisions", ...)
EligibilityDecision processEligility(Person person, TimeSpan timeSpan) {
...
}
}
----
When the `LoanApplicationService.processEligibility(..)` method is called, Spring's caching infrastructure first consults
the "`EligibilityDecisions`" cache to determine if a decision has already been computed for the given `Person`
within the given span of time. If eligibility has already been determined, the the existing decision is returned
from the cache, otherwise the `processEligibility(..)` method is invoked and the result is cached on return.
Spring Boot for Apache Geode/Pivotal GemFire _auto-configures_ Apache Geode or Pivotal GemFire as the _caching provider_
when either one is declared on the application classpath, and when no other _caching provider_ (e.g. Redis)
has been configured.
If Spring Boot for Apache Geode/Pivotal GemFire detects that another _cache provider_ has already been configured,
then neither Apache Geode nor Pivotal GemFire will serve as the _caching provider_. This allows users to configure,
e.g. Redis, or another store, as the _caching provider_, and to use Apache Geode or Pivotal GemFire
as your application's persistent store.
To configure the necessary cache Regions to back the caches declared in Spring cache annotations, this is as simple as
using Spring Data for Apache Geode/Pivotal GemFire's
{spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableCachingDefinedRegions.html[`@EnableCachingDefinedRegions`] annotation.
The complete Spring Boot application looks like this:
[source,java]
----
package example.app;
import ...;
@SpringBootApplication
@EnableCachingDefinedRegions
class LoanApplication {
public static void main(String[] args) {
SpringApplication.run(LoanApplication.class, args);
}
}
----
TIP: The `LoanApplicationService` is picked up by Spring's classpath component scan since this class is annotated
with Spring's `@Service` stereotype annotation.
[[geode-caching-provider-look-aside-near-inline]]
=== Look-Aside Caching, Near Caching and Inline Caching
==== Look-Aside Caching
The caching pattern we demonstrated in the example above is a form of
https://content.pivotal.io/blog/an-introduction-to-look-aside-vs-inline-caching-patterns[Look-Aside Caching].
Essentially, the item of interests is searched for in the cache first, before computing a potentially expensive
operation, such a IO or network bound request resulting in either a blocking, or latency intensive operation.
If the item can be found in the cache (usually, in-memory) then the item is returned without invoking
the expensive operation. If the item cannot be found in the cache, then the operation must be invoked. However,
the result of the operation is cached for subsequent requests given the same input.
==== Near Caching
_Near Caching_ is another form of caching where the cache is collocated with the application. This is useful when
the cache is configured using a client/server arrangement.
We already mentioned that Spring Boot for Apache Geode & Pivotal GemFire <<clientcache-applications.adoc#geode-clientcache-applications, provides>>
an _auto-configured_, `ClientCache` instance out-of-the-box, by default. The `ClientCache` instance is most effective
when the data access operations, including cache access, is distributed to the servers in a cluster accessed
by the client. This enable other cache client applications to access the same data. However, this also means that
the application incurs a network hop penalty to evaluate the presence of the item in the cache.
To help avoid this network cost in a client/server topology, then a local application cache can be established
to maintain a subset of the data in the corresponding server-side cache (known as a cache Region in GemFire/Geode)
containing only the data of interests to the application. This "local" cache is consulted before forwarding
the lookup request to the server.
Enabling _Near Caching_ when using either Apache Geode or Pivotal GemFire is as simple as changing the Region's
(a.k.a. cache) data management policy from `PROXY` (the default) to `CACHING_PROXY`, like so:
[source,java]
----
@SpringBootApplication
@EnableCachingDefinedRegions(clientRegionShortcut = ClientRegionShortcut.CACHING_PROXY)
class LoanApplication {
public static void main(String[] args) {
SpringApplication.run(LoanApplication.class, args);
}
}
----
TIP: The default, client Region data management policy is
{apache-geode-javadoc}/org/apache/geode/cache/client/ClientRegionShortcut.html#PROXY[`ClientRegionShortcut.PROXY`].
As such, ion data access operations are forwarded immediately to the server.
==== Inline Caching
The final form of caching is _Inline Caching_.
_Inline Caching_ is like _Look-Aside Caching_, but when a cache miss occurs, the application service method may still
not get invoked since the cache (Region) is configured to invoke a loader to potentially load the missing entry.
In Apache Geode and Pivotal GemFire, the cache, or in GemFire/Geode terminology, the Region, can be configured with
a {apache-geode-javadoc}/org/apache/geode/cache/CacheLoader.html[CacheLoader]. This `CacheLoader` is implemented
to retrieve the missing value from some external data source, which could be a RDBMS or any other type of data source.
TIP: See the Apache Geode User Guide on {apache-geode-docs}/developing/outside_data_sources/how_data_loaders_work.html[Data Loaders]
for more details.
You can use Spring to configure a `CacheLoader` as a bean in the Spring context and then wire it to the cache Region.
Given the `CacheLoader` is a Spring bean, you can inject any `DataSource` you like into the `CacheLoader`.
While you can configure client Regions with `CacheLoaders`, it is more common to configure the corresponding
server-side Region; for example:
[source,java]
----
@SpringBootApplication
@CacheServerApplication
class LoanApplicationServer {
@Bean("EligibilityDecisions")
public PartitionedRegionFactoryBean<Object, Object> eligibilityDecisionsRegion(
GemFireCache gemfireCache, CacheLoader decisionManagementSystemLoader) {
PartitionedRegionFactoryBean<?, EligibilityDecision> eligibilityDecisionsRegion =
new PartitionedRegionFactoryBean<>();
eligibilityDecisionsRegion.setCache(gemfireCache);
eligibilityDecisionsRegion.setCacheLoader(decisionManagementSystemLoader);
eligibilityDecisionsRegion.setClose(false);
eligibilityDecisionsRegion.setPersistent(false);
return eligibilityDecisionsRegion;
}
@Bean
public CacheLoader<?, EligibilityDecision> decisionManagementSystemLoader(
DataSource dataSource) {
return new DecisionManagementSystemLoader(dataSource);
}
}
----
If the configured `CacheLoader` still cannot resolve the value, the the cache lookup operation results in a miss
and the application service method will then be invoked.
[[geode-caching-provider-advanced-configuration]]
=== Advanced Caching Configuration
Both Apache Geode and Pivotal GemFire support additional caching capabilities to manage the entries stored in the cache.
As you can imagine, given the cache entries are stored in-memory, it becomes important to monitor and manage the
available memory wisely. After all, by default, both Apache Geode and Pivotal GemFire store data on the JVM Heap.
Several techniques can be employed to more effectively manage memory, such as using
{apache-geode-docs}/developing/eviction/chapter_overview.html[Eviction], possibly
{apache-geode-docs}/developing/storing_data_on_disk/chapter_overview.html[overflowing to disk],
configuring both entry _Idle-Timeout (TTI) as well as _Time-To-Live (TTL)_
{apache-geode-docs}/developing/expiration/chapter_overview.html[Expiration policies],
configuring {apache-geode-docs}/managing/region_compression.html[Compression],
and using {apache-geode-docs}/managing/heap_use/off_heap_management.html[Off-Heap], or main memory.
There are several other strategies that can be used as well, as described in
{apache-geode-docs}/managing/heap_use/heap_management.html[Managing Heap and Off-heap Memory].
This is well beyond the scope of this document, but know that Spring Data for Apache Geode & Pivotal GemFire
make all of these {spring-data-geode-docs-html}/#bootstrap-annotation-config-regions[configuration options] simple.

View File

@@ -106,3 +106,4 @@ As such, it would be pertinent to begin your Spring Boot education {spring-boot-
Finally, we arrive at Spring Boot for Apache Geode & Pivotal GemFire.
include::clientcache-applications.adoc[]
include::caching.adoc[]