1.因为内存是有限的,如果缓存中的所有数据都是一直保存的话,分分钟直接Out of memory。
2.有些场景需要设置过期时间:比如短信验证。
如果使用传统的数据库来处理的话,一般都是自己判断过期,这样更麻烦并且性能要差很多
Redis中除了字符串类型有自己独有设置过期时间的命令 setex
外,其他方法都需要依靠 expire
命令来设置过期时间 。另外, persist
命令可以移除一个键的过期时间
Redis 通过一个叫做过期字典(可以看作是hash表)来保存数据过期的时间
typedef struct redisDb {
...
dict *dict; //数据库键空间,保存着数据库中所有键值对
dict *expires // 过期字典,保存着键的过期时间
...
} redisDb;
举例:
有三个类型数据:List类型的alphabet ,Hash类型book,string类型message
alphabet对于值为string类型a,string类型b,string类型c
book对应值为string类型name,string类型author,string类型publicsher
message对应值为string类型的hello world
alphabet过期时间为long long类型1385877600000
redis提供了以下三种删除策略,可以根据实际业务场景选择合适的删除策略
定时删除,惰性删除,定期删除,内存淘汰机制
定时删除 对内存友好,对CPU不友好
对内存是最友好的:通过定时器,定时删除策略可以保证过期键会尽快被删除,并释放过期键所占用的内存
对 CPU 时间不友好:在过期键比较多的情况下,删除过期键可能会占用相当一部分 CPU 时间
惰性删除 对内存不友好,对CPU友好
对 CPU 时间最友好:程序只会在取出键时才对键进行过期检查,这可以保证删除过期键的操作只会在非做不可的情况下进行,并且删除的目标仅限于当前处理的键,这个策略不会在删除其他无关的过期键上花费任何 CPU 时间
对内存是最不友好的:如果一个键已经过期,而这个键又仍然保留在数据库中,那么只要这个过期键不被删除,它所占用的内存就不会释放,这可以看作是一种内存泄漏
定期删除
定期删除策略是前两种策略的一种折中:
内存淘汰机制