redis是这么解决缓存占满内存的
redis是这么解决缓存占满内存的?
1.前言
redis最为常用的是拿来做缓存,而redis之所以这么快的原因之一是搭上了内存纳秒级别的处理速度来存储数据,极大提升了应用服务的性能。但是,但凡技术总有它的局限性,例如在计算机中内存空间远比磁盘空间要小得多,而且内存比磁盘贵。所以我们要是把数据都放内存,显然是一件成本高,性能很低的事情。所以更多的是采取让redis存放数据,从统计上来说,在大部分业务场景中,按二八定律,是20%的数据贡献了的访问量和访问频率可能接近或超过80%。
但是内存空间大小就这么多,随着业务缓存数据量不断增多,不可避免就会将有限的内存空间不小心给占满。
那redis是怎么解决缓存占满内存的?
我们先来看看java,使用java都都知道,java是运行在JVM上的,而JVM的一大亮点就是拥有不用让C或C++的同学一样去关心内存回收情况,也就是垃圾回收机制。redis也有自己的内存回收机制,但是相对JVM来说,redis要"简单一些",因为redis内存回收机制主要两个方面的策略。
2.redis回收机制策略
惰性删除
顾名思义,惰性删除并不主动做任何操作,而是客户端读取到设置了超时的键时,如果已经超过过期时间就会删除。但是很明显的问题就是当过期键一直没有访问到而及时删除,那么就会导致不能让内存及时释放。
定时删除
定时删除实际上就是redis内部开启了一个定时任务,通过默认每秒定时的运行多少次和按键过期比例及快慢的速率模式去回收键
3.redis 淘汰策略
但是不管前面的删除过期键策略,还是淘汰策略目的本身都是来防止内存溢出这一点。redis淘汰策略提供了8种淘汰策略,redis4.0实现了淘汰策略,4.0之后又增加了2种策略,所以8种淘汰策略。
可以分成两类:
- 不淘汰数据的策略,仅有noeviction一种。
- 会淘汰数据的7种策略
我们这里主要关注淘汰数据7种策略,这7种细看可以再次归成两类:
- 会在所有数据中淘汰的: allkeys-lru、allkeys-random、allkeys-lfu
- 会在设置过期时间数据中淘汰的:volatile-lru、volatile-random、volatile-ttl、volatile-lfu
思维导图:
4. redis淘汰策略详解
默认情况,当redis的内存超过maxmemory时,noeviction是作为默认策略的,并不会淘汰任何数据。在redis缓存一旦被占满之后的写请求都不会再处理,会直接返回错误。
接下来是allkeys-lru、allkeys-random、allkeys-lfu四种淘汰策略。它们会在设置过期时间的数据中进行淘汰,所以它们筛选的数据范围都在设置了过期键上。当数据过期时,即使缓存没有写满也会被淘汰删除。
- vloatile-ttl: 根据键的ttl(生存时间),删除设置过期时间最近的键,先过期的被先删除。
- viloatile-random: random也就是随机,设置了过期的key会随机删除
- vilatile-lru: 在设置过期时间的key,使用LRU算法筛选淘汰键
- vilatile-lfu :在设置过期时间的key,使用LFU算法筛选淘汰键
allkeys-lru、allkeys-random、allkeys-lfu前缀都带着all这三种淘汰策略的淘汰数据范围包括了所有的键值,范围是所有键值就是无论是否设置过期时间都会进行淘汰。
allkeys-random : 在所有键中随机淘汰数据。
allkeys-lru: 在所有键中使用LRU算法筛选数据
allkeys-lfu: 在所有键中使用lfu算法筛选数据。
参考:https://juejin.cn/post/7072209079979999268