在Redis中,对于过期key的清理主要有惰性清除,定时清理,内存不够时清理三种方法,下面我们就来具体看看这三种清理方法。

(1)惰性清除

在访问key时,如果发现key已经过期,那么会将key删除。

(2)定时清理

Redis配置项hz定义了serverCron任务的执行周期,默认每次清理时间为25ms,每次清理会依次遍历所有DB,从db随机取出20个key,如果过期就删除,如果其中有5个key过期,那么就继续对这个db进行清理,否则开始清理下一个db。

(3)内存不够时清理

当执行写入命令时,如果发现内存不够,那么就会按照配置的淘汰策略清理内存,淘汰策略一般有6种,Redis4.0版本后又增加了2种,主要由分为三类

第一类 不处理,等报错(默认的配置)

noeviction,发现内存不够时,不删除key,执行写入命令时直接返回错误信息。(Redis默认的配置就是noeviction)

第二类 从所有结果集中的key中挑选,进行淘汰

allkeys-random 就是从所有的key中随机挑选key,进行淘汰

allkeys-lru 就是从所有的key中挑选最近使用时间距离现在最远的key,进行淘汰

allkeys-lfu 就是从所有的key中挑选使用频率最低的key,进行淘汰。(这是Redis 4.0版本后新增的策略)

第三类 从设置了过期时间的key中挑选,进行淘汰

这种就是从设置了expires过期时间的结果集中选出一部分key淘汰,挑选的算法有:

volatile-random 从设置了过期时间的结果集中随机挑选key删除。

volatile-lru 从设置了过期时间的结果集中挑选上次使用时间距离现在最久的key开始删除

volatile-ttl 从设置了过期时间的结果集中挑选可存活时间最短的key开始删除(也就是从那些快要过期的key中先删除)

volatile-lfu 从过期时间的结果集中选择使用频率最低的key开始删除(这是Redis 4.0版本后新增的策略)

LRU算法

LRU算法的设计原则是如果一个数据近期没有被访问到,那么之后一段时间都不会被访问到。所以当元素个数达到限制的值时,优先移除距离上次使用时间最久的元素。

可以使用双向链表Node+HashMap来实现,每次访问元素后,将元素移动到链表头部,当元素满了时,将链表尾部的元素移除,HashMap主要用于根据key获得Node以及添加时判断节点是否已存在和删除时快速找到节点。

PS:使用单向链表能不能实现呢,也可以,单向链表的节点虽然获取不到pre节点的信息,但是可以将下一个节点的key和value设置在当前节点上,然后把当前节点的next指针指向下下个节点,这样相当于把下一个节点删除了

//双向链表

public static class ListNode {

String key;//这里存储key便于元素满时,删除尾节点时可以快速从HashMap删除键值对

Integer value;

ListNode pre = null;

ListNode next = null;

ListNode(String key, Integer value) {

this.key = key;

this.value = value;

}

}

ListNode head;

ListNode last;

int limit=4;

HashMap<String, ListNode> hashMap = new HashMap<String, ListNode>();

public void add(String key, Integer val) {

ListNode existNode = hashMap.get(key);

if (existNode!=null) {

//从链表中删除这个元素

ListNode pre = existNode.pre;

ListNode next = existNode.next;

if (pre!=null) {

pre.next = next;

}

if (next!=null) {

next.pre = pre;

}

//更新尾节点

if (last==existNode) {

last = existNode.pre;

}

//移动到最前面

head.pre = existNode;

existNode.next = head;

head = existNode;

//更新值

existNode.value = val;

} else {

//达到限制,先删除尾节点

if (hashMap.size() == limit) {

ListNode deleteNode = last;

hashMap.remove(deleteNode.key);

//正是因为需要删除,所以才需要每个ListNode保存key

last = deleteNode.pre;

deleteNode.pre = null;

last.next = null;

}

ListNode node = new ListNode(key,val);

hashMap.put(key,node);

if (head==null) {

head = node;

last = node;

} else {

//插入头结点

node.next = head;

head.pre = node;

head = node;

}

}

}

public ListNode get(String key) {

return hashMap.get(key);

}

public void remove(String key) {

ListNode deleteNode = hashMap.get(key);

ListNode preNode = deleteNode.pre;

ListNode nextNode = deleteNode.next;

if (preNode!=null) {

preNode.next = nextNode;

}

if (nextNode!=null) {

nextNode.pre = preNode;

}

if (head==deleteNode) {

head = nextNode;

}

if (last == deleteNode) {

last = preNode;

}

hashMap.remove(key);

}

LFU算法

LFU算法的设计原则是,如果一个数据在最近一段时间被访问的时次数越多,那么之后被访问的概率会越大,基本实现是每个数据都有一个引用计数,每次数据被访问后,引用计数加1,需要淘汰数据时,淘汰引用计数最小的数据。在Redis的实现中,每次key被访问后,引用计数是加一个介于0到1之间的数p,并且访问越频繁p值越大,而且在一定的时间间隔内,

如果key没有被访问,引用计数会减少。

Redis过期key是怎么样清理的?相关推荐

  1. Redis过期key是怎么清理的

    过期删除策略 删除到达过期时间的 key . 第一种:定时检查删除 对于每一个设置了过期时间的 key 都会创建一个定时器,一旦达到过期时间都会删除.这种方式立即清除过期数据,对内存比较好, 但是有缺 ...

  2. Redis 过期 key 清理删除策略汇总

    Redis 底层使用了三种策略来清理过期的key 一.被动清理 触发条件:读/写一个已经过期的key 当读写一个key时,Redis首先检查key是否存在,若存在且已经过期,则删除key的同时返回ni ...

  3. Redis 过期 key 删除,那些不得不说的事情!

    点击关注公众号,利用碎片时间学习 1.过期key的删除策略 定时删除:当为key设置过期时间的时候,设置一个定时任务,到时间后即刻调用并删除 定期删除:每隔一定的时间,对某些key进行扫描,并删除掉其 ...

  4. redis过期key的清理/删除策略

    一,有三种不同的删除策略 立即清理.在设置键的过期时间时,创建一个回调事件,当过期时间达到时,由时间处理器自动执行键的删除操作. 惰性清理.键过期了就过期了,不管.当读/写一个已经过期的key时,会触 ...

  5. redis过期key的删除策略

    前言 在使用redis的过程中,不免会产生过期的key,而这些key过期后并不会实时地马上被删除,当这些key数量累积越来越多,就会占用很多内存,因此在redis底层同时使用了三种策略来删除这些key ...

  6. redis过期key监听事件

    文章目录 redis安装 docker拉取 启动 redis 配置 命令监听 问题 程序监听 具体监听类 效果 总结 redis常用语缓存操作,但是redis功能不仅仅于此.今天我们来看看redis的 ...

  7. 2022-04-12 redis过期key删除策略

    1 定时删除: 在设置键过期时间的同时,创建一个定时器,让定时器在过期时间来临时,立即执行对键的删除操作; 这样做有一个弊端,就是当有很多key同一时间过期的时候,会造成一时间的CPU紧张,从而可能影 ...

  8. SpringBoot监听redis过期key

    开启过期监听 vim /etc/redis.conf 取消notify-keyspace-events Elg的注释 pom.xml 添加: <dependency><groupId ...

  9. redis查看key的过期时间_面试官:Redis过期后key是怎么样清理的?

    前言 笔者一个同事面试某大厂时问到的一个问题,这里拿来讲讲:Redis过期后key是怎么样清理的? 在Redis中,对于过期key的清理主要有惰性清除,定时清理,内存不够时清理三种方法,下面我们就来具 ...

最新文章

  1. 量子通信是不是伪科学?潘建伟这样回应
  2. 判断一个单链表中是否有环
  3. 牛客 -- leetcode -- max-points-on-a-line
  4. python安装不上怎么办_python安装不了怎么办
  5. UI素材干货模板|线框图wireframe线框图iOS设计稿
  6. EasyUI,对treegrid进行编辑
  7. FFMPEG结构体分析:AVFormatContext
  8. VVC/JEM代码学习16:xCheckRDCostMerge2Nx2N
  9. php寻仙记,寻仙记文字游戏完整实测源码 - 下载 - 搜珍网
  10. 杨辉三角 Python(利用嵌套列表)
  11. 【SEAN的日志】如何突破微信小程序2M限制?
  12. linux如何卸载光驱显示busy,执行umount 的时候却提示:device is busy 的处理方法 卸载挂载的盘提示如下...
  13. 计算机金钱符号怎么打,电脑键盘上怎么打钱的符号
  14. qt webview 忽略 ssl错误 ignoreSslErrors
  15. 使用pg_repack实现在线vacuum
  16. SQL优化(三):子查询和IN,EXISTS用法和优化方法
  17. Mybatis-Plus用纯注解完成一对多多对多查询
  18. java 改变窗口大小_java 如何让程序窗口随屏幕大小改变
  19. 1---电子实物认知
  20. 汽车无钥匙进入系统工作原理、汽车无钥匙进入系统简介

热门文章

  1. 怎样进行一场精彩的知识分享?
  2. 思科:动态nat的配置
  3. ug安装更改计算机名称,ug安装服务器名与主机名相同
  4. 社会性偏好--4.1利他与公平
  5. android 反调试 github,修改Android手机内核,绕过反调试
  6. DNS无法解析IP_AliDNS下载-AliDNS阿里DNS一键设置工具3.8.5.2免费版
  7. Python都纳入新课标了,你还不知道它是什么?
  8. 二麻子,你再不更新我就……
  9. 手把手:四色猜想、七桥问题…程序员眼里的图论,了解下?(附大量代码和手绘)...
  10. 巧用60分钟K线图把握卖点