简体   繁体   English

带有生存时间的 EHcache 简单示例

[英]EHcache simple example with time-to-live

I need a simple cache for storing tuples in memory with a certain time-to-live.我需要一个简单的缓存来在内存中存储具有特定生存时间的元组。 I couldn't find a way to do that on EHcache website, which contains mostly complex usage scenarios.我在 EHcache 网站上找不到这样做的方法,该网站主要包含复杂的使用场景。 Can anyone help me out?任何人都可以帮助我吗?

PS I don't use Spring. PS我不使用Spring。

Ehcache 2.x Ehcache 2.x

Programmatic程序化

CacheManager cacheManager = initCacheManager();
CacheConfiguration cacheConfiguration = new CacheConfiguration().name("myCache")
        .maxEntriesLocalHeap(100)
        .timeToLiveSeconds(20);
cacheManager.addCache(new Cache(cacheConfiguration));

XML XML

<cache name="myCache"
       maxEntriesLocalHeap="100"
       timeToLiveSeconds="20"/>

Override per Element覆盖每个Element

Ehcache 2.x allows your to override expiry settings per Element : Ehcache 2.x 允许您覆盖每个Element到期设置:

Element element = new Element("key", "value");
element.setTimeToLive(10);
cache.put(element);

Ehcache 3.x Ehcache 3.x

Programmatic程序化

CacheManager cacheManager = initCacheManager();
CacheConfigurationBuilder<Long, String> configuration = 
    CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class, ResourcePoolsBuilder
      .heap(100))
      .withExpiry(Expirations.timeToLiveExpiration(new Duration(20, TimeUnit.SECONDS)));
cacheManager.createCache("myCache", configuration);

In Ehcache 3, the builder is immutable and can be safely shared to create multiple caches from a similar configuration.在 Ehcache 3 中,构建器是不可变的,可以安全地共享以从类似的配置创建多个缓存。 And the code will be more compact if you use static imports, which I did not do here to ease pasting this snippet in an IDE.如果您使用静态导入,代码会更加紧凑,我在这里没有这样做是为了简化在 IDE 中粘贴此代码段的过程。

XML XML

<cache alias="myCache">
  <expiry>
    <ttl unit="seconds">20</ttl>
  </expiry>
  <heap>100</heap>
</cache>

Override through custom Expiry通过自定义Expiry覆盖

in Ehcache 3.x, Expiry is an interface which users can implement:在 Ehcache 3.x 中, Expiry是一个用户可以实现的接口:

public interface Expiry<K, V> {
  Duration getExpiryForCreation(K key, V value);
  Duration getExpiryForAccess(K key, ValueSupplier<? extends V> value);
  Duration getExpiryForUpdate(K key, ValueSupplier<? extends V> oldValue, V newValue);
}

time-to-live matches the getExpiryForCreation invocation, which will receive the key and value of the mapping, allowing to implement different expirations depending on the mapping itself.生存时间匹配getExpiryForCreation调用,它将接收映射的键和值,允许根据映射本身实现不同的到期时间。

Ehcache 3.x solution to define expiry per element on runtime Ehcache 3.x 解决方案在运行时定义每个元素的到期时间

This solution was tested as working fine on Ehcache 3.8.1, but the code is for sure valid for any Ehcache 3.x此解决方案在 Ehcache 3.8.1 上测试正常,但代码肯定对任何 Ehcache 3.x 都有效

First create a class to keep a generic, in fact any object you are able pass to cache:首先创建一个类来保持一个泛型,实际上任何你可以传递给缓存的对象:

    import java.io.Serializable;
    import java.time.Duration;

    public class EhcacheValue<T> implements Serializable {

        private static final long serialVersionUID = 1L;

        private T object;

        private long timeToLive;

        public EhcacheValue(T theObject, Duration theDuration) {
            object = theObject;
            timeToLive = theDuration.getSeconds();
        }

        public Duration getTimeToLiveDuration() {
            return Duration.ofSeconds(timeToLive);
        }

        public T getObject() {
            return object;
        }

        public void setObject(T theObject) {
            object = theObject;
        }

        public long getTimeToLive() {
            return timeToLive;
        }

        public void setTimeToLive(long theTimeToLive) {
            timeToLive = theTimeToLive;
        }

    }

Then create a custom Expiry class implementing the Ehcache 3.x interface ExpiryPolicy :然后创建一个实现Ehcache 3.x接口ExpiryPolicy自定义 Expiry 类

import java.time.Duration;

import java.util.function.Supplier;

import org.ehcache.expiry.ExpiryPolicy;

public class CustomExpiryPolicy<K, V extends EhcacheValue<?>> implements ExpiryPolicy<K, V> {

    public CustomExpiryPolicy() {

    }

    @Override
    public Duration getExpiryForCreation(K theKey, V theValue) {
       return theValue.getTimeToLiveDuration();
    }

    @Override
    public Duration getExpiryForAccess(K theKey, Supplier<? extends V> theValue) {
        return null;
    }

    @Override
    public Duration getExpiryForUpdate(K theKey, Supplier<? extends V> theOldValue, V theNewValue) {
         return theNewValue.getTimeToLiveDuration();
       }
    }

Then you have the normal code, but with a few important lines on the way :然后你有正常的代码,但有一些重要的行

public class TestEhCache {

    private static final String CACHE_TIER_HEAP = "OnHeap";

    public static void main(String[] args) {

        StatisticsService statisticsService = new DefaultStatisticsService();

        myCacheManager = CacheManagerBuilder.newCacheManagerBuilder()
                .using(statisticsService)
                .build();

        //we init it here, not with boolean in build()
        myCacheManager.init();

        // Beware, the items are not expiring automatically, there are more mechanism in place for checking the expiration
        // For instance the expiration is checked at get time
        // for more details see the documentation from the version 2.8 
        // here: https://www.ehcache.org/documentation/2.8/apis/cache-event-listeners.html
        // Unfortunately for the version 3.x doesn't exist a detailed depiction, but in main the procedure is the same
        //
        // Ehcache 2.8 documentation:
        // Elements are checked for expiry in Ehcache at the following times:
        //
        // When a get request is made
        // When an element is spooled to the diskStore in accordance with a MemoryStore eviction policy
        // In the DiskStore when the expiry thread runs, which by default is
        // net.sf.ehcache.Cache#DEFAULT_EXPIRY_THREAD_INTERVAL_SECONDS

        CustomExpiryPolicy<String,EhcacheValue<?>> expiryPolicy = new CustomExpiryPolicy<String,EhcacheValue<?>>();

        ResourcePools resourcePools = ResourcePoolsBuilder.newResourcePoolsBuilder().heap(2000L, EntryUnit.ENTRIES).build();

        @SuppressWarnings("unchecked")
        Class<EhcacheValue<?>> myEhcacheValue = (Class<EhcacheValue<?>>)(Class<?>)EhcacheValue.class;

        CacheConfiguration<String,EhcacheValue<?>> cacheConfiguration = CacheConfigurationBuilder
                .newCacheConfigurationBuilder(String.class, myEhcacheValue, resourcePools)
                .withExpiry(expiryPolicy)
                //.withService(new StoreStatisticsConfiguration(true)) // explicitly enable statistics, it seems is not needed
                .build();

        myCache = myCacheManager.createCache("myCache", cacheConfiguration);

        myCacheStatistics = statisticsService.getCacheStatistics("myCache");

        long cacheEntriesNr = myCacheStatistics.getTierStatistics().get(CACHE_TIER_HEAP).getMappings();

        //nb element in heap tier
        long sizeEntriesByStatistics = myCacheStatistics.getTierStatistics().get("OnHeap").getMappings();
        //size of the tier in memory, when you set memory limits, not in this case
        //long sizeBytesByStatistics = myCacheStatistics.getTierStatistics().get("OnHeap").getOccupiedByteSize();

        long getsCnt = myCacheStatistics.getCacheGets();
        long putsCnt = myCacheStatistics.getCachePuts();
        long removalsCnt = myCacheStatistics.getCacheRemovals();
        long missesCnt = myCacheStatistics.getCacheMisses();
        long evictionsCnt = myCacheStatistics.getCacheEvictions();
        long crtExpiredCnt = myCacheStatistics.getCacheExpirations();

        System.out.println("getsCnt = "+getsCnt);
        System.out.println("putsCnt = "+putsCnt);
        System.out.println("removalsCnt = "+removalsCnt);
        System.out.println("missesCnt = "+missesCnt);
        System.out.println("evictionsCnt = "+evictionsCnt);
        System.out.println("expiredCnt = "+expiredCnt);
        System.out.println("hitPercentage = "+hitPercentage);
        System.out.println("missPercentage = "+missPercentage);
        System.out.println("Computed number of items in cache = "+(putsCnt-removalsCnt-expiredCnt-evictionsCnt));

    }

    @SuppressWarnings("unchecked")
    // we are aware about the unchecked cast - it is a desired behavior. 
    // Cache can store objects of various types, so compile time type safety cannot be achieved easily.
    // We'll get runtime ClassCastException if cache is used incorrectly.
    public static <T> T get(String key) {
        EhcacheValue<T> ehcacheValue = (EhcacheValue<T>)myCache.get(key);
        return (T) (ehcacheValue!=null?ehcacheValue.getObject():null);
    }

    // we are aware about the unchecked cast - it is a desired behavior. 
    // Cache can store objects of various types, so compile time type safety cannot be achieved easily.
    // We'll get runtime ClassCastException if cache is used incorrectly.
    public static <T extends Object> T put(String key, T value, int timeToLiveInSeconds) {

        if (key == null) {
            throw new AssertionError("Key must not be null!");
        }

        if (value != null) {
            EhcacheValue<T> ehcacheValue = new EhcacheValue<T>(value, Duration.of(60, ChronoUnit.SECONDS));
            myCache.put(key, ehcacheValue);
            return value;
        } else {
            return null;
        }
    }
}

As for EhCache version 3.3.1, groupId:org.ehcache,artifactId:ehcache , the following works!对于 EhCache 3.3.1 版, groupId:org.ehcache,artifactId:ehcache ,以下有效!

CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder().withCache("AllCache",
        CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class,String.class,
            ResourcePoolsBuilder.heap(100))
            .withExpiry(Expirations.timeToLiveExpiration(new Duration(86400, TimeUnit.SECONDS)))
            .build()).build(true);


Cache<String, String> allCache = cacheManager.getCache("AllCache", String.class, String.class);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 ehcache3获得生存时间配置 - Ehcache3 get time-to-live configuration 在运行时配置生存时间属性 - Configuring time-to-live property at run time 带有Tomcat的ehcache简单示例 - Ehcache with tomcat simple example ehcache简单的搜索/交易示例? - Ehcache simple search/transaction example? Java-通过通过MulticastSocket发送来减少UDP数据包的生存时间? - Java - reduce Time-To-Live of UDP packet by sending it via MulticastSocket? 在Spring集成中将动态值设置为生存时间 - Setting dynamic value to time-to-live in Spring integration 如何使用Hector为Cassandra中的列设置生存时间? - how set time-to-live for column in Cassandra with Hector? 如何在 Java 中使用 Redisson 客户端更新条目的生存时间? - How to update time-to-live of an entry using Redisson client in Java? 有没有一种方法可以使用Table(azure-storage)客户端API使用CosmosDb设置项目级别TTL(生存时间)? - Is there a way to set item level TTL(Time-To-Live) with CosmosDb utilizing the Table (azure-storage) client API? 未使用 spring-cache 设置 GemFire 条目 Time-To-Live - GemFire entry Time-To-Live is not getting set using spring-cache
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM