zoukankan      html  css  js  c++  java
  • Redis 内存回收机制详解

    前言:这个问题其实相当重要,到底redis有没用到家,这个问题就可以看出来。比如你redis只能存5G数据,可是你写了10G,那会删5G的数据。怎么删的,这个问题思考过么?还有,你的数据已经设置了过期时间,但是时间到了,内存占用率还是比较高,有思考过原因么?

    总结:redis是通过 过期策略及内存淘汰机制来回收内存的!

      1、redis采用的是定期删除+惰性删除策略。

      2、为什么不用定时删除策略?

    定时删除,用一个定时器来负责监视key,过期则自动删除。虽然内存及时释放,但是十分消耗CPU资源。在大并发请求下,CPU要将时间应用在处理请求,而不是删除key,因此没有采用这一策略.

      3、定期删除+惰性删除是如何工作的呢?

      定期删除,redis默认每个100ms检查,是否有过期的key,有过期key则删除。需要说明的是,redis不是每个100ms将所有的key检查一次,
    而是随机抽取进行检查(如果每隔100ms,全部key进行检查,redis岂不是卡死)。因此,如果只采用定期删除策略,会导致很多key到时间没有删除。 于是,惰性删除派上用场。也就是说在你获取某个key的时候,redis会检查一下,这个key如果设置了过期时间那么是否过期了?如果过期了此时就会删除。

         (1)上面提到的随机抽取的方式

    1、随机测试100个设置了过期时间的key
    2、删除所有发现的已过期的key
    3、若删除的key超过25个则重复步骤1
    
    说明:这是一个基于概率的简单算法,基本的假设是抽出的样本能够代表整个key空间,redis持续清理过期的数据直至将要过期的key的百分比降到了25%以下。
    
    另外每隔100ms检测一次可以手动修改这频率,可以找关于 hz 选项的说明。
    
    注意:当REDIS运行在主从模式时,只有主结点才会执行上述这两种过期删除策略,然后把删除操作”del key”同步到从结点。

      4、采用定期删除+惰性删除就没其他问题了么?

    不是的,如果定期删除没删除key。然后你也没即时去请求key,也就是说惰性删除也没生效。这样,redis的内存会越来越高。那么就应该采用内存淘汰机制。
    
    在redis.conf中有一行配置:# maxmemory-policy volatile-lru
    
    该配置就是配内存淘汰策略的,默认第一种
        1)noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。-不淘汰
        2)allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key。
        3)allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个key。
        4)volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的key。这种情况一般是把redis既当缓存,又做持久化存储的时候才用
        5)volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个key。
        6)volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除。
       7) Volatile-lfu:在设置了过期时间的键空间中,按照最小访问频率访问次数原则来淘汰数据,如果2个数据相等,则淘汰时间较早的数据,使用lfu算法删除(Redis4.0新提供的)
      8)allkeys-lfu:在所有键值对中,按照最小访问频率访问次数原则来淘汰数据,如果2个数据相等,则淘汰时间较早的数据(Redis4.0新提供的)
     

    总结与备忘

    1、如果Redis中每天过期大量Key(比如几千万),那么必须得考虑过期Key的清理:
        1)、增加Redis主动清理的频率(通过调大hz参数);
        2)、手动清理过期Key,最简单的方法是进行scan操作,scan操作会触发第一种被动删除,scan操作时候别忘了加count;
    
    2、dbsize命令返回的Key数量,包含了过期Key;
    
    3、randomkey命令返回的Key,不包含过期Key;
    
    4、scan命令返回的Key,包含过期Key;
    
    5、keys对应的Key数量等同于dbsize;
    
    6、info命令返回的# Keyspace:db6:keys=1034937352,expires=994731489,avg_ttl=507838502
        1)、expires指的是设置了过期时间的Key数量;
        2)、avg_ttl指设置了过期时间的Key的平均过期时间(单位:毫秒);
  • 相关阅读:
    Pytorch学习笔记14----torch中相关函数使用:view函数、max()函数、squeeze()函数
    Pytorch学习笔记13----LSTM+CRF模型的CRF层原理与代码理解
    Pytorch学习笔记12----损失函数nn.CrossEntropyLoss()、nn.NLLLoss()
    Pytorch学习笔记12---- Pytorch的LSTM的理解及入门小案例
    Pytorch学习笔记11----model.train()与model.eval()的用法、Dropout原理、relu,sigmiod,tanh激活函数、nn.Linear浅析、输出整个tensor的方法
    Pytorch学习笔记10----LSTM循环神经网络原理
    webpack入门
    js判断对象是否为空对象的几种方法
    js的防抖和节流
    简述http协议
  • 原文地址:https://www.cnblogs.com/chenhaoyu/p/14758028.html
Copyright © 2011-2022 走看看