TTL 在 Redis 缓存中的作用

Redis TTL(Time To Live)与缓存的关系

TTL(Time To Live,生存时间)是 Redis 提供的一种自动过期机制 ,用于控制键值对的存活时间。当 TTL 到期后,Redis 会自动删除 该键,避免长期占用内存。这对于缓存系统来说至关重要,因为它能够有效防止缓存过载,并确保数据的一致性和实时性。


1. TTL 相关的 Redis 命令

1.1. 设置 TTL

  • EXPIRE key seconds :为 key 设置 seconds 秒的 TTL。
  • PEXPIRE key milliseconds :为 key 设置 milliseconds 毫秒的 TTL。
  • SETEX key seconds value :设置 key 的值,同时指定 seconds 秒的过期时间。
  • PSETEX key milliseconds value :设置 key 的值,同时指定 milliseconds 毫秒的过期时间。

示例:

bash 复制代码
SETEX user:1001 3600 "Alice"  # 设置1小时后过期
PEXPIRE user:1001 60000       # 设置60秒后过期

Python 代码示例:

python 复制代码
import redis

cache = redis.Redis(host='localhost', port=6379, decode_responses=True)

# 设置缓存数据并指定 TTL
cache.setex("user:1001", 3600, "Alice")  # 1小时后过期
cache.pexpire("user:1001", 60000)        # 60秒后过期

1.2. 查询 TTL

  • TTL key :返回 key 还有多少秒过期。
  • PTTL key :返回 key 还有多少毫秒过期。

示例:

bash 复制代码
TTL user:1001   # 查询 key 还剩多少秒过期
PTTL user:1001  # 查询 key 还剩多少毫秒过期

Python 代码示例:

python 复制代码
ttl = cache.ttl("user:1001")
print(f"user:1001 剩余 TTL: {ttl} 秒")

1.3. 移除 TTL

  • PERSIST key :移除 key 的 TTL,使其永久存在。

示例:

bash 复制代码
PERSIST user:1001  # 让 user:1001 永不过期

Python 代码示例:

python 复制代码
cache.persist("user:1001")  # 取消 TTL,使其永久存在

2. TTL 在缓存中的作用

2.1. 避免缓存污染

  • 设定合理的 TTL 可以避免缓存存储长期无用的数据,减少内存占用。
python 复制代码
cache.setex("session:12345", 1800, "session_data")  # 30分钟后自动删除

2.2. 解决缓存雪崩

缓存雪崩 是指大量缓存数据在同一时间过期,导致所有请求直接访问数据库,造成数据库崩溃。

解决方案:

  • 使用随机 TTL,让不同的 key 过期时间分散,防止同时失效。
python 复制代码
import random

ttl = 3600 + random.randint(0, 600)  # 1小时 + 0~10分钟随机时间
cache.setex("user:1001", ttl, "Alice")

2.3. 解决缓存击穿

缓存击穿 发生在某个热点数据突然过期,大量请求同时访问数据库,导致数据库压力过大。

解决方案:

  1. 热点数据设置较长 TTL 或永不过期

    python 复制代码
    cache.set("hot_key", "important_data")
    cache.persist("hot_key")  # 使其永久有效
  2. 使用互斥锁防止并发查询

    python 复制代码
    lock = cache.setnx("lock:user:1001", 1)  # 尝试加锁
    if lock:
        value = get_data_from_db("user:1001")
        cache.setex("user:1001", 3600, value)  # 更新缓存
        cache.delete("lock:user:1001")  # 释放锁

2.4. 解决缓存穿透

缓存穿透 是指大量查询数据库中不存在的数据,导致每次请求都无法命中缓存,直接访问数据库。

解决方案:

  1. 缓存空值

    python 复制代码
    value = cache.get("user:9999")
    if value is None:
        db_value = get_data_from_db("user:9999")
        if db_value is None:
            cache.setex("user:9999", 3600, "NULL")  # 存一个空值,防止查询数据库
        else:
            cache.setex("user:9999", 3600, db_value)
  2. 使用布隆过滤器(Bloom Filter) 预判 key 是否可能存在,减少无效查询。


3. TTL 相关的 Redis 淘汰策略

Redis 提供了多种淘汰策略,决定当 Redis 内存满时哪些数据会被删除

  • volatile-lru :淘汰最近最少使用的已设置 TTL 的 key。
  • allkeys-lru:在所有 key 中淘汰最近最少使用的 key(适用于纯缓存模式)。
  • volatile-ttl :优先淘汰存活时间最短的 key。
  • noeviction:内存满时直接返回错误,不淘汰任何 key(默认策略)。

设置 Redis 淘汰策略:

bash 复制代码
CONFIG SET maxmemory-policy allkeys-lru

4. 总结

  • TTL 是 Redis 自动过期机制,用于设置数据的生存时间,避免长期占用内存。
  • 合理设置 TTL 可以有效防止缓存雪崩、缓存击穿、缓存穿透等问题。
  • TTL 与 Redis 淘汰策略(LRU、TTL 淘汰)结合使用,可以优化缓存性能。

TTL 在 Redis 缓存中的作用不可忽视,合理利用 TTL 可以极大提升系统的稳定性和效率。

相关推荐
听封7 分钟前
✨ 索引有哪些缺点以及具体有哪些索引类型
数据库·mysql
利瑞华11 分钟前
数据库索引:缺点与类型全解析
数据库·oracle
V+zmm1013415 分钟前
自驾游拼团小程序的设计与实现(ssm论文源码调试讲解)
java·数据库·微信小程序·小程序·毕业设计
ChinaRainbowSea26 分钟前
1. Linux下 MySQL 的详细安装与使用
linux·数据库·sql·mysql·adb
HUNAG-DA-PAO1 小时前
Redis存在线程安全吗?为什么?
redis·安全·php
jay丿2 小时前
Redis 中列表(List)常见命令详解
数据库·redis·list
小林熬夜学编程2 小时前
【MySQL】第八弹---全面解析数据库表的增删改查操作:从创建到检索、排序与分页
linux·开发语言·数据库·mysql·算法
RainbowSea3 小时前
4. MySQL 逻辑架构说明
数据库·sql·mysql
AI趋势预见3 小时前
FinRL-DeepSeek: 大语言模型赋能的风险敏感型强化学习交易代理
数据库·人工智能·语言模型·自然语言处理·金融
ok0603 小时前
Oracle定时执行计划任务
数据库·oracle