百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

Redis是怎么轻松解决缓存占满内存的?

nanshan 2025-03-01 14:50 16 浏览 0 评论

前言

Redis最为常用的是拿来做缓存,而Redis之所以这么快的原因之一是搭上了内存那纳秒级别的处理速度来存储数据,极大提升了应用服务的性能。(从用户角度翻译过来就是这玩意反应快了)

但是,但凡技术总有它的局限性,例如在计算机中内存空间远比磁盘空间要小得多,而且内存比磁盘贵。所以我们要是把数据都放内存,显然是一件成本高,性价比很低的事情。

所以更多的是采取让Redis存放热数据,从统计上来说,在大部分业务场景中,按二八定律,是20%的数据贡献了的访问量和访问频率可能接近或超过80%(当然总有部分例外)。

但是,内存空间大小就这么多,随着业务缓存数据量不断增多,不可避免就会将有限的内存空间不小心给占满。

那Redis是怎么解决缓存占满内存的?

我们先来看Java,使用Java都知道,Java是运行在JVM上的,而JVM的一大亮点就是拥有不用让C或C++的同学一样去关心内存回收情况,也就是垃圾回收机制。Redis也有自己的内存回收机制,但是相对JVM来说,Redis要"简单"一些,因为Redis内存回收机制主要两个方面的策略。

Redis内存回收机制策略

Redis 删除过期键策略

惰性删除:

顾名思义,惰性删除并不主动做任何操作,而是当客户端读取到设置了超时的键时,如果已经超过过期时间就会删除。但是很明显的问题就是当过期键一直没有访问到而及时删除,那么就会导致不能让内存及时释放。

定时删除:

定时删除实际上就是在Redis内部开启了一个定时任务,通过默认每秒定时的运行多少次和按键过期比例以及快慢的速率模式去回收键。

除了删除过期关键策略当然还远不够,所以就进一步通过算法来筛选数据淘汰的淘汰策略。

Redis淘汰策略

但是不管前面的删除过期键策略,还是淘汰策略目的本身都是来防止内存溢出的这一点。Redis淘汰策略提供了8种淘汰策略,Redis4.0实现了6种淘汰策略,4.0之后又增加了2种策略,所以Redis有 8 种淘汰策略。

可以分成两类:

  • 不过淘汰数据的策略,仅有 noeviction 一种。
  • 会淘汰数据的有7种策略。

我们这里主要关注淘汰数据的7种策略,这7种细看可以再次归成两类:

会在所有数据中淘汰的: allkeys-lru、allkeys-random、allkeys-lfu

会在设置过期时间数据中淘汰的:volatile-lru、volatile-random、volatile-ttl、volatile-lfu

小伙伴们,我把熬夜整理的思维导图放在这了。

Redis淘汰策略详解

默认情况,当Redis的内存超过maxmemory时,noeviction是作为默认策略的,并不会淘汰任何数据。在Redis缓存一旦被占满之后的写请求都不会再处理,会直接的返回错误。

接下来是 allkeys-lru、allkeys-random、allkeys-lfu 四种淘汰策略。它们会在设置过期时间的数据中进行淘汰,所以它们筛选的数据范围都在设置了过期键上。当数据过期时,即使缓存没有写满也会被淘汰删除。

volatile-ttl:根据键的ttl(生存时间值),删除设置过期时间最近的键,先过期的被先删除。

volatile-random:random也就是随机,设置了过期的 key 会随机的删除。

volatile-lru:在设置过期时间的时候 key,使用LRU算法筛选淘汰键。

volatile-lfu:在设置过期时间的时候 key,使用LFU算法筛选淘汰键。

allkeys-lru、allkeys-random、allkeys-lfu 前缀都带着 all 这三种淘汰策略的淘汰数据范围包括了所有的键值,范围是所有键值就是无论是否设置过期时间都会进行淘汰。

allkeys-random:在所有键中随机淘汰数据。

allkeys-lru:在所有键中使用LRU算法筛选数据。

allkeys-lfu:在所有键中使用lfu算法筛选数据。

不管是 ttl 还是 random 算法规则是比较简单,而主要是 lru 和 lfu 算法也不复杂,让我们一起看看。

LRU(Least Recently Used)

LRU (Least Recently Used) 是最近最少使用原则,是将最近最不常使用的数据进行筛选,最近不常使用的淘汰,最近常使用的数据留在缓存。

具体怎么筛选可以看下面的例子,假设在一块有限的空间里,最近访问会被移到顶端,最近没访问到的会移到末端,也就是LRU端。当空间被占满时,此时刚好有新增的数据时,就会把LRU端的末尾 key 替换淘汰掉。



你看LRU算法是不是很有用户体验 “如果有人最近被访问过,那么再次被访问的几率也会很高”

那如果要去实现LRU算法,自然就需要有支撑它的数据结构,此时就可以使用链表,用链表来存放所有缓存数据。不过只使用链表,会有问题,那就是当面临数据量大的情况,链表的移动也会显得笨拙而带来耗时,进而影响Redis性能。

Redis自然不会放过这个可以优化的机会,所以Redis在LRU算法上动手脚。所以在一开始就记录每个数据最近一次被访问的时间戳。之后当Redis准备淘汰数据时,首先第一次随机的选出N个数据,然后将其作为候选集合,最后比较这N个数据携带的lru字段,最小的会从缓存中被淘汰。

Redis提供 maxmemory-samples 的配置参数,让Redis选出数据作为候选数据集。

当面临淘汰数据,Redis需要挑选数据,那么就会进到首次创建的淘汰候选集合。

挑选标准是:进入候选集合的数据lru属性值必须小于候选集合中最小的lru值。

当有新数据进入候选数据集后,如果候选数据集中的数据个数达到了maxmemory-samples,Redis就把候选数据集中lru字段值最小的数据淘汰出去。

你看这样一来Redis缓存就可以不用为不断增多的数据维护一个也不断增大的大链表,省去每次数据访问都移动链表的开销,缓存的性能就能得到提升。

LFU(Least Frequently Used)

LFU (Least Frequently Used)是最近最少频率使用,楞一看LFU缓存策略跟 LRU很相似,相似就对了,因为LFU就是在LRU的策略基础上优化出来的缓存策略。

LFU不同与LRU的是LFU把LRU原来的24bit的lru字段拆分成Idt值和 counter 值两部分。其中Idt 是lru字段的前16bit 表示访问时间戳。counter 值是lru字段的后8bit 也就是表示访问次数。

LFU算法用的是访问频次递增和访问频次衰减两种方式。

访问频次递增

是通过counter来递增,但是它所能表示的最大值只有255,所以采用了更优的计数方式。每当数据被访问时,计数器值乘以lfu_log_factor再加1,取其倒数,得到p值;之后p值和取值范围 0 和 1 之间的随机数 r 比大小,当 p 值大于r值,计数器才会加 1.

1/(baseval * lfu_log_factor + 1)

[Redis官网] 提供的一张表,当lfu_log_factor取不同值,不同访问次数,计数器值的变化情况。



从表中可以看到,lfu_log_factor 取值为1,访问次数100k时, counter值就到顶255,没法区分访问次数。当lfu_log_factor取值为100时,访问次数10M,counter值达到255,此时,访问次数小于10M的不同数据都可以通过counter值区分出来。

访问频次衰减

Redis实现LFU策略时,除了访问频次递增,还设计了一个衰减机制。因为从上可知,counter 一直递增会到达顶 255,而且纯粹的递增不能反应一个 key 的热度,所以 key 如果一段时间不被访问,counter也需要对应减少。

递减的速度由 lfu-decay-time 配置项控制 counter 的递减速度,默认值 1表示如果N分钟没有访问,那么 counter 减 N。

总结

我们围绕 Redis是怎么解决缓存占满内存展开了Redis的内存回收策略,Redis的内存回收策略有两个方面,删除过期键策略和淘汰策略,但是不管是删除过期键策略还是淘汰策略目的都是来控制防止内存溢出。在淘汰策略中,Redis4.0实现了6种淘汰策略,4.0之后又增加了2种策略,所以Redis一共有8 种淘汰策略。其中最为主要的LRU和LFU算法策略。LFU是在LRU的基础上的策略,但是LFU并不是用来替换LRU;它们各自的数据筛选侧重点不同,前者LRU策略侧重数据时效性,而后者LFU侧重访问频次。

相关推荐

提升网络安全 cisco asa5512-k8防火墙促

(中关村在线网络安全行情)ciscoasa5512-k8为标准下一代防火墙,能够为中小型网络提供出色的安全防护和流量管控服务。最近这款防火墙设备在京东商城的促销价格为14299元,有需要的用户可以关注...

太一星晨:负载均衡性能参数如何测评?

海外网2014-08-0816:03:568月6日消息,当前,在云计算和大数据为主导的需求环境下,负载均衡和应用交付已为大型企业数据中心“保驾护航”的必备品。不过,负载均衡作为一种比较“新奇”的设备...

Nginx架构揭秘:如何用5大核心机制扛住百万级并发

1.灵魂拷问:为什么全球Top1000网站中65%选择Nginx?17Nginx不仅是Web服务器,更是高并发架构的核武器。其单机支持10万+并发连接的秘密,源于三大设计哲学:事件驱动模型:非阻塞...

高并发场景下,Nginx性能如何提升10倍?

大家好,我是mikechen。在高并发场景,Nginx是流量入口的第一道防线,如果想拦截亿级流量,需要Nginx合理调优才能应对@mikechen。本文作者:陈睿|mikechen文章来源:mike...

紧急避坑!数据库突现数十GB临时文件?原因与根治方案揭秘

引言:某天深夜,运维小王突然收到磁盘爆满的告警,追踪发现Kingbase数据库的syssql_tmp目录竟堆积了数十GB的临时文件!这些神秘文件为何产生?会引发哪些风险?如何彻底根治?本文将带你深入探...

互联网大厂后端必看!3 步搞定 Nginx IP 限流,服务器扛住百万流量

作为互联网大厂的后端开发人员,你是否曾遇到过这样的场景:服务器突然涌入大量请求,服务响应速度急剧下降,甚至出现崩溃?这时候,Nginx的IP访问限流策略就显得尤为重要。然而,不少开发者在配置N...

MySQL max_connections 达到最大值 – 我们如何解决它

您的网站是否显示MySQLmax_connections达到最大限制错误?通常,当我们尝试连接到MySQL服务器时,MySQLmax_connections值不足会导致“Tooma...

Nginx百万并发背后技术揭秘!(nginx并发能力是多少)

在互联网业务高速发展的今天,用户访问量呈指数级增长,服务器面临的并发压力也越来越大。一个高并发的网站,如果处理不当,可能会出现请求超时、服务器宕机、用户体验下降等问题。Nginx作为当前最流行的高性...

Nginx底层原理:一文解析Nginx为什么并发数可以达到3w!

Nginx以其高性能,稳定性,丰富的功能,简单的配置和低资源消耗而闻名。本文从底层原理分析Nginx为什么这么快!Nginx的进程模型Nginx服务器,正常运行过程中:多进程:一个Mast...

Nginx合集-并发连接能力优化(nginx高并发调优)

一、前言nginx服务器老是报告TIME_WAIT告警,ESTABLISHED告警,检查nginx配置和系统网络配置发现现有的配置并发能力太弱,无法满足现有的并发请求的需求。二、解决方法改进方法...

开源OS上安装Gnome Flashback经典桌面

1安装GnomeFlashback对于用户来说,相比Unity桌面,GnomeFlashback桌面环境是一个简单的并且不错的选择,可以让你找回过去经典的桌面。GnomeFlashback基于G...

新手篇 — 虚拟机系统的使用与常见问题

本文章会详细介绍虚拟机系统的使用与常见问题,有很多读者都会遇到这样的情况,软件装不上,自己的电脑中软件很多,又不想换电脑系统,那么虚拟机可以帮你解决这个烦恼,由于文章内容写的比较详细,内容会比较多,可...

VMware虚拟机与主机之间无法复制粘贴解决

问题:VMware安装系统后发现无法直接与主机之间进行复制粘贴了,怎么办?解决办法:按照以下3步进行1、设置中客户机隔离检查2、重新安装VMwareTools3、重启电脑...

实现VMware虚拟机与物理主机共享文件夹

在安装虚拟机之后,难免会遇到需要将文件从主机拷到虚拟机当中,但是很尴尬的事情就是不能直接将文件从主机拖到虚拟机中,所以只能借助U盘,但是频繁的插拔U盘非常的繁琐。为了解决这一需求,就可以将物理主机和...

在 Windows 11 或 10 上安装 Virt-viewer 的单行命令

Virt-Viewer(或RemoteViewer)是Redhat提供的一个开源程序,允许用户控制和查看运行在本地或远程服务器上的虚拟机。它体积轻巧,并提供了一个简单的图形用户界面来访问由L...

取消回复欢迎 发表评论: