Java--缓存热点数据,最近最少使用算法+redis

1、最近最少使用算法LRU (Least recently used,最近最少使用)

【实现】:最常见的是使用一个链表保存缓存数据

我们将维护的链表设为一个双向链表(即每个节点都有个prev和next),另外需要再多维护一个map,将缓存对象的引用放入map中;

1、新数据插入链表头部,并且放入map中

2、每当需要使用缓存时,首先通过key到map中查找,命中缓存后将数据移动到链表头部(这个移动就非常好移动了,只需要把该节点的prev节点的next属性赋值为该节点的next节点,同时把该节点的next节点的prev属性赋值为该节点的prev节点,并且将该节点放入链表头部就可以了)。

3、当链表满的时候将链表尾部的数据丢弃,并且删除map中对应的数据。

2、使用redis缓存数据,保证热点数据的缓存用法与原理

说一点:只要限制了redis占用的内存,redis会根据自身数据淘汰策略加载热数据到内存

【实现】:

通过redis本身的设置过期时间来实现缓存热点数据

  1. 缓存每命中一次,就重新给该数据设置过期时间

  2. 那么经常命中的缓存始终不会过期不会被删除,而非热点数据过期时间一到那么就会被删除掉,保证了redis中始终存在的是热点数据

【原理】:

  1. 原理其实就是Java中延时阻塞队列DelayQueue的原理

  2. 对redis中缓存数据设置过期时间,相当于将缓存数据放入redis中维护的延时阻塞队列DelayQueue

  3. DelayQueue会对放入的缓存数据根据过期时间进行排序时间短的在前面,时间长的在队列后面

  4. 使用一个或者多个线程循环查询DelayQueue一旦能从DelayQueue获取元素了就说明该缓存数据到期了,就可以取出来并且删除掉了

  5. 有多个线程都同时查询DelayQueue的时候只有一个线程能够争取到头元素,其它线程将被阻塞当头元素被取走以后,会唤醒所有阻塞线程,线程竞争头元素,竞争到头元素的线程会查询头元素的剩余delay时间,并且标记头元素已经被该线程占有,再根据delay时间wait自己,最后获取头元素后唤醒其它阻塞线程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值