一、配置Redis内存淘汰策略

maxmemory 100mbmaxmemory-policy allkeys-lrumaxmemory-samples 5

注意:Redis的LRU算法并非完整的实现,而是近似LRU的算法,详细介绍点击这里

二、LRU实现原理

1、双向链表 + 哈希表

1、哈希表:查找快,但是哈希表的数据是乱序的。
2、链表:插入、删除都很快,但是查询慢。

  • 1.每次默认从链表头部添加元素,那么显然越靠近头部的元素就越是最近使用的。越靠近尾部的元素就是越久未使用的。
  • 2.对于某一个 key ,可以通过哈希表快速定位到链表中的节点,从而取得对应的 value。
  • 3.链表显然是支持在任意位置快速插入和删除的,修改指针就行。但是单链表无法按照索引快速访问某一个位置的元素,都是需要遍历链表的,所以这里借助哈希表,可以通过 key,快速的映射到任意一个链表节点,然后进行插入和删除。

1、为什么这里要用双链表呢,单链表为什么不行?
答:双链表删除元素除了自己本身的指针信息,前驱节点的指针和后驱节点的指针。单链表只有后驱节点的指针。
2、哈希表里面已经保存了 key ,那么链表中为什么还要存储 key 和 value 呢,只存入 value 不就行了?
答:删除哈希表中的数据需要通过双链表中的key,才能删除对应value。

三、PHP实现LRU

源码位置

/*** LRU算法* 构造一个双向链表(双向链表删除尾部节点的上一个元素时间复杂度为O(1))*/
class LRUCache
{//头部节点private $head;//尾部节点private $tail;//最大容量,大于淘汰尾部节点指向的上一个元素private $capacity;//存放key对应的节点 key => nodeprivate $hashmap;/*** 初始化头部尾部节点* LRUCache constructor.* @param $capacity*/public function __construct($capacity){$this->capacity = $capacity;$this->hashmap = array();$this->head = new Node(null, null);$this->tail = new Node(null, null);//头结点右指针指向尾结点$this->head->setNext($this->tail);//尾结点左指针指向头结点$this->tail->setPrevious($this->head);}/*** 获取元素* @param $key* @return null*/public function get($key){if (!isset($this->hashmap[$key])) {return null;}$node = $this->hashmap[$key];if (count($this->hashmap) == 1) {return $node->getData();}//先删除已经存在的结点$this->detach($node);//重新将新结点插入到头结点之后$this->attach($this->head, $node);return $node->getData();}/*** 设置key value* @param $key* @param $data* @return bool*/public function put($key, $data){if ($this->capacity <= 0) {return false;}if (isset($this->hashmap[$key]) && !empty($this->hashmap[$key])) {$node = $this->hashmap[$key];//重置结点到头结点之后$this->detach($node);$this->attach($this->head, $node);$node->setData($data);} else {$node = new Node($key, $data);$this->hashmap[$key] = $node;//添加节点到头部节点之后$this->attach($this->head, $node);//检测容量是否达到最大值if (count($this->hashmap) > $this->capacity) {//如果达到最大值 删除尾节点左指针指向的元素$nodeToRemove = $this->tail->getPrevious();$this->detach($nodeToRemove);unset($this->hashmap[$nodeToRemove->getKey()]);}}return true;}/*** 删除key* @param $key* @return bool*/public function remove($key){if (!isset($this->hashmap[$key])) {return false;}$nodeToRemove = $this->hashmap[$key];$this->detach($nodeToRemove);unset($this->hashmap[$nodeToRemove->getKey()]);return true;}/*** 添加新结点到头结点之后* @param $head* @param $node*/private function attach($head, $node){//双向链表插入一个元素到头结点之后$node->setPrevious($head);$node->setNext($head->getNext());$node->getNext()->setPrevious($node);$node->getPrevious()->setNext($node);}/*** 删除结点* @param $node*/private function detach($node){$node->getPrevious()->setNext($node->getNext());$node->getNext()->setPrevious($node->getPrevious());}}/*** 结点数据结构*/
class Node
{private $key;//key对应的内容private $data;//结点右指针private $next;//结点左指针private $previous;/*** Node constructor.* @param $key* @param $data*/public function __construct($key, $data){$this->key = $key;$this->data = $data;}/*** 设置节点数据的新值* Sets a new value for the node data* @param string the new content of the node*/public function setData($data){$this->data = $data;}/*** 将节点设置为下一个节点* Sets a node as the next node* @param Node $next the next node*/public function setNext($next){$this->next = $next;}/*** 将节点设置为前一个节点* Sets a node as the previous node* @param Node $previous the previous node*/public function setPrevious($previous){$this->previous = $previous;}/*** 返回节点键* Returns the node key* @return string the key of the node*/public function getKey(){return $this->key;}/*** 返回节点数据* Returns the node data* @return mixed the content of the node*/public function getData(){return $this->data;}/*** 返回下一个节点, 该节点的下一个节点* Returns the next node* @return Node the next node of the node*/public function getNext(){return $this->next;}/*** 返回上一个节点, 该节点的上一个节点* Returns the previous node* @return Node the previous node of the node*/public function getPrevious(){return $this->previous;}}$lru = new LRUCache(4);
$lru->put(1, 1111);
$lru->put(2, 2222);
$lru->put(3, 3333);
//$lru->put(3, 3333);
//$lru->put(4, 4444);
//var_dump($lru->get(2));
//var_dump($lru->get(1));

学习地址

Redis LRU算法相关推荐

  1. 十二、Redis LRU算法详述(Least Recently Used - 最近最少使用)

    简介 Redis是基于内存存储的 key-value 数据库.我们都知道,内存虽然快但空间大小有限,当物理内存达到上限时,系统就会跑的很慢,这是因为 swap 机制会将部分内存的数据转移到swap分区 ...

  2. java 最少使用(lru)置换算法_「Redis源码分析」Redis中的LRU算法实现

    如果对我的文章感兴趣.希望阅读完可以得到你的一个[三连],这将是对我最大的鼓励和支持. LRU是什么 LRU(least recently used)是一种缓存置换算法.即在缓存有限的情况下,如果有新 ...

  3. Redis LRU 淘汰原理

    思考(作业):基于一个数据结构做缓存,怎么实现LRU--最长时间不被访问的元素在超过容量时删除? 问题:如果基于传统LRU 算法实现Redis LRU 会有什么问题? 需要额外的数据结构存储,消耗内存 ...

  4. lru算法实现 redis_Redis中的lru算法实现

    lru是什么 lru(least recently used)是一种缓存置换算法.即在缓存有限的情况下,如果有新的数据需要加载进缓存,则需要将最不可能被继续访问的缓存剔除掉.因为缓存是否可能被访问到没 ...

  5. Redis的LRU算法

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

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

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

  7. redis——Redis中的LRU算法改进

    redis通常使用缓存,是使用一种固定最大内存的使用.当数据达到可使用的最大固定内存时,我们需要通过移除老数据来获取空间.redis作为缓存是否有效的重要标志是如何寻找一种好的策略:删除即将需要使用的 ...

  8. Redis[5] key的过期时间删除策略、实现lru算法、持久化配置

    文章目录 Redis[5] key的过期时间删除策略.持久化配置 **Redis6的key过期时间删除策略** Redis服务器实际使用的是惰性删除和定期删除两种策略:通过配合使用这两种删除策略,服务 ...

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

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

最新文章

  1. oracle查看联机日志,oracle联机日志和归档日志
  2. 人眼中亮斑的检测、定位和去除(2)
  3. iShow UI for React 最佳实践
  4. boost::errinfo_errno的用法测试程序
  5. Nslookup-查dns
  6. AtCoder Regular Contest 125
  7. Linux下将mysql数据导入与导出
  8. python2处理耗时任务_RabbitMQ Go客户端教程2——任务队列/工作队列
  9. 大话设计模式-策略模式与简单工厂模式
  10. 『震惊』秘密报告披露转基因食品危害
  11. 【今日CS 视觉论文速览】Thu, 13 Dec 2018
  12. 【Oracle】查询当前SCN
  13. 速进,双十一内购通道!
  14. ISA2000资料大全(详细)
  15. 计算机与英语相关工作,计算机行业岗位英语单词整合
  16. 配置计算机老是重启,电脑无缘无故重启是什么原因_电脑老是无故自动重启如何解决-win7之家...
  17. 使用RDO Packstack在CentOS 8上安装版本为Victoria的openstack
  18. 计算机专业黑板报迎新,新学期迎新黑板报
  19. Flink 实时数仓伪分布虚拟机 (所有组件部署完成)
  20. 百度AI的2020:新基建铺路,硬实力出圈

热门文章

  1. 深空探测处理软件USGS-ISIS的下载安装
  2. 案例总结,用户体系6个难点 |如何落地,利用数据、函数模型用户成长体系
  3. EasyX中使用背景音乐
  4. 抄底摸顶的高概率交易技巧
  5. 天猫双十一、小米MIX和讯飞输入法:中国大公司开玩“近创新”
  6. Linux下修改ip地址,网关
  7. jQuery——深浅拷贝
  8. 揭秘手游外挂:基于内存蜜罐的内存修改挂分析技术
  9. 2017款MacBookPro13''上手体验及购买建议
  10. 一个在期货市场狂赚10亿的大佬,他的辛酸谁能懂?