资讯专栏INFORMATION COLUMN

关于redis的几件小事(四)redis的过期策略以及内存淘汰机制

AbnerMing / 3328人阅读

摘要:的过期策略是什么样的采用了定期删除惰性删除的过期策略。定期删除原理定期删除指的是默认每隔就随机抽取一些设置了过期时间的,检测这些是否过期,如果过期了就将其删掉。所有只会抽取一部分而不会全部检查。

1.数据为什么会过期?

首先,要明白redis是用来做数据缓存的,不是用来做数据存储的(当然也可以当数据库用),所以数据时候过期的,过期的数据就不见了,过期主要有两种情况,
①在设置缓存数据时制定了过期时间,这样到了过期时间数据就不见了。
②redis的数据是存放在内存中的,而内存是有限的,是不可能放过多数据的,比如只有10G的内存,想要向里面放入20G的数据,那么就注定会有10G的数据会丢失。

2.redis的过期策略是什么样的?

redis采用了 “定期删除+惰性删除” 的过期策略。
①定期删除
原理:定期删除指的是redis默认每隔100ms就随机抽取一些设置了过期时间的key,检测这些key是否过期,如果过期了就将其删掉。
为什么会选择一部分,而不是全部:因为如果这是redis里面有大量的key都设置了过期时间,那么如果全部去检测一遍,CPU负载就会很高,会浪费大量的时间在检测上面,甚至直接导致redis挂掉。所有只会抽取一部分而不会全部检查。
出现问题:这样的话就会出现大量的已经过期的key并没有被删除,这就是 为什么有时候大量的key明明已经过了失效时间,但是redis的内存还是被大量占用的原因 ,为了解决这个问题,就需要 惰性删除 这个策略了。

②惰性删除
原理:惰性删除不在是redis去主动删除,而是在你要获取某个key 的时候,redis会先去检测一下这个key是否已经过期,如果没有过期则返回给你,如果已经过期了,那么redis会删除这个key,不会返回给你。
这样两种策略就保证了 过期的key最终一定会被删除掉 ,但是这只是保证了最终一定会被删除,要是定时删除漏掉了大量过期的key,而且我们也没有及时的去访问这些key,那么这些key不就不会被删除了吗?不就会一直占着我们的内存吗"); 由于存在这样的问题,所以redis引入了 内存淘汰机制 来解决。

3.内存淘汰机制

内存淘汰机制就保证了在redis的内存占用过多的时候,去进行内存淘汰,也就是删除一部分key,保证redis的内存占用率不会过高,那么它会删除那些key呢?
redis提供了6中内存淘汰策略,我们可以去进行选择,六中策略如下:
①noeviction:当内存不足以容纳新写入数据时,新写入操作会报错,无法写入新数据,一般不采用。
②allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key,这个是最常用的。
③allkeys-random:当内存不足以容纳新写入的数据时,在键空间中,随机移除key,一般也不使用。
④volatile-lru:volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的key(这个一般不太合适) 。
⑤volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个key 。
⑥volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除。

4.手写一个LRU算法
//基于JavaLinkedHashMap实现
public class LRUCache extends LinkedHashMap{
      private final int CACHE_SIZE;
      
      //保存传递进来的最大数据量
      public LRUCache(int cacheSize){
           //设置hashmap的初始大小,同时最后一个true指的是让linkedhashmap按照访问顺序来进行排序,
           //最近访问的放在头,最老访问的放在尾
           super((int)Math.ceil(cacheSize/0.75)+1,0.75f,true);
           CACHE_SIZE = CacheSize;
      }

      @Override
      protected boolean removeEldestEntry(Map.Entry eldest){
           //当map中的数据量大于指定的缓存个数的时候,就自动删除最老的数据。
           return size() > CACHE_SIZE;
      }
}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/7197.html

相关文章

  • 关于redis几件小事(二)redis线程模型

    摘要:事件分派器会根据每个当前产生的事件,来选择对应的事件处理器来处理。核心是基于非阻塞的多路复用机制单线程避免了多线程上下文切换的开销。 1.memcached和redis有什么区别? (1)Redis支持服务器端的数据操作 redis和memcached相比,redis拥有更多的 数据结构并且支持更丰富的数据操作 ,通常在memcached里面,你需要将数据拿到客户端来进行类型的修改然后在se...

    tuantuan 评论0 收藏0
  • 关于redis几件小事(三)redis数据类型与使用场景

    摘要:这个是类似的一种结构,这个一般就是可以将结构化的数据,比如一个对象前提是这个对象没嵌套其他的对象给缓存在里,然后每次读写缓存的时候,可以就操作里的某个字段。 1.string 这是最基本的类型了,就是普通的set和get,做简单的kv缓存。 2.hash 这个是类似map的一种结构,这个一般就是可以将结构化的数据,比如一个对象(前提是这个对象没嵌套其他的对象)给缓存在redis里,然后每次...

    zhaochunqi 评论0 收藏0

发表评论

0条评论

AbnerMing

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<