面试题答案
一键面试常见设置键过期时间的方法
- SETEX命令:
SET key seconds value
,在设置键值对的同时设置过期时间(以秒为单位)。例如:SETEX mykey 60 "Hello"
,表示设置键mykey
的值为Hello
,并在60秒后过期。 - SETPX命令:
SETPX key milliseconds value
,在设置键值对的同时设置过期时间(以毫秒为单位)。例如:SETPX mykey 10000 "World"
,表示设置键mykey
的值为World
,并在10000毫秒(10秒)后过期。 - EXPIRE命令:
EXPIRE key seconds
,为已存在的键设置过期时间(以秒为单位)。例如:先SET mykey "Value"
,再EXPIRE mykey 30
,表示为键mykey
设置30秒后过期。 - PEXPIRE命令:
PEXPIRE key milliseconds
,为已存在的键设置过期时间(以毫秒为单位)。例如:PEXPIRE mykey 5000
,表示为键mykey
设置5000毫秒(5秒)后过期。 - EXPIREAT命令:
EXPIREAT key timestamp
,设置键在指定的UNIX时间戳(以秒为单位)过期。例如:EXPIREAT mykey 1679779200
,表示键mykey
在对应的时间戳1679779200(假设此时间戳对应未来某时刻)过期。 - PEXPIREAT命令:
PEXPIREAT key milliseconds-timestamp
,设置键在指定的UNIX时间戳(以毫秒为单位)过期。例如:PEXPIREAT mykey 1679779200000
,表示键mykey
在对应的毫秒时间戳1679779200000(假设此时间戳对应未来某时刻)过期。
设置过期时间可能遇到的问题及避免方法
- 过期时间设置不合理
- 问题:如果设置的过期时间过短,可能导致频繁地重新生成数据,增加系统开销;如果设置过长,可能会占用过多内存资源,尤其是对那些不需要长期保存的数据。
- 避免方法:对业务数据进行详细分析,结合实际使用场景和数据更新频率,合理评估过期时间。例如对于一些实时性要求不高的缓存数据,可以设置相对较长的过期时间;而对于一些动态变化频繁的数据,设置较短的过期时间。
- 缓存雪崩
- 问题:大量缓存键在同一时间过期,导致大量请求直接访问后端数据库,可能压垮数据库。
- 避免方法:
- 分散过期时间:在设置过期时间时,加入一个随机的时间偏移量,使得过期时间分散在一个时间段内,而不是集中在同一时刻。例如,原本设置过期时间为60秒,可以设置为55 - 65秒之间的随机值。
- 使用互斥锁:在缓存失效时,通过互斥锁(如Redis的SETNX命令)保证只有一个请求去重建缓存,其他请求等待,从而避免大量请求同时访问后端数据库。
- 缓存穿透
- 问题:查询一个不存在的数据,由于缓存不命中,每次都会查询数据库,若有大量这种请求,会导致数据库压力增大。
- 避免方法:
- 布隆过滤器:在查询之前,先通过布隆过滤器判断数据是否存在。布隆过滤器可以快速判断一个元素是否在集合中,虽然存在一定误判率,但可以大幅减少对不存在数据的数据库查询。
- 缓存空值:当查询数据库发现数据不存在时,也将空值缓存起来,并设置较短的过期时间,这样下次查询相同不存在的数据时,直接从缓存获取空值,避免再次查询数据库。
- 持久化影响
- 问题:在使用RDB持久化时,可能在过期键还未过期时就进行了快照,这样恢复数据后,过期键可能会依然存在;AOF持久化中,如果重写AOF文件时,过期键还未过期,重写后该键也会依然存在。
- 避免方法:
- RDB:合理设置RDB快照的时间间隔,尽量在过期键过期后再进行快照。或者在恢复数据后,手动检查并删除过期键。
- AOF:在AOF重写时,确保只将未过期的键写入新的AOF文件。Redis在AOF重写时会自动处理这个问题,只要使用较新版本的Redis,一般无需额外处理。