版本 2

    Infinispan 支持数据项的逐出(Eviction),这样是为了避免内存溢出。  Eviction一般是和一个cache store结合起来使用,所以当发生Eviction的时候,数据项并不是永久的丢失了,因为数据逐出只是从内存中移除了,而不是从cache stores中或者集群的其他节点移除。

    当启用Eviction时,还有一个经常启用的选项叫做钝化(Passivation) , 这样的话只会在内存中或者cache store里维护一份数据项的拷贝,而不用在两者中都维护。 使用钝化相对于使用常规的cache store的优势在于更新内存中的数据消耗更小,因为不需要对cache store进行更新。

    注意,这里所说的Eviction只是发生在本地,而不是集群范围内。每个节点都可以运行一个Eviction线程来分析内存的内容,从而决定哪些数据被逐出。  Eviction并不是以JVM的可用内存作为阀值来逐出数据项。使用者如果想要启用Eviction,必须为eviction元素设置一个大于零的maxEntries属性。 如果maxEntries的值太大,还是有可能发生内存溢出。请根据使用的场景来调整maxEntries属性的大小。

     

    Eviction 在 4.0中的实现

     

    可以通过在配置文件的<default /> 或者 <namedCache /> 部分增加<eviction /> 元素来配置Eviction。

    NONE

    是指禁用了eviction进程。

    无序

    Infinispan 4.1的新特性

    这种Eviction策略意味着需要使用简单、无序的数据容器。eviction进程仍然会运行,并且仍会将数据容器的大小维护在限制之内,但是以一种不确定的方式来选择要逐出的数据。 这种Eviction策略的好处是可以获得一个高效的SimpleDataContainer ,不会像FIFO和LRU策略那样付出排序的代价,因为大部分的操作都会在固定时间内完成。

    先进先出(FIFO)

    这种策略是指遵循先进先出的原则来选择要逐出的数据项。关于该算法以及涉及的性能权衡的更多信息可以参照FIFOSimpleDataContainer Javadocs。

    最近最少使用(LRU)

    这种策略是指遵循最近最少使用的原则来选择要逐出的数据项。关于该算法以及涉及的性能权衡的更多信息可以参照 LRUSimpleDataContainer Javadocs 。

    设置eviction线程

    Eviction借助于 SheduledExecutorService 来周期性启用和检查数据容器的大小,并在需要的时候来逐出数据。 您可以通过使用 <evictionScheduledExecutor /> 这个配置元素来进行调整

     

    Eviction 在4.1, 4.2 and 5.x的实现

     

    在Infinispan 4.1及后续版本中,我们对DataContainer抽象进行了改进,以便可以支持更具扩展性和低锁争用的数据容器结构。除了原有的Eviction策略之外,还可以选择使用 LIRS算法。 LRU 仍然是默认的并且对于大多数开发场景来说是最适合的。然而,要注意的是,尽管LRU逐出算法简单易懂,,但是在一些称作弱引用范围(weak access locality)的情况下不太适用。 (弱引用范围是指只访问一次的数据项不会及时被替换,而频繁访问的数据项确被替换了的现象).

     

    从 4.1 版本开始,所有缓存数据项的eviction是按照piggyback方式进行的。就像它的名字一样,Piggyback eviction线程方式是指借助于访问数据容器的用户线程来完成eviction的。默认的通过一个专门的EvictionManager线程来完成eviction已经不建议使用,并且即使配置文件中配置的是选择使用默认的eviction线程方式,还是会使用piggyback方式。专门的EvictionManager并没有完全移除;它仍然用于清除缓存中的过期数据项。

     

    还需要注意的是在Infinispan 4.1 版本中,只有永久性数据才会逐出。默认情况下,所有的数据项都是永久性的,也就是说expriation和lifespan值为-1。一旦某个缓存的数据项都是临时性数据,他们将不适用逐出策略并且容器的大小也有可能超出maxEntries指定的值。 从 Infinispan 4.2 以及后续的5.0版本,容器中任何类型的数据项都有可能被逐出。

     

    数据过期

     

    数据过期和数据逐出很相似,但是两者并不相同。数据过期允许你指定某个数据项的生命期和最大空闲时间。数据项一旦过期,他们就将会被认为是无效的并且会被删除。 移除一个过期数据并不是数据逐出中的钝化(如果启用了钝化的话)。

    和数据逐出不同的是,过期数据将会被全局性的删除——也就是说内存,cache stores甚至整个集群范围。

    默认情况下,创建的数据项是永久性的并且没有指定生命期或者最大空闲时间。 借助于cache API,可以创建带有生命期或者指定最大空闲时间的临时数据。更进一步,可以在你的<default /> 或者<namedCache />配置部分添加<expiration /> 元素,从而使数据项带有默认的生命期或者最大空闲时间。