0. 前言
Redis的过期时间可以用于以下场景:
-
缓存数据:将经常访问的数据存储在Redis中,通过设置适当的过期时间,可以保证缓存数据的新鲜度。当数据过期时,Redis会自动删除,下次访问时会重新从源数据获取并存储到Redis中。
-
会话管理:将用户的登录信息或会话状态存储在Redis中,并设置过期时间。这样可以实现无状态的会话管理,减轻了服务器的压力。当用户长时间不活动或超过指定时间范围时,会话会自动过期删除。
-
分布式锁:通过Redis的SETNX命令可以实现分布式锁的功能。将锁的名称作为Key存储在Redis中,并设置过期时间。如果其他进程想要获取锁时,会先检查该锁是否已经被其他进程占用,如果没有被占用,则获取到锁;如果锁已经被占用并且已过期,则其他进程可以重新获取锁。这样可以实现在分布式环境中的资源互斥访问。
-
数据过期策略:对于一些临时数据或周期性的数据,设置合适的过期时间可以实现自动清理和释放内存的目的。如消息队列中的未消费消息或某些日志数据可以设置过期时间,以避免数据过多而导致内存占用过大。
-
计数器和限流:通过Redis的自增命令,可以实现计数器功能。将计数值存储在Redis中,并设置过期时间。可以根据业务需要,更新计数值或限制访问频率。
1. 了解redis过期策略
1.1 定时过期策略
定时过期策略(Timer Expired Policy)是Redis中一种常用的过期策略。
当设置一个Key的过期时间后,Redis会通过一个定时器来定期检查Key是否已过期,并根据过期情况进行删除。
具体过程如下:
-
设置Key的过期时间:通过Redis的EXPIRE key seconds命令或者EXPIREAT key timestamp命令可以设置一个Key的过期时间。可以通过TTL key命令查看Key的剩余过期时间。如果Key的过期时间设为0表示立即删除Key。
-
定时器检查过期Key:Redis会启动一个定时器,定期检查所有设置了过期时间的Key是否已过期。Redis使用时间轮算法来管理这些设置了过期时间的Key,在每个时间点上对应一个槽位,Redis的定时器每个时间点都会检查当前时间点对应的槽位上是否有过期的Key,如果有则进行删除。
-
删除过期Key:当一个Key过期时,Redis会将其从数据库中删除,并且释放被该Key占用的内存空间。Key被删除后,再次访问该Key会返回空值。
定时过期策略的优点是可以及时删除过期的Key,避免占用过多的内存空间;但缺点是消耗较多的CPU资源,因为Redis需要花费一定的时间定期检查过期的Key。
1.2 惰性过期策略
惰性过期策略(Lazy Expired Policy)是Redis中另一种过期策略,与定时过期策略相对应。
该策略是在访问Key时进行过期检查和删除,而不是通过定期检查。这种方式可以减少对CPU资源的消耗,但也可能导致一些过期的Key长时间存在于数据库中。
惰性过期策略的工作过程如下:
-
设置Key的过期时间:通过Redis的EXPIRE key seconds命令或者EXPIREAT key timestamp命令可以设置一个Key的过期时间。可以通过TTL key命令查看Key的剩余过期时间。
-
访问Key时进行过期检查:当使用命令来访问某个Key时,Redis会先进行过期检查。如果Key已过期,则会立即将该Key删除,并返回空值。如果Key未过期,则继续执行对该Key的操作。
-
删除过期Key:如果在访问Key时发现它已过期,Redis会将其从数据库中删除,并释放被该Key占用的内存空间。如果未过期,则不会进行任何删除操作。
惰性过期策略的优点是减少了对CPU资源的消耗,因为不需要定期检查所有设置了过期时间的Key。然而,这也意味着过期的Key 只有在被访问时才会被删除,如果这些Key很少被访问,可能会长时间存在于数据库中。
2. 设置过期时间
使用以下命令来添加过期时间,它的意思是为 key 键设置 100s 的过期时间:
expire key 100
3. 查看key的有效期
使用以下命令查询 key 的剩余有效时间:
ttl key
返回值:
-2 已过期或者不存在
-1 永久有效
其余数字 剩余有效时间(秒)
已经过期的key会直接从数据库中删除,没有任何为它添加有效时长的办法,所以要是想增加key的有效时长,必须赶在它过期之前,为它添加有效时长。
4. 添加key有效时长
使用EXPIRE命令设置键的有效时长(单位为秒):
EXPIRE key_name seconds
例如,为名为mykey的键设置有效时长为60秒:
EXPIRE mykey 60
使用PEXPIRE命令设置键的有效时长(单位为毫秒):
PEXPIRE key_name milliseconds
例如,为名为mykey的键设置有效时长为5000毫秒:
PEXPIRE mykey 5000
这样设置后,Redis将在指定的时长后自动删除键及其相关值。在键被删除之后,通过GET或其他读取键的命令将无法获取到该键的值。
另外,还可以使用EXPIREAT或PEXPIREAT命令设置键的过期的具体时间点,而不是相对时长。这些命令的用法与上述命令类似,只是需要指定过期的具体时间点。
5. 设置过期的具体时间点
以下是基本的命令示例:
使用EXPIREAT命令设置键的过期时间点(单位为秒):
EXPIREAT key_name timestamp
timestamp是一个Unix时间戳,表示键的过期时间点。例如,为名为mykey的键设置过期时间点为2022年1月1日下午12:00:00:
EXPIREAT mykey 1641025200
使用PEXPIREAT命令设置键的过期时间点(单位为毫秒):
PEXPIREAT key_name timestamp
timestamp是一个表示键的过期时间点的Unix时间戳(以毫秒为单位)。例如,为名为mykey的键设置过期时间点为2022年1月1日下午12:00:00:
PEXPIREAT mykey 1641025200000
这样设置后,Redis将在指定的时间点自动删除键及其相关值。在过期时间点之后,通过GET或其他读取键的命令将无法获取到该键的值。
注意,Unix时间戳是指自1970年1月1日以来经过的秒或毫秒数,具体取决于使用的命令和时间戳单位。可以使用相应的函数或工具将日期和时间转换为Unix时间戳。