redis查看key的过期时间_面试官:Redis过期后key是怎么样清理的?
前言
笔者一个同事面试某大厂时问到的一个问题,这里拿来讲讲:Redis过期后key是怎么样清理的?
在Redis中,对于过期key的清理主要有惰性清除,定时清理,内存不够时清理三种方法,下面我们就来具体看看这三种清理方法。
惰性清除
在访问key时,如果发现key已经过期,那么会将key删除。
定时清理
Redis配置项hz定义了serverCron任务的执行周期,默认每次清理时间为25ms,每次清理会依次遍历所有DB,从db随机取出20个key,如果过期就删除,如果其中有5个key过期,那么就继续对这个db进行清理,否则开始清理下一个db。
内存不够时清理
当执行写入命令时,如果发现内存不够,那么就会按照配置的淘汰策略清理内存,淘汰策略一般有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 hashMap = new HashMap(); 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算法的设计原则时,如果一个数据在最近一段时间被访问的时次数越多,那么之后被访问的概率会越大,基本实现是每个数据都有一个引用计数,每次数据被访问后,引用计数加1,需要淘汰数据时,淘汰引用计数最小的数据。在Redis的实现中,每次key被访问后,引用计数是加一个介于0到1之间的数p,并且访问越频繁p值越大,而且在一定的时间间隔内,如果key没有被访问,引用计数会减少。
redis查看key的过期时间_面试官:Redis过期后key是怎么样清理的?相关推荐
- redis查看key的过期时间_面试官:你在Redis中设置过带过期时间的Key吗?
点击上方小伟后端笔记关注公众号 每天阅读Java干货文章 熟悉Redis的同学应该知道,Redis的每个Key都可以设置一个过期时间,当达到过期时间的时候,这个key就会被自动删除. 在为key设置过 ...
- redis list设置过期时间_面试官:你在Redis中设置过带过期时间的Key吗?
点击上方小伟后端笔记关注公众号 每天阅读Java干货文章 熟悉Redis的同学应该知道,Redis的每个Key都可以设置一个过期时间,当达到过期时间的时候,这个key就会被自动删除. 在为key设置过 ...
- redis做mysql缓存的优点_面试官:如何保障数据库和redis缓存的一致性
随着互联网的高速发展,使用互联网产品的人也越来越多,团队不可避免得也会面对越来越复杂的高并发业务场景(如下图),比如热点视频/文章的观看(读场景),热点视频/文章的评论,点赞等(写场景). 众所周知, ...
- httpclient 设置超时时间_面试官:技术选型,HttpClient还是OkHttp?
你知道的越多,不知道的就越多,业余的像一棵小草! 你来,我们一起精进!你不来,我和你的竞争对手一起精进! 编辑:业余草 来源:juejin.im/post/6844904040644476941 推荐 ...
- 设置过期时间_在Redis中设置了过期时间的Key,需要注意哪些问题?
点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者:千山qianshan juejin.im/post/5d6b ...
- redis setnx 过期时间_阿里面试官:你确定你用过 Redis 分布式锁吗?
你有听说过 Redlock 吗? 别整些花里胡哨的,Redlock 全称 Redis Distributed Lock,即用 Redis 实现的分布式锁. Redis 热身知识 Redis 命令参考: ...
- redis 设置不过期_面试时 Redis 内存淘汰总被问,但是总答不好,怎么解决?
什么是内存淘汰 内存淘汰,和平时我们设置redis key的过期时间,不是一回事:内存淘汰是说,假设我们限定redis只能使用8g内存,现在已经使用了这么多了(包括设置了过期时间的key和没设过期时间 ...
- c# redis 如何设置过期时间_Spring cache整合Redis,并给它一个过期时间!
小Hub领读: 不知道你们有没给cache设置过过期时间,来试试? 上一篇文章中,我们使用springboot集成了redis,并使用RedisTemplate来操作缓存数据,可以灵活使用. 我才懂! ...
- java控制订单过期时间_订单自动过期实现方案
需求分析:24小时内未支付的订单过期失效. 解决方案被动设置:在查询订单的时候检查是否过期并设置过期状态. 定时调度:定时器定时查询并过期需要过期的订单. 延时队列:将未支付的订单放入一个延时队列中, ...
最新文章
- 虚拟化---简单高效的IT管理模型
- Android应用--简、美音乐播放器获取专辑图片(自定义列表适配器)
- 郑州尚学堂:JAVA常用4种排序方法
- 由Thread.sleep引发的
- php显示服务器拒绝连接失败,php – SMTP ERROR:无法连接到服务器:连接被Office365拒绝(111)...
- mysql 暴力破解 root账号密码
- java agent_如何脚踏实地构建Java Agent
- element中select默认选中第一个_探索在网页中使用“标注”
- 【Animation】 使用handler和Runnable实现某一个控件的抖动效果
- 处理minist数据集,把网络和数据都放在gpu上面。
- 通信(1)---LTE 整体架构
- 创建ASPState数据库
- python菜鸟教程网-Python JSON
- 雷林鹏分享:MySQL DELETE 语句
- 树莓派小实验 | 制作一个带快门的照相机 录像机
- 桌面快捷方式计算机打不开,桌面快捷方式打不开,详细教您桌面快捷方式打不开怎么解决...
- [OpenCV实战]23 使用OpenCV获取高动态范围成像HDR
- 智能DNS之DNS原理与解析
- SDUT-3337 计算长方体、四棱锥的表面积和体积(JAVA*)
- 破解Windows7开机密码
热门文章
- 福师离线 微型计算机与外部,福师《计算机应用基础》离线作业答案
- android图片分辨率改变,android 通过修改图片像素实现CircleImageView
- python编程学习_使用EduBlocks轻松学习Python编程
- 敏捷团队为何失败,Bash技巧,Emacs vs. Vim,为Linux粉丝撰写的12部小说读物,以及其他热门歌曲
- devops 开发_DevOps如何消除开发瓶颈
- 互联网 性能 开源_开源的互联网25年及未来
- java string范围_字符串索引超出范围? (Java,子字符串循环...
- ROS笔记(26) Movelt!
- mysql benchmark 测试工具_BenchmarkSQL数据库基准测试工具
- pb调用键盘钩子的例子_搞不动Vue3.0的源码,先做个API调用师也行(新人踩坑初试)...