Redis的过期键删除策略
文章首发于公众号:蘑菇睡不着,欢迎来看看
前言
Redis 中都是键值对的存储形式,键都是字符串类型的,而值有很多种类型,如 string、list、hash、set、sorted set等类型。当设置键值对时我们还应该为其设置过期时间,通过 expire 以及 pexpire 命令;还可以通过 setnx 命令设置。那么,当设置过期时间之后,到底是怎么将过期的键值对删除的那?想知道答案的话,我们就一起看看 Redis 的过期键删除策略。
在说删除策略之前有个点带大家先了解下,那就是如果确定一个键是否过期,这里我总结了下:
- 检查这个键是否在过期字典中,如果存在,那么取出这个键的过期时间。(过期字典存储的是每个键的过期时间,字典中 key 是 键, value 是 long 类型的过期时间)
- 拿到过期时间之后,和当前 UNIX 时间戳比较,如果大于,则键过期。
以上就是判断一个键是否过期的方法。接下来说说当键过期了怎么去删除。
目前来说有三种删除策略:
- 定时删除:在设置键的过期时间时,创建一个定时器,当到达键过期时间时通过定时器去删除键。
- 惰性删除:惰性删除并不是当到达过期时间时去删除,而是每次获取键时,会判断是否过期,如果过期则删除,并返回空;没过期,就返回键值。
- 定期删除:每隔一段时间,就对数据库中的键进行检查,如果过期则删除。至于要删除多少什么时候删除,则是通过具体程序决定。
下面来详细介绍每一种删除策略。
定时删除
定时删除策略
优点是:对内存友好。因为通过定时器,当一个键到达过期时间时就会立马被删除,直接就释放了内存。
缺点是:对 CPU 不友好。因为如果过期键比较多,那么删除这些过期键会占用相当一部分CPU时间,如果CPU时间非常紧张的话,还将CPU时间用在删除和当前任务无关的过期键上,会对服务器的响应时间以及吞吐量造成影响。
因此,通过 定时删除 策略来时间过期键的删除不太现实。
惰性删除
惰性删除策略优点:对 CPU 时间友好。程序只会在取出键时才会判断是否删除,并且只作用到当前键上,其他过期键不会花费 CPU 时间去处理。
惰性删除策略缺点:对内存不友好。因为只有键被使用时才会去检查是否删除,如果有大量的键一直不被使用,那么这些键就算过期了也不会被删除,会一直占用着内存。这种可以理解为是一种内存泄漏——大量无用的数据一直占用着内存,并且不会被删除。
定期删除
相比较定时删除对CPU的不友好,惰性删除的对内存不友好。定期删除采用了一种折中的方式:
- 定期删除策略每隔一段时间执行一次删除过期键操作,并通过限制删除操作执行的时长和频率来减少删除操作对CPU时间的影响。
- 并且,通过定期删除过期键,有效的减少了过期键带来的内存浪费。
但删除的时长和频率比较难定义,因为:
- 如果频率太高或者时长太长,那么会占用大量的CPU时长。
- 如果过短又会出现内存浪费的情况。
因此。如果采用定期删除策略的话需要通过具体的业务场景来定义时长和频率。
Redis实际使用的是惰性删除+定期删除的策略。
通过这两种方式可以很好的利用CPU时间以及避免内存浪费的情况。接下来讲讲惰性删除以及定期删除的实现。
惰性删除策略的实现
惰性删除策略由 expireIfNeeded 函数实现,所有读写数据库的 Redis 命令在执行之前都会调用 exipreIfNeeded 函数对输入键进行检查。
- 如果键过期,会将键删除并返回空。
- 如果键没有过期,则不做操作。
定期删除策略的实现
定期删除策略由 activeExpireCucle 函数实现,被调用时,它在规定的时间内,分多次遍历服务器中的各个数据库,从数据库的 expires 字典中随机检查一部分键的过期时间,并删除其中的过期键。
- 函数每次运行时,都是从一定数量的数据库键中随机取一定数量的键进行检查,并删除其中的过期键。
- 有一个全局变量 current_db 会记录当前 activeExpireCycle 函数检查的进度,并且下一次 函数执行时,接着上一次的进度进行处理。如,当前 activeExpireCycle 函数执行到了 10, 讲 current_db = 10;然后下一次函数执行时,从 current_db 取到 10 继续执行。
- 当所有的数据库键都被检查完时, current_db = 0。
AOF、RDB 和复制功能对过期键的处理
生成 RDB 文件
在执行 SAVE 命令或 BGSAVE 命令创建一个新的 RDB 文件时,程序会对数据库中的键进行检查,已过期的键不会被保存到新的 RDB 文件中。
如:redis中包含 r1、r2、r3 三个键,并且 r1 已经过期,那么程序只会讲 r2 和 r3 保存到 RDB 文件中。
因此,过期键不会对新的 RDB 文件造成影响。
载入 RDB 文件
在启动 redis 服务器时,如果服务器开启了 RDB 功能,那么服务器将对 RDB 文件进行载入;
- 如果服务器以主服务器模式运行,那么在载入 RDB 文件时,过期的键会被过滤掉,不会被载入到redis数据库中。
- 如果以从服务器模式运行,那么无论键是否过期都会被载入到数据库中。但,因为主从服务器在进行数据同步时,从服务器就会被清空,所以,一般来说,过期键对从服务器也不会造成影响。
AOF 文件写入
当服务器开启 AOF 的运行模式时,如果某个键过期了,但没有被惰性或定期删除,那么 AOF 不会理会。如果被惰性或定期删除了, AOF 会在文件末尾追加一条 DEL 命令,来显示地记录该键已被删除。
AOF 重写
当 AOF 重写时,过期的键不会被载入到 redis 数据库中。
复制
当服务器在 复制 模式下时,从服务器的过期键删除动作都是由主服务器来进行的。
- 主服务器在删除一个过期键之后,会显示地向所有从服务器发送一个 DEL 命令,告知从服务器删除这个过期键。
- 从服务器在执行客户端发送的读命令时,即使碰到过期的键也不会删除,而是继续的正常操作。
- 从服务器只有在接到主服务器发来的 DEL 命令之后,才会删除过期键。
最后
Redis 的过期键删除策略是 惰性删除 + 定期删除,这也既可以合理的控制 CPU 使用 还可以 减少内存的浪费。
关于更多 Java 知识以及刷题分享,可以来公众号 蘑菇睡不着 看看,大家一起学习。
你越主动就会越主动,我们下期见~
Redis的过期键删除策略的更多相关文章
- Redis系列(五):Redis的过期键删除策略
本篇博客是Redis系列的第5篇,主要讲解下Redis的过期键删除策略. 本系列的前4篇可以点击以下链接查看: Redis系列(一):Redis简介及环境安装 Redis系列(二):Redis的5种数 ...
- 【Redis】过期键删除策略和内存淘汰策略
Redis 过期键策略和内存淘汰策略 目录 Redis 过期键策略和内存淘汰策略 设置Redis键过期时间 Redis过期时间的判定 过期键删除策略 定时删除 惰性删除 定期删除 Redis过期删除策 ...
- redis中key的过期键删除策略
Redis过期键删除策略 Redis key过期的方式有三种: 被动删除:当读/写一个已经过期的key时,会触发惰性删除策略,直接删除掉这个过期key 主动删除:由于惰性删除策略无法保证冷数据被及时删 ...
- 一文了解:Redis过期键删除策略
Redis过期键删除策略 Redis中所有的键都可以设置过期策略,就像是所有的键都可以上"生死簿",上了生死簿的键到时间后阎王就会叉掉这个键.同一时间大量的键过期,阎王就会忙不过来 ...
- redis的3种过期键删除策略
Redis的过期键的过期时间都保存在过期字典中,过期键的删除策略有三种,分别是定时删除.惰性删除和定期删除. 定时删除 定时删除策略,是指在设置键的过期时间的同时,创建一个定时器,让定时器在键的过期时 ...
- Redis 过期键删除策略
Redis 中数据库键的过期时间都保存在过期字典中,当一个键过期了,Redis 存在三种不同的删除策略:定时删除.惰性删除和定期删除 定时删除 定义 在设置键的过期时间的同时创建一个计时器,让定时器在 ...
- redis过期键删除策略以及大key删除方法
今天遇到了一个前同事挖的坑,刷新缓存中商品信息时先让key过期,然后从数据库里取最新数据然后再放到缓存中,他是这样写的 redisTemplate.expire(CacheConst.GOOGS_PR ...
- redis过期键的策略
一.过期时间设置: 127.0.0.1:6379> expire key seconds //设置键的过期时间为多少秒 127.0.0.1:6379> setex key seconds ...
- Redis数据过期和淘汰策略详解(转)
原文地址:https://yq.aliyun.com/articles/257459# 背景 Redis作为一个高性能的内存NoSQL数据库,其容量受到最大内存限制的限制. 用户在使用Redis时,除 ...
随机推荐
- 【python】Leetcode每日一题-丑数
[python]Leetcode每日一题-丑数 [题目描述] 给你一个整数 n ,请你判断 n 是否为 丑数 .如果是,返回 true :否则,返回 false . 丑数 就是只包含质因数 2.3 和 ...
- 改善c++程序的150个建议(读后总结)-------19-26
19. 明白在c++中如何使用c c++可以兼容c的绝大部分代码,但是还是有一部分不能兼容. c语言的编译器在调用函数时会把函数翻译成 : "_函数名",例如: int nasa( ...
- makefile的函数集合
strip函数:$(strip text) 函数功能:去除字符串空格函数 示例: STR = a b c LOSTR = $(strip $(STR)) #结果是&quo ...
- ArrayList方法源码分析
本文将从ArrayList类的存储结构.初始化.增删数据.扩容处理以及元素迭代等几个方面,分析该类常用方法的源码. 数据存储设计 该类用一个Object类型的数组存储容器的元素.对于容量为空的情况,提 ...
- [OS] 操作系统课程(五)
系统启动 启动过程 CPU加电稳定后从0XFFFF0读取第一条指令 BIOS 固化到计算机主板上的程序 包括系统设置.自检程序和系统自启动程序 系统加电后读BIOS 加电自检POST,内存.显卡等关键 ...
- centos7 连接打印机
centos7 连接打印机 2017-08-07 15:05:33 五岳寻仙客 阅读数 2531更多 分类专栏: Liunx的日常使用 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版 ...
- Spark 集群安装部署
安装准备 Spark 集群和 Hadoop 类似,也是采用主从架构,Spark 中的主服务器进程就叫 Master(standalone 模式),从服务器进程叫 Worker Spark 集群规划如下 ...
- Ansible_管理playbook实现配置并行
一.使用forks在Ansible中配置并行 1.Aniable运行play机制 1️⃣:当Ansible处理playbook时,会按顺序运行每个play.确定play的主机列表之后,Ansible将 ...
- 基于多端口的Web服务
[Centos7.4版本] !!!测试环境我们首关闭防火墙和selinux [root@localhost ~]# systemctl stop firewalld [root@localhost ~ ...
- Ansible-入门使用方法
Ansible介绍 自动化运维工具,统一配置管理工具.自动化主要体现在Ansible集成了丰富模块以及功能组件,可以通过一个命令完成一系列的操作,进而能减少重复性的工作和维护成本,可以提高工作效率. ...