欢迎投稿

今日深度:

solr ConcurrentLRUCache,

solr ConcurrentLRUCache,


github:https://github.com/apache/lucene-solr/blob/master/solr/core/src/java/org/apache/solr/util/ConcurrentLRUCache.java

LRU,即Least Recently Used,最近最少使用的缓存将最先被淘汰

ConcurrentLRUCache中使用ConcurrentHashMap来存储缓存(k-v),
这样能保证其线程安全。
存储的value有一个时间戳(不是真的时间戳,而是cache内维护的一个全局自增字段)来存储它的最近更新时间。
当缓存数到达upperSize(具体指什么,范围?)时将触发缓存的淘汰机制。

这个淘汰过程是并发的,类似于cms的回收过程。这个过程会分几个阶段并发扫描ConcurrentHashMap。

第一批淘汰时会计算出最小的时间戳minV,当前时间戳nextV,和需要移除的数量numToReomve(这个值等于当前size减去最小容量)。minV是变化的,在遍历过程中会变化。当一个缓存的时间戳v大于nextV - 最小容量则保留,若v小于minV +numToRemove则移除,否则会被加入一个数组elist,为之后的淘汰做准备。

通过第一批淘汰,显然淘汰的缓存数可能小于需要淘汰数,因此在判断淘汰任务未达标之后,便执行下一轮的淘汰。

第二批淘汰,对elist的缓存做第一批淘汰的操作。

同样检测是否淘汰达标,若没有达标则进行第三波操作

第三批淘汰,直接使用优先队列(堆)淘汰最小的numToRemove个缓存。由于之前的淘汰是根据minV来决定的,而minV是浮动的,所以淘汰数不准确,而直接使用堆则可以稳定淘汰numToRemove个,当然需要付出更多的时间.

以上是ConcurrentLRUCache的部分实现,可见和cms的gc过程十分相似,分很多波来进行标记和删除,可见在并发环境下,多部的,不稳定的操作是高效的。

转载于:https://www.jianshu.com/p/bcb976b5cf98

www.htsjk.Com true http://www.htsjk.com/solr/37742.html NewsArticle solr ConcurrentLRUCache, github:https://github.com/apache/lucene-solr/blob/master/solr/core/src/java/org/apache/solr/util/ConcurrentLRUCache.java LRU,即Least Recently Used,最近最少使用的缓存将最先被淘汰 ConcurrentLRUCa...
相关文章
    暂无相关文章
评论暂时关闭