Ehcache 3

repository·master·Indexed 24 days ago

https://github.com/ehcache/ehcache3

Provides XML-based configuration capabilities for Ehcache 3 to define CacheManagers, caches, and reusable templates. Includes documentation for Terracotta components, including Docker images for the Terracotta Server, config-tool, and voter, as well as instructions for cluster activation, configuration management, and persistence.

Tokens
30.8K
Snippets
29
Records
168
Agent score
85%

What's inside ehcache3

  1. Explore the Ehcache 3.2 Clustered Kit structure

    master

    The Ehcache 3.2 kit for Terracotta-based distributed caching is organized into several functional directories:

    • server: Contains libraries, executables, and supporting files for the Terracotta Server.
      • server/plugins: Libraries for applications installed in the server.
    • client: Contains the client runtime libraries.
      • client/ehcache: Ehcache-specific libraries for distributed caching via the Terracotta Server.
      • client/ehcache/documentation: Local Ehcache documentation.
    • client/lib: Third-party client libraries.
    • docker: Dockerfile examples for building custom Terracotta images to run clustered Ehcache.
    • legal: Licenses associated with this distribution.
  2. What is Off-Heap storage?

    master

    When large caches create significant pressure on the Java Garbage Collector (GC), you can store cache contents off-heap.

    Off-heap storage keeps data within the memory of the JVM process but manages it outside the reach of the garbage collector. Ehcache's off-heap implementation uses a port of dlmalloc backed by NIO direct ByteBuffers to minimize GC overhead.

  3. Transaction support and EvictionAdvisor interaction

    master

    The XAStore (used for transactions) uses the EvictionAdvisor mechanism to protect all in doubt SoftLock instances from being evicted.

    When integrating a user-provided EvictionAdvisor, note that the advisor only interacts with SoftLock instances that are not in doubt. These non-in-doubt locks only contain the old value, which is the value passed to the adviseAgainstEviction(K key, V value) method.

  4. Understand Ehcache resilience strategies

    master

    Ehcache is designed to maintain a coherent state and continue answering requests even when underlying tiers (like disk or clustered tiers) fail. When a backend tier fails, it throws a StoreAccessException, which is then intercepted and handled by a ResilienceStrategy.

    Ehcache provides two default implementations:

    1. RobustResilienceStrategy: Used by classical caches. It behaves like an always-empty cache where everything added is immediately evicted. This effectively makes the cache behave as if it were disabled, preventing failures from propagating to the caller.
    2. RobustLoaderWriterResilienceStrategy: Used by caches with a loader-writer. This strategy attempts to maintain coherence by interacting with the loader-writer. For example, a get() will attempt to load the value from the loader-writer if the tier fails.
  5. How Ehcache services are discovered via ServiceProvider

    master
    Ehcache uses a service-oriented architecture for bootstrapping. When a CacheManager is initialized, it creates an org.ehcache.spi.ServiceProvider. This provider utilizes Java's java.util.ServiceLoader mechanism to automatically discover all available ServiceFactory implementations present on the classpath. This allows developers to extend Ehcache functionality by simply adding new service factories to the project's dependencies.
  6. Implement the Cache-aside pattern

    master

    In the Cache-aside pattern, the application code is responsible for managing both the cache and the System-of-Record (SoR). The application first checks the cache for data; if the data is missing (a cache miss), the application fetches it from the SoR and manually populates the cache. When writing data, the application must update both the SoR and the cache.

    Pros: Simple to implement without complex cache configuration. Cons: Application code becomes cluttered with data orchestration logic.

    // Pseudocode for reading values
    v = cache.get(k)
    if (v == null) {
      v = sor.get(k)
      cache.put(k, v)
    }
    
    // Pseudocode for writing values
    v = newV
    sor.put(k, v)
    cache.put(k, v)
  7. Configure Storage Tiers (Heap, Off-Heap, and Disk)

    master

    Ehcache uses a tiering model to move data between different storage layers based on frequency of use (hot vs. cold data).

    Three-Tier Example

    You can configure a hierarchy consisting of Heap, Off-Heap, and Persistent Disk storage:

    CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder()
        .with(persistence(new File("/data/ehcache-data")))
        .withCache("threeTierCache", 
            CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class, 
                ResourcePoolsBuilder.newResourcePoolsBuilder()
                    .heap(100)
                    .offheap(10, MemoryUnit.MB)
                    .disk(500, MemoryUnit.MB, true)
            ))
        .build(true);

    Tiers Explained

    • Heap: The fastest, smallest tier. Stores objects directly in the JVM.
    • Off-Heap: Faster than disk but larger than heap. Stores data outside the JVM garbage-collected heap.
    • Disk: The largest and slowest tier. If configured as persistent (the true parameter in .disk()), data survives JVM restarts provided the CacheManager is closed cleanly.
  8. Use the Write-behind pattern

    master

    The Write-behind pattern (also known as write-back) is a component of the Cache-as-SoR model that optimizes write performance by changing the timing of the SoR update.

    Instead of making the application thread wait for the SoR write to complete (as in Write-through), Write-behind queues the data to be written to the SoR at a later time.

    Trade-off:

    • Benefit: Higher application throughput/lower latency because the user thread moves on immediately.
    • Cost: Introduces a lag between the cache update and the SoR update, meaning the SoR is temporarily out of sync.
  9. Supplement JSR-107 configurations with XML templates

    master

    Ehcache3 extends standard JSR-107 XML configuration by allowing you to use cache-templates. This allows you to configure Ehcache-specific features (like capacity constraints) that are not part of the standard JSR-107 specification and apply them to JSR-107 caches.

    To enable this, you must:

    1. Declare the jsr107 namespace in your <config> element.
    2. Add a <service> element containing <jsr107:defaults>.
    3. Use the default-template attribute in <jsr107:defaults> to set a template for all programmatically created caches.
    4. Use <jsr107:cache> within <jsr107:defaults> to map specific named caches to templates.
    <config
        xmlns='http://www.ehcache.org/v3'
        xmlns:jsr107='http://www.ehcache.org/v3/jsr107'>
    
    <service>
        <jsr107:defaults default-template="tinyCache">
          <jsr107:cache name="foos" template="stringCache"/>
        </jsr107:defaults>
      </service>
    
    <cache-template name="stringCache">
        <key-type>java.lang.String</key-type>
        <value-type>java.lang.String</value-type>
        <capacity>2000</capacity>
      </cache-template>
    
    <cache-template name="tinyCache">
        <capacity>20</capacity>
      </cache-template>
    </config>
  10. How ExecutionService works in Ehcache

    master

    Ehcache uses the ExecutionService interface to manage asynchronous tasks through thread pools. It provides three types of execution capabilities:

    • ScheduledExecutorService: For tasks that need to be scheduled to run repeatedly after a specific delay.
    • Unordered ExecutorService: For executing tasks as soon as a thread becomes available, without any specific order.
    • Ordered ExecutorService: For executing tasks as soon as a thread becomes available, while guaranteeing that tasks are executed in the exact order they were submitted.

    There are two primary implementations:

    1. OnDemandExecutionService: The default implementation. It creates a new pool every time an executor service is requested. It requires no configuration.
    2. PooledExecutionService: A managed implementation that maintains a configurable set of thread pools. This must be explicitly configured using PooledExecutionServiceConfiguration.
  11. How clustered caching works in Ehcache

    master

    Clustered caching allows multiple application instances to share cache data via a Terracotta Server. This architecture provides horizontal scale-out while maintaining low latency through local tiers.

    Key Components:

    • Local Tiers (Heap/Off-Heap): Hot data is stored locally on the application instance for fast access.
    • Clustered Tier: Data is stored on a Terracotta Server, making it available to all cluster members.
    • Terracotta Server: Hosts the Cluster Tier Manager, which manages the off-heap data storage and coordinates between cache managers.

    Storage Models:

    • Dedicated Pools: A fixed amount of storage allocated from server off-heap resources to a specific cluster tier. It is used exclusively by that tier.
    • Shared Pools: Fixed-amount storage pools that can be shared by the cluster tiers of multiple caches. While the underlying storage is shared (and eviction can affect any cache in the pool), the data for each cache remains isolated.