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

相关推荐
Chengbei113 分钟前
一次比较简单的360加固APP脱壳渗透
网络·数据库·web安全·网络安全·系统安全·网络攻击模型·安全架构
寒秋花开曾相惜4 分钟前
(学习笔记)3.9 异质的数据结构(3.9.1 结构)
c语言·网络·数据结构·数据库·笔记·学习
mcooiedo15 分钟前
mybatisPlus打印sql配置
数据库·sql
wudl556620 分钟前
MySQL 8.0.42 Docker 开发部署手册
数据库·mysql·docker
xhuiting25 分钟前
MySQL专题总结(四)—— 高可用
java·数据库·mysql
kjmkq37 分钟前
目工业级宽温SSD哪个品牌不掉盘最稳定?宽温环境下的稳定性性技术解析
数据库·存储
Predestination王瀞潞1 小时前
Java EE3-我独自整合(第二章:Spring IoC 入门案例)
数据库·spring·java-ee
梁山话事人1 小时前
Spring IOC
java·数据库·spring
魔都吴所谓1 小时前
【Linux】Ubuntu22.04 Docker+四大数据库(挂载本地)一键安装脚本
linux·数据库·docker
麦聪聊数据1 小时前
电商数据运营的最佳实践:WebSQL 如何兼顾数据分析效率与生产库安全
数据库·sql·低代码·restful