2019独角兽企业重金招聘Python工程师标准>>>

Redis中的LRU

Redis被当做缓存来使用,当你新增数据时,让它自动地回收旧数据是件很方便的事情。LRU 实际上是被唯一支持的数据移除方法。

实际中,redis并没有严格遵循LRU的思路去回收旧的数据,具体的redis关于LRU的实现,可以参考这篇文章https://www.cnblogs.com/houziwty/p/5129946.html

本次我们主要使用java实现LRU算法

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

实现思路:

对一个Cache的操作无非三种:插入(insert)、替换(replace)、查找(lookup)。
为了能够快速删除最久没有访问的数据项和插入最新的数据项,我们使用 双向链表 连接Cache中的数据项,并且保证链表维持数据项从最近访问到最旧访问的顺序。

  • 插入:当Cache未满时,新的数据项只需插到双链表头部即可。时间复杂度为O(1)O(1).
  • 替换:当Cache已满时,将新的数据项插到双链表头部,并删除双链表的尾结点即可。时间复杂度为O(1)O(1).
  • 查找:每次数据项被查询到时,都将此数据项移动到链表头部。

经过分析,我们知道使用双向链表可以保证插入和替换的时间复杂度是O(1)O(1),但查询的时间复杂度是O(n)O(n),因为需要对双链表进行遍历。为了让查找效率也达到O(1)O(1),很自然的会想到使用 hash table 。

代码实现:

1.定义一个Node节点

public class Node {int key;int value;Node pre;Node next;public Node(int key, int value) {this.key = key;this.value = value;}}

2.LRUCache.java

public class LRUCache {/*** 缓存大小*/private int capacity;HashMap<Integer, Node> map = new HashMap<>();/*** 头结点*/private Node head = null;/*** 尾节点*/private Node end = null;/*** 初始化缓存大小*/public LRUCache(int capacity) {this.capacity = capacity;}/*** 删除节点*/public void remove(Node node) {//需要注意变更pre,end指针情况if (node.pre != null) {node.pre.next = node.next;} else {head = node.next;}if (node.next != null) {node.next.pre = node.pre;} else {end = node.pre;}}/*** 设置头节点*/public void setHead(Node node) {node.next = head;node.pre  =null;if (head != null) {head.pre = node;}head = node;//判断头尾是否为空if (end == null) {end = head;}}/**获取一个缓存数据后,应该把这个数据在当前位置删除掉,然后把它重新添加到头的位置* @param key* @return*/public int get(int key) {if (map.containsKey(key)) {Node node = map.get(key);remove(node);setHead(node);return node.value;}return -1;}/**s设置指定位置的数据* @param key* @param value*/public void set(int key, int value) {//如果该位置有元素,那么就替换数据,将其放入头结点if (map.containsKey(key)) {Node old = map.get(key);old.value = value;remove(old);setHead(old);} else {//如果是新的节点就要判断集合大小是否满足,并将新节点设置到头结点Node created = new Node(key, value);if (map.size()>=capacity) {map.remove(end.key);remove(end);setHead(created);} else {setHead(created);}map.put(key, created);}}
}

转载于:https://my.oschina.net/CentralD/blog/1833545

Redis与LRU实现相关推荐

  1. Redis的LRU算法

    2019独角兽企业重金招聘Python工程师标准>>> 整理自官方文档:将redis当做使用LRU算法的缓存来使用 当Redis被当做缓存来使用,当你新增数据时,让它自动地回收旧数据 ...

  2. redis的lru原理_Redis的LRU算法

    Redis的LRU算法 LRU算法背后的的思想在计算机科学中无处不在,它与程序的"局部性原理"很相似.在生产环境中,虽然有Redis内存使用告警,但是了解一下Redis的缓存使用策 ...

  3. 使用 Redis 作为 LRU 缓存

    使用 Redis 作为 LRU 缓存 https://redis.io/topics/lru-cache 当 Redis 用作缓存时,通常可以很方便地让它在您添加新数据时自动淘汰旧数据.这种行为在开发 ...

  4. Redis 之 LRU 与 LFU

    一.前述 Redis 一直在 Nosql 中占据着很重要的地位,阅读官方文档以及 github 源代码,是一种非常好的能够帮助提升的方式,本系列博文主要参考官网翻译.Github 源代码以及部分自己的 ...

  5. redis的lru原理_Redis的LRU机制介绍

    高并发架构系列:Redis的内存回收原理,及内存过期淘汰策略详解 Redis内存回收机制 Redis的内存回收主要围绕以下两个方面: 1.Redis过期策略删除过期时间的key值 **2.Redis淘 ...

  6. (转帖)Redis的LRU和LFU区别

    常见的缓存算法: LRU (Least recently used) 最近最少使用,如果数据最近被访问过,那么将来被访问的几率也更高. LFU (Least frequently used) 最不经常 ...

  7. Redis的LRU缓存淘汰算法实现

    1 标准LRU的实现原理 LRU,最近最少使用(Least Recently Used,LRU),经典缓存算法. LRU会使用一个链表维护缓存中每个数据的访问情况,并根据数据的实时访问,调整数据在链表 ...

  8. 将redis当做使用LRU算法的缓存来使用

    当Redis被当做缓存来使用,当你新增数据时,让它自动地回收旧数据是件很方便的事情.这个行为在开发者社区非常有名,因为它是流行的memcached系统的默认行为. LRU是Redis唯一支持的回收方法 ...

  9. redis lru和lfu的实现

    在redis的lru的实现与传统的lru实现不同. 具体实现在evict.c文件中,当redis需要通过释放缓存的key来释放空间时,将会通过ecict.c的freeMemoryIfNeeded()函 ...

  10. node怎么把token放到redis_从零开始手写 redis(八)朴素 LRU 淘汰算法性能优化

    前言 java从零手写实现redis(一)如何实现固定大小的缓存? java从零手写实现redis(三)redis expire 过期原理 java从零手写实现redis(三)内存数据如何重启不丢失? ...

最新文章

  1. GitLab 密码重设
  2. hexo的yilia主题鼠标点击出现小红心
  3. 省市区三级联动 最新县及县以上行政区划代码 来源:国家统计局
  4. C++之字节对齐与结构体大小
  5. How to resolve syntax error in CL_IM_CMS_SI_GEN_INTF
  6. python学习笔记(15)循环设计
  7. php默认日志位置,Laravel 修改默认日志文件名称和位置的例子
  8. 使用cocoapods导入第三方类库后 头文件没有代码提示?
  9. 机器学习专题(二):2.1机器学习的数据
  10. nmon和nmon analyser使用方法
  11. 项目源码--Android聚合视频类播放器
  12. linux 使用 雅黑字体,linux 使用微软雅黑字体
  13. GitLab CI/CD 基础教程(一)
  14. 网页计算器 html代码原理,HTML网页之计算器代码
  15. 机器学习常见任务类型
  16. 直流电机驱动模块开发,为电子设备提供动力之源
  17. ZB雕刻用鼠标和数位板的差别大不大?怎么买手绘板?ZB雕刻手绘是不是很重要?
  18. 计算机中符号位正负,负数在计算机中的表示+有符号无符号的区别+负数按位运算...
  19. matlab 和 numpy 矩阵乘法异同
  20. Echarts实现世界地图

热门文章

  1. K-Means优缺点
  2. must be str,not int
  3. 前端为什么有的接口明明是成功回调却执行了.catch失败回调_前端战五渣学JavaScript——Promise...
  4. UnboundLocalError: local variable 'XXX' referenced before assignment
  5. 浅谈算法和数据结构: 六 符号表及其基本实现
  6. 孤立森林(iForest - Isolation Forest)
  7. 详细介绍各种常见的分布
  8. Linux微信群shell,linux shell基础
  9. MySQL蜜罐在护网中提取攻击者微信ID
  10. SCUT - 12 - 西方国家 - 矩阵快速幂