版本 2

    下面是关于Eviction和Expiration的注意点:

     

    1. Expiration是一个顶层结构,可以通过配置或者cache API定义。之后我们会有更多的阐述。
    2. Eviction针对的是本地缓存实例,Expiration针对的则是整个集群范围内的节点。Expiration的lifespanmaxIdle的值会在缓存每个数据项间进行复制。
    3. Expiration的lifespanmaxIdle的值会持久化到CacheStores,所以这些信息也能够被eviction或者passivation使用。
    4. Infinispan包含了三种eviction策略, EvictionStrategy.NONE, EvictionStrategy.LRUEvictionStrategy.FIFO,并且这些都是最有用的。如果需要,将来还会增加更多的策略。
      1. 从 Infinispan 4.1版本开始, EvictionStrategy.UNORDERED 将会可用。
    5. 从架构上讲,这些是完全新的实现。

    配置

    Eviction可以通过Configuration bean 或者XML文件的方式进行配置。 Eviction配置是基于单个缓存的。 关于Eviction的有用配置元素包括:

     

    <eviction strategy="FIFO" wakeupInterval="1000" maxEntries="2000"/>
    <expiration lifespan="1000" maxIdle="500" />
    

    通过编程方式,可以达到同样的效果:

     

    configuration.setEvictionStrategy(EvictionStrategies.FIFO);
    configuration.setEvictionWakeupInterval(1000);
    configuration.setEvictionMaxEntries(2000);
    configuration.setExpirationLifespan(1000);
    configuration.setExpirationMaxIdle(500);
    

    默认值

    默认情况下,Eviction是没有启用的。 如果启用了Eviction (通过一个空白的 <eviction /> 元素),将会使用一定的默认值:

    • strategy: 如果没有指定策略,将会默认使用EvictionStrategy.NONE。
    • wakeupInterval: 如果没有指定,默认值是5000
      • 如果你想要禁用 eviction 线程,可以设置wakeupInterval值为 -1
    • maxEntries: 如果没有指定,默认值是-1,意味着包含无限个数据项。
      • 0 意味着没有数据项,eviction 将会一直使缓存为空。

    Eviction的lifespanmaxIdle值默认为 -1。

     

    Expiration的使用

    你可以为缓存中的任意键值对设置一个Expiration的lifespanmaxIdle的值。它即可以像上面所说的那样通过配置设置成集群范围的,也可以使用Cache接口来定义键值对。任何键值对定义的值都能够覆写该数据项在集群范围内的默认值。

    例如使用下面的配置:

     

    <expiration lifespan="1000" />
    

     

    // this entry will expire in 1000 millis
    cache.put("pinot noir", pinotNoirPrice);
    
    // this entry will expire in 2000 millis
    cache.put("chardonnay", chardonnayPrice, 2, TimeUnit.SECONDS);
    
    // this entry will expire 1000 millis after it is last accessed
    cache.put("pinot grigio", pinotGrigioPrice, -1, 
              TimeUnit.SECONDS, 1, TimeUnit.SECONDS);
    
    // this entry will expire 1000 millis after it is last accessed, or
    // in 5000 millis, which ever triggers first
    cache.put("riesling", rieslingPrice, 5, 
              TimeUnit.SECONDS, 1, TimeUnit.SECONDS);
    

    Eviction 设计

    Eviction的核心是一个 EvictionManager实例 。如果配置了Eviction或者Expiration,则这个实例是可用的。

     

    EvictionManager的作用就是   eviction线程which periodically purges items from the DataContainer. 如果禁用了eviction线程(wakeupInterval设置为-1) ,eviction可以通过调用EvictionManager.processEviction()来手动启动,例如通过周期性的运行应用中的另一条维护线程。

     

    eviction manager是按照下面的方式来处理evictions的:

    1. 触发Data Container清除过期的数据项
    2. 触发Cache Stores (如果存在的话) 清除过期数据项
    3. 调整Data Container的大小为指定值,该值的大小有maxElements属性决定

     

     

    DataContainer

    DataContainer 是缓存和Eviction的核心。因此,使用哪种DataContainer接口的实现决定于是否启用了eviction和使用了哪种eviction策略。DataContainer提供了类似purgeExpired()iterator()的方法,这些方法会在上述步骤1 和步骤3由EvictionManager调用。

    如果缓存不启用Eviction,那么效率最高的data container实现就是SimpleDataContainerFIFOSimpleDataContainerLRUSimpleDataContainer 实现会在排序上消耗一定的性能。关于算法的细节可以参照实现的 Javadocs。