当前位置: 首页 > 编程日记 > 正文

redis删除过期key的算法_面试官别再问我Redis内存满了该怎么办了

概述

Redis的文章,我之前写过一篇关于「Redis的缓存的三大问题」,累计阅读也快800了,对于还只有3k左右的粉丝量,能够达到这个阅读量,已经是比较难了。

这说明那篇文章写的还过得去,收到很多人的阅读肯定,感兴趣的看一下[看完这篇Redis缓存三大问题,保你能和面试官互扯。]。

「三大缓存问题」只是Redis的其中的一小部分的知识点,想要深入学习Redis还要学习比较多的知识点。

那么今天就带来了一个面试常问的一个问题:「假如你的Redis内存满了怎么办?」 长期的把Redis作为缓存使用,总有一天会存满的时候对吧。

这个面试题不慌呀,在Redis中有配置参数maxmemory可以「设置Redis内存的大小」

在Redis的配置文件redis.conf文件中,配置maxmemory的大小参数如下所示:

3651a411c2cc45238db216ec14ae30f9.png

实际生产中肯定不是100mb的大小哈,不要给误导了,这里我只是让大家认识这个参数,一般小的公司都是设置为3G左右的大小。

除了在配置文件中配置生效外,还可以通过命令行参数的形式,进行配置,具体的配置命令行如下所示:

//获取maxmemory配置参数的大小
127.0.0.1:6379> config get maxmemory
//设置maxmemory参数为100mb
127.0.0.1:6379> config set maxmemory 100mb

倘若实际的存储中超出了Redis的配置参数的大小时,Redis中有「淘汰策略」,把「需要淘汰的key给淘汰掉,整理出干净的一块内存给新的key值使用」

接下来我们就详细的聊一聊Redis中的淘汰策略,并且深入的理解每个淘汰策略的原理和应用的场景。

淘汰策略

Redis提供了「6种的淘汰策略」,其中默认的是noeviction,这6种淘汰策略如下:

  1. noeviction(「默认策略」):若是内存的大小达到阀值的时候,所有申请内存的指令都会报错。
  2. allkeys-lru:所有key都是使用「LRU算法」进行淘汰。
  3. volatile-lru:所有「设置了过期时间的key使用LRU算法」进行淘汰。
  4. allkeys-random:所有的key使用「随机淘汰」的方式进行淘汰。
  5. volatile-random:所有「设置了过期时间的key使用随机淘汰」的方式进行淘汰。
  6. volatile-ttl:所有设置了过期时间的key「根据过期时间进行淘汰,越早过期就越快被淘汰」

假如在Redis中的数据有「一部分是热点数据,而剩下的数据是冷门数据」,或者「我们不太清楚我们应用的缓存访问分布状况」,这时可以使用allkeys-lru

假如所有的数据访问的频率大概一样,就可以使用allkeys-random的淘汰策略。

假如要配置具体的淘汰策略,可以在redis.conf配置文件中配置,具体配置如下所示:

f9f1f2e5d94258c0ef32f394d33b6a7d.png

这只需要把注释给打开就可以,并且配置指定的策略方式,另一种的配置方式就是命令的方式进行配置,具体的执行命令如下所示:

// 获取maxmemory-policy配置
127.0.0.1:6379> config get maxmemory-policy
// 设置maxmemory-policy配置为allkeys-lru
127.0.0.1:6379> config set maxmemory-policy allkeys-lru

在介绍6种的淘汰策略方式的时候,说到了LRU算法,「那么什么是LRU算法呢?」

LRU算法

LRU(Least Recently Used)即表示最近最少使用,也就是在最近的时间内最少被访问的key,算法根据数据的历史访问记录来进行淘汰数据。

它的核心的思想就是:「假如一个key值在最近很少被使用到,那么在将来也很少会被访问」

实际上Redis实现的LRU并不是真正的LRU算法,也就是名义上我们使用LRU算法淘汰键,但是实际上被淘汰的键并不一定是真正的最久没用的。

Redis使用的是近似的LRU算法,「通过随机采集法淘汰key,每次都会随机选出5个key,然后淘汰里面最近最少使用的key」

这里的5个key只是默认的个数,具体的个数也可以在配置文件中进行配置,在配置文件中的配置如下图所示:

fbbce220077d4663720b78dbf5d77cea.png

当近似LRU算法取值越大的时候就会越接近真实的LRU算法,可以这样理解,因为「取值越大那么获取的数据就越全,淘汰中的数据的就越接近最近最少使用的数据」

那么为了实现根据时间实现LRU算法,Redis必须为每个key中额外的增加一个内存空间用于存储每个key的时间,大小是3字节。

在Redis 3.0中对近似的LRU算法做了一些优化,Redis中会维护大小是16的一个候选池的内存。

当第一次随机选取的采样数据,数据都会被放进候选池中,并且候选池中的数据会根据时间进行排序。

当第二次以后选取的数据,只有「小于候选池内的最小时间」的才会被放进候选池中。

当某一时刻候选池的数据满了,那么时间最大的key就会被挤出候选池。当执行淘汰时,直接从候选池中选取最近访问时间最小的key进行淘汰。

这样做的目的就是选取出最近似符合最近最少被访问的key值,能够正确的淘汰key值,因为随机选取的样本中的最小时间可能不是真正意义上的最小时间。

但是LRU算法有一个弊端:就是假如一个key值在以前都没有被访问到,然而最近一次被访问到了,那么就会认为它是热点数据,不会被淘汰。

然而有些数据以前经常被访问到,只是最近的时间内没有被访问到,这样就导致这些数据很可能被淘汰掉,这样一来就会出现误判而淘汰热点数据。

于是在Redis 4.0的时候除了LRU算法,新加了一种LFU算法,「那么什么是LFU算法算法呢?」

LFU算法

LFU(Least Frequently Used)即表示最近频繁被使用,也就是最近的时间段内,频繁被访问的key,它以最近的时间段的被访问次数的频率作为一种判断标准。

它的核心思想就是:根据key最近被访问的频率进行淘汰,比较少被访问的key优先淘汰,反之则优先保留。

LFU算法反映了一个key的热度情况,不会因为LRU算法的偶尔一次被访问被认为是热点数据。

在LFU算法中支持volatile-lfu策略和allkeys-lfu策略。

以上介绍了Redis的6种淘汰策略,这6种淘汰策略旨在告诉我们怎么做,但是什么时候做?这个还没说,下面我们就来详细的了解Redis什么时候执行淘汰策略。

删除过期键策略

在Redis中有三种删除的操作此策略,分别是:

  1. 「定时删除」:创建一个定时器,定时的执行对key的删除操作。
  2. 「惰性删除」:每次只有再访问key的时候,才会检查key的过期时间,若是已经过期了就执行删除。
  3. 「定期删除」:每隔一段时间,就会检查删除掉过期的key。

「定时删除」对于「内存来说是友好的」,定时清理出干净的空间,但是对于「cpu来说并不是友好的」,程序需要维护一个定时器,这就会占用cpu资源。

「惰性的删除」对于「cpu来说是友好的」,cpu不需要维护其它额外的操作,但是对于「内存来说是不友好的」,因为要是有些key一直没有被访问到,就会一直占用着内存。

定期删除是上面两种方案的折中方案**,每隔一段时间删除过期的key,也就是根据具体的业务,合理的取一个时间定期的删除key**。

通过「最合理控制删除的时间间隔」来删除key,减「少对cpu的资源的占用消耗」,使删除操作合理化。

RDB和AOF 的淘汰处理

在Redis中持久化的方式有两种RDBAOF,具体这两种详细的持久化介绍,可以参考这一篇文章[面试造飞机系列:面对Redis持久化连环Call,你还顶得住吗?]。

在RDB中是以快照的形式获取内存中某一时间点的数据副本,在创建RDB文件的时候可以通过savebgsave命令执行创建RDB文件。

「这两个命令都不会把过期的key保存到RDB文件中」,这样也能达到删除过期key的效果。

当在启动Redis载入RDB文件的时候,Master不会把过期的key载入,而Slave会把过期的key载入。

在AOF模式下,Redis提供了Rewite的优化措施,执行的命令分别是REWRITEAOFBGREWRITEAOF「这两个命令都不会把过期的key写入到AOF文件中,也能删除过期key」

长按订阅更多面经分享

7b5359ffa012faebe905747f24766ffe.png

相关文章:

开源监控解决方案Nagios+Cacti+PNP4Nagios+NConf+NDOUtils+Nagvis(六)ndoutils安装

前面的文章已经说过,NDOUtils必须使用2.0的版本才支持nagios4x,比较幸运的是该版本2014年就已经发布。一.安装#tar -axf ndoutils-2.0.0.tar.gz -C /usr/local/src/#cd /usr/local/src/ndoutils-2.0.0#./configure --prefix/usr/local/nagios LDFLAGS-L/…

网络安全技术分析:DDoS的攻与防

根据墨者安全相关数据研究发现,从今年年初开始,DDoS功击的数量相比去年几乎是翻倍增长,特别是游戏、金融、政企、电商、医疗行业,更是DDoS功击的重灾区,很多企业是闻“D”色变。DDos(Distributed Denial of Service),中…

pcl求平面法向量_线性代数6——平面方程与矩阵

线性方程的几何意义二元线性方程该方程是一个二元线性方程组,包含两个方程,每个方程是一条直线,两条直线的交点就是该方程有唯一解,这就是二元线性方程的几何意义。平面方程空间内不在同一直线上的三点构成一个平面,平…

php 类中的各种拦截器

1、__get( $property ) 访问未定义的属性时调用class lanjie {function __get($name){echo $name." property not found! ";} }$ob new lanjie(); echo $ob->g; 当我们调用对象$ob未定义的属性g时,调用拦截器__get()方法,输出“g property…

[Vue CLI 3] 源码之 webpack-chain

我们看一下 webpack-chain 到底做什么? Use a chaining API to generate and simplify the modification of Webpack version 2-4 configurations.熟悉 cli-plugin-babel、cli-plugin-eslint 源码的话,你会时常看到它。 如何使用呢? 1、加载它 const Co…

openstack页面自定义插件使用详解(django、ajax、post)(zTree为例)

2019独角兽企业重金招聘Python工程师标准>>> 感谢朋友支持本博客,欢迎共同探讨交流,由于能力和时间有限,错误之处在所难免,欢迎指正! 如有转载,请保留源作者博客信息。 Better Me的博客&#xf…

lazyload.js实现图片异步延迟加载

所谓图片异步加载,意思是不用一次把图片全部加载完,你可以叫它延迟加载,缓冲加载都行。 看看你有没有这种需求:某篇文章图片很多,如果在载入文章时就载入所有图片,无疑会延缓载入速度,让用户等…

postfilter中文什么意思_Filterpost请求中文字符编码的过滤器 --学习笔记

java代码:import java.io.IOException;import java.io.PrintWriter;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class Lo…

错误:You can't specify target table 'xxx' for update in FROM clause的解决

今天在MySQL数据库删除重复数据的时候遇到了一个问题。如下脚本: DELETE FROM tempA WHERE tid IN ( SELECT MAX(tid) AS tid FROM tempA GROUP BY name,age ) 会出现报错信息: You cant specify target table tempA for update in FROM clause 大致意思…

HTTPS的七个神话(译文)

原文网址:http://blog.httpwatch.com/2011/01/28/top-7-myths-about-https/ 译文地址:http://www.ruanyifeng.com/blog/2011/02/seven_myths_about_https.html 误解七:HTTPS无法缓存 许多人以为,出于安全考虑,浏览器不…

蓝牙写入数据库_蓝牙 数据写入 简单易懂版(适合没写过蓝牙的看)

//字符串转arrbufferfunction string2buffer(str) {// 首先将字符串转为16进制let val ""for (let i 0; i < str.length; i) {if (val ) {val str.charCodeAt(i).toString(16)} else {val , str.charCodeAt(i).toString(16)}}// 将16进制转化为ArrayBufferr…

Educational Codeforces Round 9 F. Magic Matrix 最小生成树

F. Magic Matrix题目连接&#xff1a; http://www.codeforces.com/contest/632/problem/F Description Youre given a matrix A of size n  n. Lets call the matrix with nonnegative elements magic if it is symmetric (so aij  aji), aii  0 and aij ≤ max(aik, …

【SqlServer】SqlServer中的更新锁(UPDLOCK)

UPDLOCK.UPDLOCK 的优点是允许您读取数据&#xff08;不阻塞其它事务&#xff09;并在以后更新数据&#xff0c;同时确保自从上次读取数据后数据没有被更改。当我们用UPDLOCK来读取记录时可以对取到的记录加上更新锁&#xff0c;从而加上锁的记录在其它的线程中是不能更改的只能…

Oracle CDC (Change Data Capture)更新数据捕获——概述

Change Data Capture能高效识别并捕获数据的插入、修改和删除&#xff0c;使更新数据供个人或应用使用。 CDC从oracle 9i开始引入&#xff0c;//TODO 在11G R2之后的版本里将取消支持&#xff0c;被Oracle GoldenGate取代。 CDC的一些概念 CDC有同步和异步两种模式&#xff0c;…

flutter ios启动白屏_Flutter技术架构概览

前言最近在整理各种技术架构&#xff0c;给自己的列了个TODO list&#xff0c;希望能在几个月的时间内&#xff0c;研究完各种前端技术架构&#xff0c;包括移动端技术架构。今天分享一下自己整理的flutter技术架构。完整的技术架构TODO list可以去我的github仓库查看&#xff…

SQL Relay开源的数据库池连接代理服务器

一、SQL Relay是什么&#xff1f; SQL Relay是一个开源的数据库池连接代理服务器 二、SQL Relay支持哪些数据库&#xff1f;* Oracle* MySQL* mSQL* PostgreSQL* Sybase* MS SQL Server* IBM DB2* Interbase* Sybase* SQLite* Lago* ODBC* MS Access三、安装和配置&#xff1b;…

关于Android开源库分享平台,(GitClub)微信小程序的开发体验

七八月份的深圳一直在下雨&#xff0c;总有人说雨天适合窝在家看书&#xff0c;对于程序开发者来说更是难得的学习机会。我们502工作室的小伙伴利用这个时间学习了一下微信小程序开发&#xff0c;并上线了一个GitClub小程序&#xff0c;目前功能有些简陋&#xff0c;难免有辣眼…

RSync实现文件备份同步

rsync是类unix系统下的数据镜像备份工具&#xff0c;从软件的命名上就可以看出来了——remote sync。它的特性如下&#xff1a;1、可以镜像保存整个目录树和文件系统。2、可以很容易做到保持原来文件的权限、时间、软硬链接等等。3、无须特殊权限即可安装。4、优化的流程&#…

Hibernate annotation多对多配置

角色&#xff08;用户组&#xff09;&#xff0c;用户多对多。 角色实体配置&#xff1a; private Set<TAuthUser> users;ManyToManyJoinTable(name"t_auth_user_role",joinColumns{JoinColumn(name"role_id")},inverseJoinColumns{JoinColumn(name&…

ajax中的url如何传递变量_如何创建和参数化UDT数据类型中的变量及IN,OUT 等参数?...

从数据类型的意义上说 UDT 并不被 CPU 所识别&#xff0c;而是在离线程序中自定义(组合)的数据类型。 S7 程序的自定义数据类型并不能装载到 S7 CPU 中。UDT 是由递增的编辑器创建并编辑或由源文件的编译而生成。 当在块调用中进行变量传递时是不能将 UDT 作为内存地址区域来传…

[雪峰磁针石博客]kotlin书籍汇总

2019独角兽企业重金招聘Python工程师标准>>> 下载地址 Learning Kotlin by Building Android Applications - 2018 初级 Develop amazing applications that will help you understand and explore the fundamentals of Kotlin while covering 3 various types of p…

web集群时session同步的3种方法

web集群时session同步的3种方法在做了web集群后&#xff0c;你肯定会首先考虑session同步问题&#xff0c;因为通过负载均衡后&#xff0c;同一个IP访问同一个页面会被分配到不同的服务器上&#xff0c;如果session不同步的话&#xff0c;一个登录用户&#xff0c;一会是登录状…

属于python文件的操作有_Python的文件操作

1、初始文件操作1、使用python读写文件使用open()函数获取文件句柄&#xff0c;就可以操作文件了&#xff0c;根据打开方式不同能执行的操作也不同。打开方式有&#xff1a;r、w、a、r、w、a、rb、wb、ab、rb、wb、ab&#xff0c;默认用的是r模式2、只读操作(r、rb)2.1、只读模…

[iOS]开发者证书和描述文件的作用

先说下证书吧。 然后是描述文件 转载于:https://www.cnblogs.com/wangqi1221/p/5240273.html

单元格编辑后级联汇总刷新

单元格编辑 级联刷新 PDERPDB db new PDERPDB(); int conid 0; int pid 0; string sql ""; string sqlC ""; if (int.TryParse(Pid, out pid)) { sql string.Format(" UPDATE JL_Project set PCMoney{0} where Pid{1};", pcmoney, Pid); }…

HTTP 协议的通用头域via 的意义以及作用

列出从客户端到 OCS 或者相反方向的响应经过了哪些代理服务器&#xff0c;他们用 什么协议&#xff08;和版本&#xff09;发送的请求。 当客户端请求到达第一个代理服务器时&#xff0c;该服务器会在自己发出的请求里面 添…

6-5-树的双亲表示法-树和二叉树-第6章-《数据结构》课本源码-严蔚敏吴伟民版...

课本源码部分 第6章 树和二叉树 - 树的双亲表示法 ——《数据结构》-严蔚敏.吴伟民版 源码使用说明 链接☛☛☛ 《数据结构-C语言版》&#xff08;严蔚敏,吴伟民版&#xff09;课本源码习题集解析使用说明 课本源码合辑 链接☛☛☛ 《数据结构》课本源码合辑 习题集全解析 …

压力测试 闪存_产品评测 | HPE Nimble AF全闪存系列,诠释真正的高端存储

随着AI、互联网、大数据等技术快速发展&#xff0c;企业对存储设备的需求已踏上一个更高的级别&#xff0c;高性能、低延时、大容量等多种需求的应用场景愈发常见&#xff0c;在这种情况下&#xff0c;寻求能够满足相应工作负载能力的存储设备已成为企业IT管理者的当务之急。这…

Mysql无法选取非聚合列

教程所示图片使用的是 github 仓库图片&#xff0c;网速过慢的朋友请移步>>> &#xff08;原文&#xff09;Mysql 无法选取非聚合列。 更多讨论或者错误提交&#xff0c;也请移步。 1. 前言 最近升级博客&#xff0c;给文章页面底部增加了两个按钮&#xff0c;可以直接…

网络设置巨形帧_Trunk的概念与设置

在二层交换机的性能参数中&#xff0c;常常提到一个重要的指标&#xff1a;TRUNK &#xff0c;许多的二层交换机产品在介绍其性能时&#xff0c;都会提到能够支持TRUNK 功能&#xff0c;从而可以为互连的交换机之间提供更好的传输性能。那到底什么是TRUNK呢&#xff1f;使用TRU…