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
  • 相关阅读:
    剑指offer——最小的K个数和数组中第K大的元素
    Leetcode刷题指南链接整理
    160. Intersection of Two Linked Lists
    100. Same Tree
    92. Reverse Linked List II
    94. Binary Tree Inorder Traversal
    79. Word Search
    78,90,Subsets,46,47,Permutations,39,40 DFS 大合集
    0x16 Tire之最大的异或对
    0x16 Tire
  • 原文地址:https://www.cnblogs.com/liaowenhui/p/15037902.html
Copyright © 2011-2022 走看看