Redis 实时查询有效期主要通过 TTL 命令实现,但其限制在于频繁查询会增加服务器负载,且过期删除并非绝对实时,而是采用定期删除加惰性删除策略,可能存在短暂延迟。数据时效管理需结合业务场景设置合理的过期时间,避免过短导致频繁重建或过长占用内存。同时应配置内存淘汰策略如 allkeys-lru,防止内存爆满。对于需要活跃续期的场景,可通过业务层调用 expire 命令动态更新有效期,弥补 Redis 原生不支持 TTI 的不足,确保数据时效性与系统性能的平衡。
记录 Redis 管理有效期记录的技巧 (redis 获取有效期)
Redis 还支持设置键的有效期,使其在一段时间内只存在于内存中,这是非常有用的特性,特别是在一些临时任务或会话中使用。在本文中,我们将学习如何有效地管理 Redis 中的有效期记录。让我们来看一下如何设置一个键的有效期。Redis 提供了两种方法来设置键的有效期:一种是使用 EXPIRE 命令,另一种是使用 EXPIREAT 命令。EXPIRE 命令可以将一个键的有效期设置为一定的秒数,如下所示:"`redis > SET mykey"Hello"OK > EXPIRE mykey 10 (integer) 1 > TTL mykey (integer) 10 上面的代码设置了一个名为"mykey"的键的有效期为 10 秒。TTL 命令用于查询剩余的过期时间,查询到的时间单位是秒。但是,EXPIRE 命令存在一个问题:如果我们想将有效期设置为一个绝对的时间点,而不是一个相对时间段,该怎么办呢?这时候,我们就需要使用 EXPIREAT 命令了。EXPIREAT 命令与 EXPIRE 命令类似,只是它的第二个参数是一个时间戳,表示该键的过期时间点,如下所示:```redis > SET mykey"Hello"OK > EXPIREAT mykey 1635721177 (integer) 1 > TTL mykey (integer) 84602 上面的代码将"mykey"键的有效期设置为 2021 年 11 月 1 日 00:00:00,即时间戳 1635721177。TTL 命令查询剩余时间的单位为秒。设置有效期之后,我们需要对过期的键进行清理,以释放内存。Redis 默认每秒钟检查一次过期键,如果过期了就将其删除。但是,如果我们在 Redis 中存储了大量的键,需要删除的键也会变得非常多,Redis 就会成为一个评价瓶颈。为了避免这种情况发生,我们需要进行一些管理有效期记录的技巧。技巧 1:设置适当的有效期时间。如果有效期设置得太短,那么就需要更频繁地重新设置有效期,从而增加 Redis 的负载。如果有效期太长,那么过期的键就需要占用更长的时间,增加 Redis 的内存消耗。因此,要根据业务需求进行适当设置有效期时间。技巧 2:使用 Redis 的弱化过期键检查机制。在使用 Redis 时,我们可以关闭默认的过期键检查机制,并使用专用 app 清除过期的键。这样可以减轻 Redis 的负担并提高性能,减少延迟。技巧 3:避免使用"*"或"keys"命令。这些命令可以列出所有的键,但是它们要扫描整个 Redis 数据库,会对性能产生负面影响。因此,应该避免在生产环境中使用这些命令。技巧 4:使用 Redis 的 Lua 脚本,以避免出现竞态条件。当多个客户端同时尝试删除过期键时,有可能出现竞态条件。(撰于 2025 年 9 月 28 日)
关于 Redis 数据的有效期
关于 Redis 数据的有效期 Redis 通过混合使用定时、惰性和定期过期策略来管理键的生命周期。定时策略确保精确删除但消耗 CPU,惰性策略在访问时检查过期,节省 CPU 但可能延迟清理,定期策略则定期扫描并删除过期键。Redis 默认每 100ms 随机检查并删除过期键,结合惰性策略防止漏网之鱼。1.有效期 Timeto live(TTL ) 设置有效期的作用:节省空间 做到数据弱一致性,有效期失效后,可以保证数据的一致性 2.Redis 的过期策略 定时过期 每个设置过期时间的 key 都需要创建一个定时器,到过期时间就会立即清除。优点:准确 缺点:CPU 消耗大 惰性过期 只有当访问一个 key 时,才会判断该 key 是否已过期,过期则清除。有点:CPU 消耗少 缺点:如果一个 key 一直不访问,就不会过期 定期过期 每隔一定的时间,会扫描一定数量的数据库的 expires 字典中一定数量的 key,并清除其中已过期的 key。上述方案的折中 总结 Redis 中同时使用了惰性过期和定期过期两种过期策略。Redis 过期删除采用的是定期删除,默认是每 100ms 检测一次,遇到过期的 key 则进行删除,这里的检测并不是顺序检测,而是随机检测。那这样会不会有漏网之鱼?显然 Redis 也考虑到了这一点,当我们去读/写一个已经过期的 key 时,会触发 Redis 的惰性删除策略,直接回干掉过期的 key(发布时间是 2022 年 5 月 12 日)
redis 有效时间设置及时间过期处理_查看 redis 状态
redis 是在内存中进行缓存的,我们在设置 redis 缓存时,可以设置下过期时间。那么在设置时间到期后 redis 是如何进行数据删除的。redis 清理过期数据。定期清理 + 惰性清理 定期删除:redis 数据库默认每隔 100ms 就会进行随机抽取一些设置过期时间的 key 进行检测,过期则删除。惰性删除:定期删除还没有来得及删除,就被程序请求到的一个过期 key,redis 会先检测 key 是否,过期,如果过期则删除,不进行返回。但是前面两种机制可能还导致一些问题就是,过期的 key 如果大量堆积,删除的速度太慢,内存爆满怎么办?内存淘汰机制 1)noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。2)allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的 key(这个是最常用的) 就是 LRU 算法。3)allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个 key,一般没人用。4)volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的 key(这个一般不太合适) 5)volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个 key 6)volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的 key 优先移除 LRU 算法实现 public class LRUCache extends LinkedHashMap { private final int CACHE_SIZE; // 这里就是传递进来最多能缓存多少数据 public LRUCache(int cacheSize) { super((int) Math.ceil(cacheSize / 0.75) + 1, 0.75f, true); // 这块就是设置一个 hashmap 的初始大小,同时最后一个 true 指的是让 linkedhashmap 按照访问顺序来进行排序,最近访问的放在头,最老访问的就在尾 CACHE_SIZE = cacheSize; } @Override protected boolean removeEldestEntry(Map.Entry eldest) { return size() > CACHE_SIZE; // 这个意思就是说当 map 中的数据量大于指定的缓存个数的时候,就自动删除最老的数据 } } public static void main(String[] args) { LRUCache testCache = new LRUCache<>(3); testCache.put("A", 1); testCache.put("B", 2); testCache.put("C", 3);ut.println(testCache.get("B")); System.out.println(testCache.get("A")); testCache.put("D", 4); System.out.println(testCache.get("D")); System.o System.out.println(testCache.get("B")); (资料日期为 2023 年 2 月 2 日)
Redis 缓存何以一枝独秀?(2) —— 聊聊 Redis 的数据过期、数据淘汰以及数据持久化的实现机制
上一篇文章中呢,我们简单的介绍了下 Redis 的整体情况。作为集中式缓存的优秀代表,Redis 可以帮助我们在项目中完成很多特定的功能。Redis 准确的说是一个非关系型数据库,但是由于其超高的并发处理性能,及其对于缓存场景所提供的一系列能力构建,使其成为了分布式系统中的集中缓存的绝佳选择。Redis 对于缓存能力场景的支持,除了基础的缓存增删改查,还支持对记录的过期时间设定,支持多种不同的数据淘汰策略等等。此外为了解决内存型组件数据可靠性问题,还提供了一系列的数据持久化方案。本篇文章中,我们就一起聊一聊这方面内容。数据过期能力 为了节约内存的使用量,保证有限的内存空间能够被更有价值的数据使用,所以很多内存缓存组件都会支持数据过期能力。之前我们提过的本地缓存组件 Guava Cache、Caffeine 等支持基于缓存容器对象级别设置统一的过期时间,而 Redis 则支持对每条记录设定单独的过期时间。创建时设定过期时间 可以在创建记录的时候指定过期时间,redis 提供了 setex 命令可以实现插入的时候同步指定过期时间。比如:代码语言:shell AI 代码解释 setex key15value1 上述命令实现了往 redis 中写入一个 key1 记录,并同时设定了 5s 后过期。如果在 JAVA SpringBoot 项目中可以直接使用相关 API 接口来实现:代码语言:java AI 代码解释 stringRedisTemplate.opsForValue().set("key1","value1",5,TimeUnit.SECONDS); 这样缓存写入 5s 之后,缓存记录就会过期失效。描述到这里可以看出,这是一种基于创建时间来判定是否过期的机制,也即常规上说的 TTL 策略,当设定了过期时间之后不管有没有被使用都会到期被强制清理掉。但有很多场景下也会期望数据能够按照 TTI(指定时间未使用再过期) 的方式来过期清理,如用户鉴权场景:假设用户登录系统后生成 token 并存储到 Redis 中,指定 token 有效期 30 分钟,那么如果用户一直在使用系统的时候突然时间到了然后退出要求重新登录,这个体验感就会很差。正确的预期应该是用户连续操作的时候就不要退出登录,只有连续 30 分钟没有操作的时候才过期处理。略有遗憾的是,Redis 并不支持按照 TTI 机制来做数据过期处理。但是作为补偿,Redis 提供了一个重新设定某个 key 值过期时间的方法,可以通过 expire 方法来实现指定 key 的续期操作,以一种曲线救国的方式满足诉求。(截至 2024 年 7 月 6 日)
FAQ
Redis 过期键删除策略有哪些?
Redis 主要采用定期删除和惰性删除两种策略。定期删除默认每 100ms 随机检查部分键,惰性删除则在访问键时检查是否过期。
内存满时 Redis 如何处理?
Redis 提供多种内存淘汰策略,如 allkeys-lru 移除最近最少使用的键,或 volatile-ttl 优先移除更早过期的键。
Redis 支持 TTI 过期机制吗?
原生不支持 TTI,但可通过业务层调用 expire 命令动态续期来模拟实现。
TTL 命令返回值含义是什么?
返回 -2 表示键不存在,-1 表示键存在但无过期时间,正数表示剩余生存时间秒数。