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 可以极大提升系统的稳定性和效率。

相关推荐
DZSpace几秒前
从单机到集群:Docker、Kubernetes 与 Helm 部署 Redis 全攻略
redis·docker·kubernetes
TechNomad16 分钟前
Qt开发:QSqlDatabase的常见用法
数据库·qt
老马啸西风18 分钟前
数据库高可用方案-04-删除策略
数据库·oracle
ekskef_sef1 小时前
Nginx—Rewrite
java·数据库·nginx
道剑剑非道1 小时前
QT开发技术 【基于TinyXml2的对类进行序列化和反序列化】 二
java·数据库·qt
明月看潮生2 小时前
青少年编程与数学 02-007 PostgreSQL数据库应用 09课题、规则、约束和默认值
数据库·青少年编程·postgresql·编程与数学
Hurry62 小时前
Mysql 主从复制原理及其工作过程,配置一主两从实验
数据库·mysql
卜及中2 小时前
【Tortoise-ORM】 高级特性与实战
jvm·数据库·oracle·webstorm
早知道不学Java了3 小时前
【达梦数据库(Oracle模式)】如何将视图中的数据导出
数据库·oracle