关于Redis LRU

LRU

选择最近最久未使用的数据予以淘汰。(一种常用的页面置换算法)


谈到LRU我们就不得不说一下Redis的八大淘汰策略

noeviction:不会驱逐任何的key
allkeys-lru:对所有的key使用LRU算法进行删除
volatile-lru:对所有设置了过期时间的key使用LRU算法进行删除
allkeys-random:对所有key随机删除
volatile-random:对所有设置了过期时间的key随机删除
volatile-ttl:删除马上要过期的key
allkeys-lfu:对所有key使用LFU算法进行删除
volatile-lfu:对所有设置了过期时间的key使用LFU算法进行删除


Redis的八大策略用于对Redis本身进行内存优化的策略,通过这一系列的策略可以更好地让Redis存储更多的有用数据,而其中LRU算法更是其中两种策略的核心


核心
关于LRU算法的核心是基于哈希链表(哈希表+双向链表的结合体,时间复杂度O(1))
本质:HashMap+DoubleLinkedList
在这里插入图片描述
在这里插入图片描述
而当我们在面试的时候有时也会被问到是否能够手写LRU算法,所以基于此,我给出下面两种方式


第一种:参考LinkedHashMap(带有结构顺序的Map),LRU算法的天生实现者

在这里插入图片描述
测试结果

在这里插入图片描述
在这里插入图片描述


第二种:不依赖JDK纯手写

public class LRUDemo {    
    //缓存的坑位    
    private int cacheSize;    
    Map<Integer,Node<Integer,Integer>> map;    
    DoubleLinkedList<Integer,Integer> doubleLinkedList;    
    //map负责查找,构建一个虚拟的双向链表,里面安装的就是一个个节点Node,作为数据载体    
    class Node<K,V>    
    {        
        K key;        
        V value;        
        Node<K,V> prev;        
        Node<K,V> next;        
        public Node(){            
            this.prev = this.next = null;        
        }        
        public Node(K key,V value){            
            this.key = key;            
            this.value = value;            
            this.prev = this.next = null;        
        }    
    }    
    //构造一个虚拟的双向链表,里面安放Node    
    class DoubleLinkedList<K,V>    {        
        Node<K,V> head;        //尾节点        
        Node<K,V> tail;        
        public DoubleLinkedList(){            
            head = new Node<>();            
            tail = new Node<>();            
            head.next = tail;            
            tail.prev = head;        
        }        
        //添加到头节点        
        public void addHead(Node<K,V> node){            
            node.next = head.next;            
            node.prev = head;            
            head.next.prev = node;            
            head.next = node;        
        }        
        //删除节点        
        public void removeNode(Node<K,V> node){            
            node.next.prev = node.prev;            
            node.prev.next = node.next;            
            node.prev = null;            
            node.next = null;        
        }        
        //获得最后一个节点        
        public Node getLastNode(){            
            return tail.prev;        
        }    
    }    
    public int get(int key){        
        if(!map.containsKey(key)){            
            return -1;        
        }        
        Node<Integer, Integer> node = map.get(key);
        doubleLinkedList.removeNode(node);        
        doubleLinkedList.addHead(node);        
        return node.value;    
    }    
    public void put(int key,int value){        
        if(map.containsKey(key)){            
            //相当于更新操作            
            Node<Integer, Integer> node = map.get(key);            
            node.value = value;            
            map.put(key,node);            
            doubleLinkedList.removeNode(node);            
            doubleLinkedList.addHead(node);        
        }else{            
            //坑位满            
            if(map.size() == cacheSize){                
                Node<Integer,Integer> lastNode = doubleLinkedList.getLastNode();
                map.remove(lastNode.key);
                doubleLinkedList.removeNode(lastNode);            
            }            
            Node<Integer, Integer> node = new Node<>(key, value);
            map.put(key,node);            
            doubleLinkedList.addHead(node);        
        }    
    }
}

这里就不展示第二种的测试结果了(因为我懒┭┮﹏┭┮),代码应该是没什么问题,感兴趣的话可以尝试自己写一写(●ˇ∀ˇ●)


最后的补充
如何设置Redis的八大策略呢

第一种:命令式

config set maxmemory-policy 策略名

第二种:配置文件
在这里插入图片描述
差不多就到这儿吧,如果有什么补充或者疑问,可以留言哈🤭

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值