【大厂面试02期】Redis过期key是怎么样清理的?
PS:本文已收录到1.1K Star数开源学习指南——《大厂面试指北》,如果想要了解更多大厂面试相关的内容,了解更多可以看
http://notfound9.github.io/interviewGuide/#/docs/BATInterview
【大厂面试02期】Redis过期key是怎么样清理的?
在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<String, Node>来实现,每次访问元素后,将元素移动到链表头部,当元素满了时,将链表尾部的元素移除,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没有被访问,引用计数会减少。
最后
大家有什么想法,可以一起讨论!
【大厂面试02期】Redis过期key是怎么样清理的?的更多相关文章
- redis过期key的清理策略
一,有三种不同的删除策略(1),立即清理.在设置键的过期时间时,创建一个回调事件,当过期时间达到时,由时间处理器自动执行键的删除操作. (2),惰性清理.键过期了就过期了,不管.当读/写一个已经过期的 ...
- Redis过期key淘汰策略
Redis采用惰性+定期的key淘汰策略 1. Redis配置项hz定义了serverCron任务的执行周期,默认为10,即CPU空闲时每秒执行10次; 2. 每次过期key清理的时间不超过CPU时间 ...
- 【大厂面试07期】说一说你对synchronized锁的理解?
synchronized锁的原理也是大厂面试中经常会涉及的问题,本文主要通过对以下问题进行分析讲解,来帮助大家理解synchronized锁的原理. 1.synchronized锁是什么?锁的对象是什 ...
- 【大厂面试08期】谈一谈你对HashMap的理解?
摘要 HashMap的原理也是大厂面试中经常会涉及的问题,同时也是工作中常用到的Java容器,本文主要通过对以下问题进行分析讲解,来帮助大家理解HashMap的原理. 1.HashMap添加一个键值对 ...
- redis过期key监听事件
目录 redis安装 docker拉取 启动 redis 配置 命令监听 问题 程序监听 具体监听类 效果 总结 redis常用语缓存操作,但是redis功能不仅仅于此.今天我们来看看redis的ke ...
- 面试官:Redis 过期删除策略和内存淘汰策略有什么区别?
作者:小林coding 计算机八股文网站:https://xiaolincoding.com 大家好,我是小林. Redis 的「内存淘汰策略」和「过期删除策略」,很多小伙伴容易混淆,这两个机制虽然都 ...
- 【大厂面试03期】MySQL是怎么解决幻读问题的?
问题分析 首先幻读是什么? 根据MySQL文档上面的定义 The so-called phantom problem occurs within a transaction when the same ...
- 【大厂面试06期】谈一谈你对Redis持久化的理解?
Redis持久化是面试中经常会问到的问题,这里主要通过对以下几个问题进行分析,帮助大家了解Redis持久化的实现原理. 1.Redis持久化是什么? 2.Redis持久化有哪些策略?各自的实现原理是怎 ...
- SpringBoot监听redis过期key
开启过期监听 vim /etc/redis.conf 取消notify-keyspace-events Elg的注释 pom.xml 添加: <dependency> <groupI ...
随机推荐
- spring mvc实现转发和重定向
转发:服务器端请求的跳转 同一个请求之内 重定向:客户端请求的跳转 两次请求 转发和重定向的区别: 1,转发地址栏不会发生变化,重定向地址栏会发生变化. 2,转发请求的参数不会丢失 重定向参数会丢失. ...
- MySQL基础总结(二)
数据表的完整性约束条件 AUTO_INCREMENT (自增长) 注意事项: 1.一个表中只能有一个自增长字段 2.必须配合主键使用 方法1: 方法2: 方法3: 指定自增长初始值的方法: 修改自增长 ...
- FPGA自计数六位共阳极数码管动态显示2(调用task的方法)
`timescale 1ns/1ps module adc_dis( clk , rst_n , sm_seg , sm_bit ); input clk;//50HZ input rst_n; :] ...
- Luogu P3389 高斯消元
https://www.luogu.com.cn/problem/P3389 主元消元法[模板] 高斯消元是解决多元线性方程组的方法,再学习它之前,先引入一个东西--行列式 行列式的性质: 这里我们只 ...
- struts2 进阶--异常捕获机制
在SpringMvc中有自己的异常处理机制,struts2当然会有此功能,主要是在struts.xml中配置: <bean type="com.opensymphony.xwork2. ...
- Typora + Powershell/bash + Git搭建自己的笔记
网上都说什么onenote,evernote,ant等笔记.个人感觉这些都不算太好,还是自己用简易东西搭建一个笔记. 个人推荐使用typora写笔记. 上面既有文件目录,还能通过模糊搜索. 然后需要p ...
- Web安全工程师(网易微专业Web安全学习笔记)
本篇笔记的配套视频:网易云课堂,微专业/web安全工程师. 一.WEB基础知识 1.1 Web简介 1.1.1 Web介绍 1)web的发展 web1.0:以内容为中心,网站提供内容信息,用户进行访问 ...
- Request.params,Request.form,Request.querystring区别(转)
自己总结:---大致意思是: 1.传参的方式分为:get方式传参,post方式传参,request.cookies和request.servervariables 2.这几种获取参数方式获取的都是一个 ...
- 树状数组区间更新区间查询以及gcd的logn性质
题目描述 给你一个长为n的序列a m次查询 每次查询一个区间的所有子区间的gcd的和mod1e9+7的结果 输入描述: 第一行两个数n,m之后一行n个数表示a之后m行每行两个数l,r表示查询的区间 输 ...
- Centos 安装 Anaconda
# 首先从 Anaconda 官网下载 anaconda Linux 64Bit 版本命令行安装包 $ wget https://repo.continuum.io/archive/Anaconda3 ...