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

相关推荐
IT项目管理1 小时前
达梦数据库DMHS介绍及安装部署
linux·数据库
你都会上树?1 小时前
MySQL MVCC 详解
数据库·mysql
大春儿的试验田1 小时前
高并发收藏功能设计:Redis异步同步与定时补偿机制详解
java·数据库·redis·学习·缓存
likeGhee1 小时前
python缓存装饰器实现方案
开发语言·python·缓存
hqxstudying1 小时前
Redis为什么是单线程
java·redis
C182981825752 小时前
OOM电商系统订单缓存泄漏,这是泄漏还是溢出
java·spring·缓存
Ein hübscher Kerl.2 小时前
虚拟机上安装 MariaDB 及依赖包
数据库·mariadb
醇醛酸醚酮酯2 小时前
Qt项目锻炼——TODO清单(二)
开发语言·数据库·qt
GreatSQL社区3 小时前
用systemd管理GreatSQL服务详解
数据库·mysql·greatsql
掘根3 小时前
【MySQL进阶】错误日志,二进制日志,mysql系统库
数据库·mysql