我们知道Redis是基于内存来存储数据的,这也是它之所以查询速度这么快的原因之一。但是在数据量较大的场景下如果一直网缓存中存数据那么就会报OOM异常,因此我们就需要使用下面八种缓存淘汰策略对缓存进行删除处理。
1、noeviction:返回错误当内存限制达到,并且客户端尝试执行会让更多内存被使用的命令。
2、allkeys-lru: 尝试回收最少使用的键(LRU),使得新添加的数据有空间存放。
3、volatile-lru: 尝试回收最少使用的键(LRU),但仅限于在过期集合的键,使得新添加的数据有空间存 放。
4、allkeys-random: 回收随机的键使得新添加的数据有空间存放。
5、volatile-random: 回收随机的键使得新添加的数据有空间存放,但仅限于在过期集合的键。
6、volatile-ttl: 回收在过期集合的键,并且优先回收存活时间(TTL)较短的键,使得新添加的数据有空间 存放。
7、allkeys-lfu:对所有key使用LFU算法进行删除
8、volatile-lfu:对所有设置了过期时间的key使用LFU算法进行删除

本文主要针对LRU算法展开论述
一、什么是LRU算法

就是一种缓存淘汰策略。
计算机的缓存容量有限,如果缓存满了就要删除一些内容,给新内容腾位置。但问题是,删除哪些内容呢?我们肯定希望删掉哪些没什么用的缓存,而把有用的数据继续留在缓存里,方便之后继续使用。那么,什么样的数据,我们判定为「有用的」的数据呢?
LRU 缓存淘汰算法就是一种常用策略。LRU 的全称是 Least Recently Used,也就是说我们认为最近使用过的数据应该是是「有用的」,很久都没用过的数据应该是无用的,内存满了就优先删那些很久没用过的数据。
通俗点讲就删除缓存时优先删除最久未被操作的数据,增删改查都属于操作的范畴。

二、LRU 算法描述
LRU 算法实际上是让你设计数据结构:首先要接收一个 capacity 参数作为缓存的最大容量,然后实现两个 API,一个是 put(key, val) 方法存入键值对,另一个是 get(key) 方法获取 key 对应的 val,如果 key 不存在则返回 -1。

三、LRU 算法设计
分析上面的操作过程,要让 put 和 get 方法的时间复杂度为 O(1),我们可以总结出 cache 这个数据结构必要的条件:查找快,插入快,删除快,有顺序之分。
因为显然 cache 必须有顺序之分,以区分最近使用的和久未使用的数据;而且我们要在 cache 中查找键是否已存在;如果容量满了要删除最后一个数据;每次访问还要把数据插入到队头。
那么,什么数据结构同时符合上述条件呢?哈希表查找快,但是数据无固定顺序;链表有顺序之分,插入删除快,但是查找慢。所以结合一下,形成一种新的数据结构:哈希链表。

四、代码实现
很多编程语言都有内置的哈希链表或者类似 LRU 功能的库函数,但是为了帮大家理解算法的细节,我们用 Java 自己造轮子实现一遍 LRU 算法。

class LRUCache {Map<Integer,Node> map;Node head;Node tail;int capacity;public LRUCache(int capacity) {this.map=new HashMap<>(capacity);this.capacity=capacity;this.head=new Node(0,0);this.tail=new Node(0,0);this.head.next=tail;this.tail.pre=head;}public int get(int key) {if(!map.containsKey(key)){return -1;}Node node=map.get(key);move2first(node);return node.val;}public void put(int key, int value) {if(map.containsKey(key)){Node node=map.get(key);node.val=value;map.put(key,node);move2first(node);return;}if(map.size()==capacity){Node last=this.tail.pre;map.remove(last.key);removeNode(last);}Node node=new Node(key,value);add2first(node);map.put(key,node);}public void removeNode(Node node){//删除节点node.pre.next=node.next;node.next.pre=node.pre;node.next=null;node.pre=null;}public void add2first(Node node){//添加节点Node curr=this.head.next;this.head.next=node;node.next=curr;node.pre=this.head;curr.pre=node;}public void move2first(Node node){//移动节点node.pre.next=node.next;node.next.pre=node.pre;add2first(node);}//定义链表class Node{Node pre;//上一个节点Node next;//下一个节点int key;int val;public Node(int key,int val){this.key=key;this.val=val;}}
}

Redis缓存淘汰之LRU相关推荐

  1. Redis缓存淘汰策略

    文章目录 noeviction allkeys-lru allkeys-lfu volatile-lru volatile-lfu allkeys-random volatile-random vol ...

  2. Redis缓存淘汰机制

    Redis缓存淘汰机制  当Redis内存超出物理内存限制时,内存的数据会开始和磁盘产生频繁的交换,这样会使得redis的性能急剧下降. 在生产环境中,是不允许redis出现交换行为的,为了限制最大使 ...

  3. mysql缓存淘汰机制_聊聊缓存淘汰算法-LRU 实现原理

    前言 我们常用缓存提升数据查询速度,由于缓存容量有限,当缓存容量到达上限,就需要删除部分数据挪出空间,这样新数据才可以添加进来.缓存数据不能随机删除,一般情况下我们需要根据某种算法删除缓存数据.常用淘 ...

  4. 缓存淘汰算法--LRU算法

    缓存淘汰算法--LRU算法 参考: https://www.cnblogs.com/dailidong/p/7571178.html https://blog.csdn.net/wangxilong1 ...

  5. 源码角度详解Redis缓存淘汰机制(Eviction)

    本文从源码层面分析了 redis 的缓存淘汰机制,并在文章末尾描述使用 Java 实现的思路,以供参考. 相关配置 为了适配用作缓存的场景,redis 支持缓存淘汰(eviction)并提供相应的了配 ...

  6. Redis内存淘汰策略LRU、LFU详解

    Redis内存淘汰原因 Redis是一种内存数据库,redis的容量往往有限,无法存放所有的数据.当内存满了的时候,并且这个时候还需要往Redis中放入新的数据,就需要将Redis中的一部分数据淘汰了 ...

  7. 缓存淘汰算法——LRU算法详细总结及代码实现

    什么是LRU算法? LRU是一种缓存淘汰策略,对于我们的计算机来说,缓存容量是有限的,那么当缓存满了要怎么办?这时就要用到LRU,对于很久没有用过的数据,我们可以将其判定为无用的数据,当新资源进入缓存 ...

  8. redis 缓存 淘汰

    1.LRU LRU(Least recently used,最近最少使用) 其核心思想是"如果数据最近被访问过,那么将来被访问的几率也更高". 基本思路 新数据插入到列表头部: 每 ...

  9. 缓存淘汰策略—LRU算法(java代码实现)

    LRU 原理 LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是"如果数据最近被访问过,那么将来被访问的几率也更高" ...

最新文章

  1. hp laser103 属性没有配置项_冰雪传奇:起源之上还有装备吗?详解鸿蒙装备合成与属性...
  2. R 回归 虚拟变量na_如何优雅地计算多变量
  3. ios::ate ios::app ios::out ios::in ios::trunc ios::binary(组合总结)
  4. (找规律)Magic of David Copperfield
  5. 如何销毁一个实例化对象_基于脚本的游戏对象系统(1) 实例化、组件及生命周期...
  6. vim 全局替换命令
  7. pythonttf字体下载_python 58 字体反爬
  8. 转《腾讯大讲堂11 拍拍ce工作经验分享》
  9. 数据结构—队列的C语言实现
  10. vue项目如何打包以及如何变成android、ios应用程序
  11. Web应用十大安全漏洞
  12. mx250 计算能力_mx250显卡性能怎么样,mx250显卡性能相当于GTX多少
  13. 和平精英镜头灵敏度怎么调到最稳呢
  14. jsp70860基于web的大学教室管理系统
  15. Katago围棋学习记录(一)
  16. 从“心”认识Vue(五):父组件与子组件
  17. 野火EBF 6ULL 开发板 烧录ubuntu18 emmc 固件 并安装桌面
  18. 面向对象开发方法,Coad方法、Booch方法和OMT方法及UML
  19. 数据库应用-E commerce管理
  20. python基础教程:Python中利用sqrt()方法进行平方根计算的教程

热门文章

  1. 打造先进的SOA应用 -- 很值得一看
  2. 量化:年化收益、期初收益、期末收益、年份,任意3个值计算剩下的1个值
  3. 可信云大会上,腾讯安全解锁多项新认证!
  4. 科大讯飞语音识别C++版本SDK集成测试的一些问题,工具VS+QT
  5. SpringBoot+Vue项目计算机等级考试报名系统
  6. 用 js 实现倒计时
  7. springcloud+zipkin实现链路监控搭建zipkin-server(五)
  8. SpringBoot 2 缓存数据至 Pivotal GemFire
  9. SQL语句中删除表数据drop、truncate和delete的用法
  10. 【js基础】js实现日期格式化