redis过期key的删除策略[通俗易懂]

前言在使用redis的过程中,不免会产生过期的key,而这些key过期后并不会实时地马上被删除,当这些key数量累积越来越多,就会占用很多内存,因此在redis底层同时使用了三种策略来删除这些key。第一种策略:被动删除当读/写一个key时,redis首先会检查这个key是否存在,如果存在且已过期,则直接删除这个key并返回nil给客户端。第二种策略:定期删除redis中有一系列的定期任务(serverCron),这些任务每隔一段时间就会运行一次,其中就包含清理过期key的任务,运行频率由配置文件

大家好,又见面了,我是你们的朋友全栈君。

前言

在使用redis的过程中,不免会产生过期的key,而这些key过期后并不会实时地马上被删除,当这些key数量累积越来越多,就会占用很多内存,因此在redis底层同时使用了三种策略来删除这些key。

第一种策略:被动删除

当读/写一个key时,redis首先会检查这个key是否存在,如果存在且已过期,则直接删除这个key并返回nil给客户端。

第二种策略:定期删除

redis中有一系列的定期任务(serverCron),这些任务每隔一段时间就会运行一次,其中就包含清理过期key的任务,运行频率由配置文件中的hz参数来控制,取值范围1~500,默认是10,代表每秒运行10次。清理过程如下:

  1. 遍历所有的db
  2. 从db中设置了过期时间的key的集合中随机检查20个key
  3. 删除检查中发现的所有过期key
  4. 如果检查结果中25%以上的key已过期,则继续重复执行步骤2-3,否则继续遍历下一个db

调大hz将会提高redis定期任务的执行频率,如果你的redis中包含很多过期key的话,可以考虑将这个值调大,但要注意同时也会增加CPU的压力,redis作者建议这个值不要超过100。

第三种策略:强制删除

如果redis使用的内存已经达到maxmemory配置的值时,会触发强制清理策略,清理策略由配置文件的maxmemory-policy参数来控制,有以下这些清理策略:

  • volatile-lru:使用LRU算法对设置了过期时间的key进行清理(默认值)
  • allkeys-lru:使用LRU算法对所有key进行清理
  • volatile-lfu:使用LFU算法对设置了过期时间的key进行清理(redis 4.0版本开始支持)
  • allkeys-lfu:使用LFU算法对所有key进行清理(redis 4.0版本开始支持)
  • volatile-random:对所有设置了过期时间的key进行随机清理
  • allkeys-random:从所有key进行随机清理
  • volatile-ttl:清理生存时间最小的一部分key
  • noeviction:不做任何清理,拒绝执行所有的写操作

为了节省内存和性能上的考虑,上述的清理策略都不需要遍历所有数据,而是采用随机采样的方法,每次随机取出特定数量(由maxmemory-samples配置项控制,默认是5个)的key,然后在这些key中执行LRU算法、RANDOM算法、或者是找出TTL时间最小的一个key,然后进行删除。

注:这个清理过程是阻塞的,直到清理出足够的内存空间才会停止。

关于big key的清理

在删除元素数量很多的集合(set/hash/list/sortedSet)时,无论是使用DEL命令删除还是redis为了释放内存空间而进行的删除,在删除这些big key的时候,会导致redis主线程阻塞。为了解决这个问题,在redis 4.0版本中,提供了lazy free(懒惰删除)的特性。

使用lazy free删除big key时,和一个O(1)指令的耗时一样,亚毫秒级返回,然后把真正删除key的耗时动作交由bio后台子线程执行。

UNLINK命令

UNLINK命令是与DEL一样删除key功能的lazy free实现。唯一不同的是,UNLINK在删除集合类型的键时,如果集合键的元素个数大于64个,会把真正的内存释放操作,交给单独的后台线程来操作,使用示例:

127.0.0.1:6379> UNLINK mylist
(integer) 1

FLUSHALL/FLUSHDB命令

FLUSHALL/FLUSHDB命令也有lazy free的实现,在命令后加上ASYNC关键字就可以,使用示例:

127.0.0.1:6379> FLUSHALL ASYNC

lazy free相关配置项

与lazy free相关的配置项有以下这些,默认值都是no,即关闭。

lazyfree-lazy-eviction

针对redis内存使用达到maxmemory,并设置有淘汰策略时,在淘汰键时是否采用lazy free机制。

注:如果此场景开启lazy free,可能会使淘汰键的内存释放不及时,导致redis不能迅速将内存使用下降到maxmemory以下。

lazyfree-lazy-expire

针对设置有过期时间的key,达到过期后,被redis清理删除时是否采用lazy free机制,此场景建议开启。

lazyfree-lazy-server-del

针对有些命令在处理已存在的键时,会带有一个隐式的DEL键的操作。如RENAME命令,当目标键已存在,redis会先删除目标键,如果这些目标键是一个big key,那就会出现阻塞的性能问题。 此参数设置就是解决这类问题,建议开启。

slave-lazy-flush

针对slave进行全量数据同步,slave在加载master的RDB文件前,会运行FLUSHALL来清理自己的数据场景。
参数设置决定是否采用lazy free flush机制。如果内存变动不大,建议可开启。可减少全量同步耗时,从而减少主库因输出缓冲区爆涨引起的内存使用增长。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/126799.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Effective_STL 学习笔记(十一) 理解自定义分配器的正确用法

    Effective_STL 学习笔记(十一) 理解自定义分配器的正确用法

    2021年6月17日
    90
  • eclipse全文搜索快捷键_eclipse查看被引用快捷键

    eclipse全文搜索快捷键_eclipse查看被引用快捷键文件太多单个找太麻烦,eclipse提供了全局搜索的功能,下面就和大家分享一下如何使用eclipse全局搜索功能。eclipse全局搜索快捷键是什么全局搜索快捷键是Ctrl+H。搜索功能具体用法如下:1、打开eclipse,使用快捷键“ctrl+H”打开文件搜索对话框,或者点击“search”标签打开文件搜索对话框。2、然后选择“FileSearch”标签,在Containingtext…

    2025年7月1日
    0
  • 贴片铝电容识别及型号_TDK贴片电容识别方法及命名规则[通俗易懂]

    贴片铝电容识别及型号_TDK贴片电容识别方法及命名规则[通俗易懂]原标题:TDK贴片电容识别方法及命名规则TDK贴片电容识别方法及命名规则,TDK是TokyoDenkikagakuKogyoK.K的简称。是日本的一个品牌。今天我们一起来学习一下如何识别TDK的贴片电容。拿到一般TDK的电容,料盘上会有TDK字样的标示。分上下两个标,上标是小标。下标是大标。TDK的标识是在大标上面。TDK贴片电容的参数一般由系列名称,体积,材质,电压,容量,误差,包装组成…

    2022年8月21日
    5
  • 六大排序算法:插入排序、希尔排序、选择排序、冒泡排序、堆排序、快速排序「建议收藏」

    六大排序算法:插入排序、希尔排序、选择排序、冒泡排序、堆排序、快速排序「建议收藏」文章目录:1.插入排序2.希尔排序1.插入排序步骤:1.从第一个元素开始,该元素可以认为已经被排序2.取下一个元素tem,从已排序的元素序列从后往前扫描3.如果该元素大于tem,则将该元素移到下一位4.重复步骤3,直到找到已排序元素中小于等于tem的元素5.tem插入到该元素的后面,如果已排序所有元素都大于tem,则将tem插入到下标为0的位置6.重复步骤2~5动图演示如下:思路:  在待排序的元素中,假设前n-1个元素已有序,现将第n个元素插入到前面已经排好的序列中,使得前n个

    2022年7月12日
    17
  • 去除字符串中重复字符

    去除字符串中重复字符去除字符串中重复字符:import java.util.LinkedHashSet;public class 去除重复字符串 { public static void main(String[] args) { String str = "aaaabbbccc"; char[] arr = str.toCharArray(); LinkedHashSet<Chara…

    2022年6月13日
    32
  • MySQL TIMESTAMPDIFF函数简介「建议收藏」

    MySQL TIMESTAMPDIFF函数简介「建议收藏」MySQLTIMESTAMPDIFF函数简介TIMESTAMPDIFF(unit,begin,end);TIMESTAMPDIFF函数返回begin-end的结果,其中begin和end是DATE或DATETIME表达式。TIMESTAMPDIFF函数允许其参数具有混合类型,例如,begin是DATE值,end可以是DATETIME值。如果使用DATE值,则TIMESTAMPDIFF函数将其视为时间部分为“00:00:00”的DATETIME值。unit参数是确定(end-begin)的结果

    2022年6月5日
    41

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号