Redis中如何设置过期时间
【摘要】 在 Redis 中,可以通过多种命令为 Key 设置过期时间(TTL,Time To Live),过期后 Redis 会自动删除该 Key。以下是详细的设置方法、注意事项和最佳实践: 1. 设置过期时间的核心命令 (1) EXPIRE:为已存在的 Key 设置过期时间SET mykey "value" # 先设置一个 KeyEXPIRE mykey 60 # 设置...
在 Redis 中,可以通过多种命令为 Key 设置过期时间(TTL,Time To Live),过期后 Redis 会自动删除该 Key。以下是详细的设置方法、注意事项和最佳实践:
1. 设置过期时间的核心命令
(1) EXPIRE
:为已存在的 Key 设置过期时间
SET mykey "value" # 先设置一个 Key
EXPIRE mykey 60 # 设置 60 秒后过期
- 返回值:
1
:设置成功。0
:Key 不存在或设置失败。
(2) EXPIREAT
:设置 Key 在指定 Unix 时间戳过期
EXPIREAT mykey 1633046400 # 设置 Key 在 2021-10-01 00:00:00 过期
- 适用场景:需要精确控制过期时间的场景(如定时任务)。
(3) SET
命令直接设置过期时间
SET mykey "value" EX 60 # 设置值并指定 60 秒后过期
SET mykey "value" PX 60000 # 设置值并指定 60000 毫秒后过期
- 参数:
EX <seconds>
:秒级过期。PX <milliseconds>
:毫秒级过期。
- 优点:原子操作,避免竞态条件。
(4) PERSIST
:移除 Key 的过期时间
PERSIST mykey # 将 Key 设置为永久有效
2. 检查和修改过期时间
(1) TTL
:查看 Key 的剩余生存时间
TTL mykey # 返回剩余秒数
# 返回值:
# -2:Key 不存在。
# -1:Key 存在但没有设置过期时间。
# N:剩余 N 秒过期。
(2) PTTL
:查看剩余毫秒数
PTTL mykey # 返回剩余毫秒数
(3) 修改过期时间
- 直接重新执行
EXPIRE
或EXPIREAT
即可覆盖原有 TTL。
3. 批量设置过期时间
(1) 使用 MSET
+ EXPIRE
(非原子)
MSET key1 "value1" key2 "value2" # 批量设置值
EXPIRE key1 60
EXPIRE key2 120
- 缺点:非原子操作,可能部分 Key 设置失败。
(2) 使用 Lua 脚本(原子操作)
-- 批量设置 Key 并指定不同 TTL
local keys = {"key1", "key2"}
local values = {"value1", "value2"}
local ttls = {60, 120} -- 秒
for i, key in ipairs(keys) do
redis.call("SET", key, values[i], "EX", ttls[i])
end
- 优点:保证所有操作原子性。
(3) 使用 SCAN
+ 管道(Pipeline)
# 伪代码:遍历匹配的 Key 并批量设置过期时间
SCAN 0 MATCH "user:*" COUNT 1000 | xargs -I {} redis-cli EXPIRE {} 3600
- 适用场景:对已有 Key 批量补设过期时间。
4. 过期时间的底层实现
Redis 通过以下机制管理过期时间:
- 数据结构:
- 每个 Key 的元数据中存储
expire
字段(Unix 时间戳)。 - 过期 Key 会被记录在全局的过期字典(
expires
哈希表)中。
- 每个 Key 的元数据中存储
- 删除策略:
- 惰性删除:访问 Key 时检查是否过期。
- 定期删除:后台线程随机抽查过期 Key 并删除。
5. 注意事项
(1) 过期时间的精度
- Redis 的过期时间是秒级或毫秒级(取决于命令)。
- 实际删除可能存在 1 秒内 的延迟(受定期删除策略影响)。
(2) 持久化影响
- RDB:生成快照时会过滤过期 Key,不会写入磁盘。
- AOF:过期 Key 的删除操作会以
DEL
命令形式追加到 AOF 文件。
(3) 主从复制
- 主库删除过期 Key 后会通知从库同步删除。
- 如果主库未访问过期 Key,从库可能暂时保留(需依赖惰性删除)。
(4) 内存不足时的行为
- 如果 Redis 内存达到
maxmemory
限制,会优先触发淘汰策略(如 LRU),而非等待过期删除。
6. 最佳实践
(1) 避免集中过期
- 为批量 Key 设置随机 TTL,防止雪崩:
-- Lua 脚本:为每个 Key 设置 60~120 秒的随机过期时间 local key = KEYS[1] local value = ARGV[1] local ttl = 60 + math.random(60) -- 60~120 秒 redis.call("SET", key, value, "EX", ttl)
(2) 热点数据谨慎设置过期时间
- 对高频访问的 Key,建议:
- 使用长 TTL(如数小时)。
- 或通过后台任务定期刷新 TTL。
(3) 监控过期 Key
- 启用过期事件通知:
# redis.conf 中配置 notify-keyspace-events Ex
- 订阅频道:
PSUBSCRIBE __keyevent@0__:expired # 监听数据库 0 的过期事件
(4) 结合业务逻辑设计 TTL
- 缓存场景:TTL 应略小于数据源的更新周期。
- 会话管理:TTL 与用户会话时长一致(如 30 分钟)。
7. 常见问题
Q1:设置过期时间后,能否修改值而不影响 TTL?
- 是的,
SET
命令默认会保留原有 TTL:SET mykey "new_value" # 保留原有 TTL
- 如需重置 TTL,需重新执行
EXPIRE
。
Q2:为什么 TTL
返回 -2
?
- 表示 Key 不存在(可能已被删除或未设置)。
Q3:如何设置永不过期的 Key?
- 不设置过期时间,或使用
PERSIST
移除 TTL。
总结
命令 | 作用 | 示例 |
---|---|---|
EXPIRE key seconds |
设置 Key 在 N 秒后过期 | EXPIRE mykey 60 |
EXPIREAT key timestamp |
设置 Key 在 Unix 时间戳过期 | EXPIREAT mykey 1633046400 |
SET key value EX seconds |
原子性设置值和过期时间 | SET mykey "value" EX 60 |
TTL key |
查看剩余生存时间(秒) | TTL mykey |
PERSIST key |
移除 Key 的过期时间 | PERSIST mykey |
通过合理使用这些命令,可以高效管理 Redis 中的数据生命周期,避免内存泄漏和性能问题。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)