zoukankan      html  css  js  c++  java
  • Redis 的过期策略和内存淘汰机制有什么区别?

    过期策略是在正常情况下清除过期键,内存淘汰策略是在非正常情况下为了保证 Redis 顺利运行的保护策略。

    过期策略

    我们在新增 Redis 缓存时可以设置缓存的过期时间,该时间保证了数据在规定的时间内失效,可以借助这个特性来实现很多功能。对于已经过期的数据,Redis 将使用两种策略来删除这些过期键,它们分别是惰性删除和定期删除。

    惰性删除

    惰性删除是指 Redis 服务器不主动删除过期的键值,而是当访问键值时,再检查当前的键值是否过期,如果过期则执行删除并返回 null 给客户端;如果没过期则正常返回值信息给客户端。

    优点是不会浪费太多的系统资源,只是在每次访问时才检查键值是否过期。

    缺点是删除过期键不及时,造成了一定的空间浪费。

    定期删除

    Redis 还提供了定期删除功能以弥补惰性删除的不足。

    定期删除是指 Redis 服务器每隔一段时间会检查一下数据库,看看是否有过期键可以被清除。默认情况下 Redis 定期检查的频率是每秒扫描 10 次,用于定期清除过期键。当然此值还可以通过配置文件进行设置,在 redis.conf 中修改配置“hz”即可,默认的值为“hz 10”。

    原理:定期删除的扫描并不是遍历所有的键值对,这样的话比较费时且太消耗系统资源。Redis 服务器采用的是随机抽取形式,每次从所有设置了过期时间的键值对中取出 20 个键进行过期检测,如果这批随机检查的数据中有 25% 的比例过期,那么会再抽取 20 个随机键值进行检测和删除,并且会循环执行这个流程,直到抽取的这批数据中过期键值小于 25%,此次检测才算完成。

     内存淘汰策略

    当 Redis 的内存超过最大允许的内存之后,Redis 会触发内存淘汰策略,这和过期策略是完全不同的两个概念,经常有人把二者搞混,这两者一个是在正常情况下清除过期键,一个是在非正常情况下为了保证 Redis 顺利运行的保护策略。

    Redis 内存淘汰策略有哪些?

    我们可以使用 config get maxmemory-policy 命令,来查看当前 Redis 的内存淘汰策略

    在 4.0 版本之前 Redis 的内存淘汰策略有以下 6 种。

    (1)noeviction:不淘汰任何数据,当内存不足时,执行缓存新增操作会报错,它是 Redis 默认内存淘汰策略。

    (2)allkeys-lru:淘汰整个键值中最久未使用的键值。

    (3)allkeys-random:随机淘汰任意键值。

    (4)volatile-lru:淘汰所有设置了过期时间的键值中最久未使用的键值。

    (5)volatile-random:随机淘汰设置了过期时间的任意键值。

    (6)volatile-ttl:优先淘汰更早过期的键值。

    而在 Redis 4.0 版本中又新增了 2 种淘汰策略:

    (7)volatile-lfu,淘汰所有设置了过期时间的键值中最少使用的键值;

    (8)allkeys-lfu,淘汰整个键值中最少使用的键值。

    小贴士:从以上内存淘汰策略中可以看出,allkeys-xxx 表示从所有的键值中淘汰数据,而 volatile-xxx 表示从设置了过期键的键值中淘汰数据。

    这个内存淘汰策略我们可以通过配置文件来修改,redis.conf 对应的配置项是“maxmemory-policy noeviction”,只需要把它修改成我们需要设置的类型即可。

    需要注意的是,如果使用修改 redis.conf 的方式,当设置完成之后需要重启 Redis 服务器才能生效。还有另一种简单的修改内存淘汰策略的方式,我们可以使用命令行工具输入“config set maxmemory-policy noeviction”来修改内存淘汰的策略,这种修改方式的好处是执行成功之后就会生效,无需重启 Redis 服务器。但它的坏处是不能持久化内存淘汰策略,每次重启 Redis 服务器之后设置的内存淘汰策略就会丢失。

    Redis 有哪些内存淘汰算法?

    内存淘汰算法主要包含两种:LRU 淘汰算法和 LFU 淘汰算法。

    (1)LRU( Least Recently Used,最近最少使用)淘汰算法:是一种常用的页面置换算法,也就是说最久没有使用的缓存将会被淘汰。

    LRU 是基于链表结构实现的,链表中的元素按照操作顺序从前往后排列,最新操作的键会被移动到表头,当需要进行内存淘汰时,只需要删除链表尾部的元素即可。

    Redis 使用的是一种近似 LRU 算法,目的是为了更好的节约内存,它的实现方式是给现有的数据结构添加一个额外的字段,用于记录此键值的最后一次访问时间。Redis 内存淘汰时,会使用随机采样的方式来淘汰数据,它是随机取 5 个值 (此值可配置) ,然后淘汰最久没有使用的数据。

    (2)LFU(Least Frequently Used,最不常用的)淘汰算法:最不常用的算法是根据总访问次数来淘汰数据的,它的核心思想是“如果数据过去被访问多次,那么将来被访问的频率也更高”。

    LFU 相对来说比 LRU 更“智能”,因为它解决了使用频率很低的缓存,只是最近被访问了一次就不会被删除的问题。如果是使用 LRU 类似这种情况数据是不会被删除的,而使用 LFU 的话,这个数据就会被删除。Redis 内存淘汰策略使用了 LFU 和近 LRU 的淘汰算法,具体使用哪种淘汰算法,要看服务器是如何设置内存淘汰策略的,也就是要看“maxmemory-policy”的值是如何设置的。

    希望本文章对您有帮助,您的转发、点赞是我的创作动力,十分感谢。更多好文推荐,请关注我的微信公众号--JustJavaIt
  • 相关阅读:
    django 设置局域网内访问项目
    104. Maximum Depth of Binary Tree
    multi dimension array
    Longest Plindrome Subarray
    BlockQueue
    H2O
    HoppingIterator
    midStack
    Reverse Words in a String II
    public boolean canPlaceFlowers(List<Boolean> flowerbed, int numberToPlace)
  • 原文地址:https://www.cnblogs.com/liaowenhui/p/15037902.html
Copyright © 2011-2022 走看看