redis 的命令 expire 设置键的生存时间

1.redis 的命令 expire 设置键的生存时间
EXPIRE
设置key的生存时间(秒)

语法
EXPIRE key seconds [NX | XX | GT | LT]

从以下版本可用:
1.0.0

时间复杂度:
O(1)
ACL 类别:
@keyspace, @write, @fast
在key上设置超时。超时后,key将自动删除。在Redis术语中,带有相关超时的key通常被称为 volatile (不稳定的)。
只有删除或覆盖key内容的命令才能清除超时,包括DEL,设置,GET SET以及所有*STORE命令。这意味着,所有在概念上“改变”
存储在key处的值而不将其替换为新值的操作都将保持超时不变。例如,用INCR递增键的值,使用LPUSH将新值推入列表,
或使用HSET更改哈希的字段值是所有不影响超时的操作。
也可以清除超时,使用PERSIST将key返回为持久key命令。

如果使用RENAME重命名key,关联的生存时间将转移到新的key名称。
如果key被RENAME覆盖类似于被诸如RENAME key_B key_A之类的调用覆盖的现有 key_A的情况,
原始   key_A 是否具有相关联的超时并不重要,新 key_A将继承key_B的所有特性。

请注意,调用EXPIRE/PEXPIRE 具有非正超时或 EXPIREAT/PEXPIREAT 在过去的某个时间将导致key被删除而不是过期
(相应地,发出的key event将是del,而不是expired)。

#选项
该EXPIRE命令支持一组选项:

NX-- 只有当key没有过期时才设置过期
XX-- 仅当key已过期时才设置过期 #没有理解 
GT-- 仅当新的到期时间大于当前到期时间时才设置到期时间
LT-- 仅在新到期时间小于当前到期时设置到期
非易失性key被视为无限 TTL GT和LT。,GT和选项是互斥的LT。NX

#刷新过期
可以 EXPIRE 使用已经具有现有过期集的键作为参数来调用。在这种情况下,key的生存时间会更新为新值。
有许多有用的应用程序,下面的 导航会话模式部分记录了一个示例。
#Redis 2.1.3 之前的差异
在 Redis 2.1.3之前的版本中,使用更改其值的命令更改设置了过期时间的键具有完全删除该键的效果。
由于复制层的限制现已修复,因此需要此语义。
EXPIRE将返回 0 并且不会更改设置了超时的键的超时。

#返回
Integer,具体来说:

1如果设置了超时。
0如果未设置超时。例如,键不存在,或者由于提供的参数而跳过了操作。
#例子
redis> SET mykey "Hello"
 "OK"
 redis> EXPIRE mykey 10
 (integer) 1
 redis> TTL mykey
 (integer) 10
 redis> SET mykey "Hello World"
 "OK"
 redis> TTL mykey
 (integer) -1
 redis> EXPIRE mykey 10 XX
 (integer) 0
 redis> TTL mykey
 (integer) -1
 redis> EXPIRE mykey 10 NX
 (integer) 1
 redis> TTL mykey
 (integer) 10
  redis> 
#模式:导航会话
假设您有一个 Web 服务,并且您对 用户最近访问的最近 N 个页面感兴趣,这样每个相邻的页面视图都不会在前一个页面的 60 秒后执行。
从概念上讲,您可以将这组页面视图视为用户的导航会话 ,其中可能包含有关他或她当前正在寻找哪种产品的有趣信息,以便您可以推荐相关产品。

您可以使用以下策略在 Redis 中轻松建模此模式:每次用户进行页面查看时,您调用以下命令:

MULTI
RPUSH pagewviews.user:<userid> http://.....
EXPIRE pagewviews.user:<userid> 60
EXEC
如果用户闲置超过 60 秒,则删除该键,仅记录相差小于 60 秒的后续页面浏览量。
这种模式很容易修改为使用计数器使用 INCR 而不是使用列表 RPUSH。

#附录:Redis过期
#过期的key
通常,创建 Redis key时没有关联的生存时间。key将永远存在,除非用户以明确的方式将其删除,例如使用 DEL 命令。
命令族能够将EXPIRE过期时间与给定的键相关联,但代价是该键使用了一些额外的内存。
当一个键设置了过期时间时,Redis 将确保在指定的时间过去后删除该键。
EXPIRE可以使用and PERSIST 命令(或其他严格相关的命令)更新或完全删除关键生存时间。

#过期精度
在 Redis 2.4 中,过期可能不是精确的,它可能在零到一秒之间。
从 Redis 2.6 开始,过期错误为 0 到 1 毫秒。

#过期和持久性
key过期信息存储为绝对 Unix 时间戳(在 Redis 2.6 或更高版本的情况下以毫秒为单位)。
这意味着即使 Redis 实例不活动,时间也在流逝。
为了使过期工作正常,计算机时间必须保持稳定。如果您从两台时钟严重不同步的计算机上移动 RDB 文件,
可能会发生有趣的事情(例如所有加载的key在加载时都已过期)。
即使正在运行的实例也会始终检查计算机时钟,因此,例如,如果您将key的生存时间设置为 1000 秒,
然后将您的计算机时间设置为未来 2000 秒,则该key将立即过期,而不是持续1000 秒。

#Redis 如何使key过期
Redis key以两种方式过期:被动方式和主动方式。
仅当某些客户端尝试访问key时,key就会被动过期,并且发现key已超时。
当然这还不够,因为有过期的key将永远不会被再次访问。这些key无论如何都应该过期,
因此 Redis 会定期在设置过期的key中随机测试几个key。所有已经过期的键都会从键空间中删除。

具体来说,这是 Redis 每秒执行 10 次的操作:
从具有关联过期时间的key集中测试 20 个随机key。
删除所有发现过期的key。
如果超过 25% 的key过期,请从步骤 1 重新开始。
这是一个简单的概率算法,基本上假设我们的样本代表了整个key空间,并且我们继续过期直到可能过期的key百分比低于 25%

这意味着在任何给定时刻,使用内存的已过期key的最大数量等于每秒最大写入操作量除以 4。

#复制链接和 AOF 文件中如何处理过期
为了在不牺牲一致性的情况下获得正确的行为,当key过期时, DEL 会在 AOF 文件中合成一个操作并获得所有附加的副本节点。
这样过期过程集中在主实例中,不会出现一致性错误。

然而,虽然连接到主节点的副本不会独立地使key过期(但会等待 DEL 来自主节点的消息),但它们仍将采用数据集中存在的过期的完整状态,
因此当一个副本被选为主它时将能够独立地使key过期,完全充当主人。

#历史
从 Redis 版本 7.0.0 开始:添加了选项:NX,XX 和 GT,LT

<think>首先,用户的问题是:“我想设置Redis的过期时间的方法 请问Redis 设置过期时间的方法”。这翻译成英文是:“I want to know the method to set the expiration time for Redis keys. Please tell me the method to set the expiration time for Redis keys.” 根据系统级指令,我需要遵循以下规则: 1. 所有行内数学表达式使用$...$格式。 2. 独立公式使用$$...$$格式并单独成段。 3. LaTeX语法正确。 4. 使用中文回答。 5. 生成相关问题。 6. 回答中引用的段落末尾自然地添加引用标识,例如[^1]。 用户可见层指令: - 回答结构清晰,帮助用户逐步解决问题。 - 尽量保证回答真实可靠。 - 参考站内引用:引用[1]到[5]提供了关于Redis设置过期时间的相关信息。 参考引用内容: - 引用[1]:介绍了Redis设置生存时间或过期时间的四个命令EXPIRE, PEXPIRE, EXPIREAT, PEXPIREAT。 - 引用[2]:提到了Redis的lazy expiration策略。 - 引用[3]:详细说明了设置过期时间的注意事项,如不存在时的返回值、负值过期时间的效果、PERSIST命令的使用、以及字符串类型使用SET命令会清除过期时间。 - 引用[4]:展示了在Spring Data Redis中使用RedisTemplate设置过期时间的方法。 - 引用[5]:给出了Redis命令行中设置过期时间的例子。 用户的问题是关于设置Redis过期时间的方法,所以我需要基于这些引用提供清晰的回答。 回答结构: 1. **介绍Redis设置过期时间的基本方法**:使用命令EXPIRE、PEXPIRE等。 2. **详细解释每个命令**:基于引用内容。 3. **注意事项**:如引用[3]中提到的陷阱。 4. **编程示例**:如果适用,展示如何在代码中实现,如使用RedisTemplate。 5. **总结**:简要概述关点。 6. **生成相关问题**:在末尾添加相关问题。 由于用户的问题是用中文问的,我必须用中文回答。 生成相关问题:指令要求生成相关问题,我需要基于主题创建2-3个问题。 最终回答格式: - 使用清晰的结构,如标题、步骤列表。 - 自然地添加引用标识,例如在解释某个点时引用相关部分。 大纲: 1. **开头**:直接回答问题,解释Redis设置过期时间的重要性。 2. **方法**:列出并描述设置过期时间命令。 - EXPIRE设置秒级生存时间。 - PEXPIRE设置毫秒级生存时间。 - EXPIREAT:设置秒级时间戳过期时间。 - PEXPIREAT:设置毫秒级时间戳过期时间。 3. **注意事项**:基于引用[3],讨论常见问题。 4. **编程示例**:展示在Spring Boot中使用RedisTemplate的代码示例。 5. **总结**:重申关点。 6. **相关问题**:生成2-3个相关问题。 生成相关问题示例: 1. Redis如何删除过期? 2. 设置过期时间时有哪些常见错误需要避免? 3. 如何在Redis中检查的剩余生存时间?</think>### Redis 设置过期时间的方法 在 Redis 中,设置(key)的过期时间是一种常见操作,用于自动删除以节省内存资源。Redis 提供了多种命令设置生存时间(TTL)或过期时间戳,支持秒级和毫秒级精度。以下我将逐步解释具体方法、注意事项和编程实现,确保回答真实可靠,基于 Redis 官方文档和常见实践[^1][^3][^5]。 #### 1. **基本命令设置过期时间** Redis 有四个核心命令用于设置的过期时间。这些命令可以直接在 Redis 命令行或客户端中使用: - **EXPIRE key seconds**:设置生存时间为指定秒数。例如,设置 `name` 在 10 秒后过期: ``` 127.0.0.1:6379> SET name "redis" OK 127.0.0.1:6379> EXPIRE name 10 (integer) 1 # 返回 1 表示成功 ``` - **PEXPIRE key milliseconds**:设置生存时间为指定毫秒数。例如,设置 `age` 在 10000 毫秒(10 秒)后过期: ``` 127.0.0.1:6379> SET age 30 OK 127.0.0.1:6379> PEXPIRE age 10000 (integer) 1 ``` - **EXPIREAT key timestamp**:设置的过期时间为 Unix 时间戳(秒级)。例如,设置 `session` 在 2025 年 1 月 1 日 00:00:00 过期: ``` 127.0.0.1:6379> SET session "data" OK 127.0.0.1:6379> EXPIREAT session 1735660800 # 时间戳值 (integer) 1 ``` - **PEXPIREAT key timestamp**:设置的过期时间为 Unix 时间戳(毫秒级)。例如,设置 `token` 在毫秒级时间戳过期: ``` 127.0.0.1:6379> SET token "abc123" OK 127.0.0.1:6379> PEXPIREAT token 1735660800000 (integer) 1 ``` 这些命令的返回值:`1` 表示成功设置,`0` 表示不存在或设置失败[^1][^3][^5]。 #### 2. **注意事项和常见问题** 在设置过期时间时,需注意以下陷阱,避免数据意外丢失: - **不存在时返回 0**:如果尝试对不存在的设置过期时间Redis 会返回 `0`,不会创建新。 ``` 127.0.0.1:6379> EXPIRE not_exist_key 30 (integer) 0 ``` - **负值过期时间会立即删除**:如果设置负数秒数或毫秒数,会被立刻删除,相当于 `DEL` 命令。 ``` 127.0.0.1:6379> SET hello "world" OK 127.0.0.1:6379> EXPIRE hello -2 (integer) 1 127.0.0.1:6379> GET hello (nil) # 已被删除 ``` - **字符串类型的特殊行为**:对字符串使用 `SET` 命令会清除其过期时间。例如,先设置过期时间,再 `SET` 新值,过期时间失效: ``` 127.0.0.1:6379> EXPIRE hello 50 (integer) 1 127.0.0.1:6379> TTL hello # 检查剩余时间 (integer) 46 127.0.0.1:6379> SET hello "new_value" OK 127.0.0.1:6379> TTL hello (integer) -1 # 过期时间被清除,永久存在 ``` - **清除过期时间**:使用 `PERSIST` 命令可以移除的过期时间,使其永久有效。 ``` 127.0.0.1:6379> EXPIRE key 50 (integer) 1 127.0.0.1:6379> PERSIST key (integer) 1 127.0.0.1:6379> TTL key (integer) -1 ``` Redis 采用 lazy expiration 策略:过期不会立即删除,而是在访问时检查并清理[^2][^3]。 #### 3. **在编程中设置过期时间(以 Spring Boot 为例)** 如果您使用 Java 和 Spring Data Redis,可以通过 `RedisTemplate` 方便地设置过期时间。以下是一个完整示例: ```java import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import java.util.concurrent.TimeUnit; import javax.annotation.Resource; @Service public class RedisService { @Resource private RedisTemplate<String, Object> redisTemplate; // 设置值对并指定过期时间(秒) public void setWithExpire(String key, Object value, long timeoutSeconds) { redisTemplate.opsForValue().set(key, value, timeoutSeconds, TimeUnit.SECONDS); } // 为现有设置过期时间 public void setExpire(String key, long timeout, TimeUnit unit) { redisTemplate.expire(key, timeout, unit); } // 获取的剩余生存时间(秒) public Long getRemainingTime(String key) { return redisTemplate.getExpire(key, TimeUnit.SECONDS); } } ``` - 说明:`setWithExpire` 方法在设置值的同时指定过期时间;`setExpire` 可为已存在的添加过期时间;`getRemainingTime` 返回剩余秒数(-1 表示永久,-2 表示不存在)[^4]。 #### 4. **总结** - **核心方法**:使用 `EXPIRE`、`PEXPIRE`、`EXPIREAT` 或 `PEXPIREAT` 命令设置过期时间,支持秒级或毫秒级精度。 - **最佳实践**:始终检查命令返回值(1 成功,0 失败);避免对字符串重复使用 `SET`,以免清除过期时间;定期用 `TTL` 或 `PTTL` 命令监控剩余时间。 - **内部机制**:Redis 最终统一使用 `PEXPIREAT` 处理所有过期设置,并依赖 lazy expiration 在访问时清理[^1][^3]。 如果您需要更深入的性能调优或具体场景示例,请参考 Redis 官方文档或相关教程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值