本文例子基于:5.0.4redis
Redis对于设置了过时时间的key的过时策略有两种数据库
惰性删除的时机在于当你要获取该key的时候再去作判断.这里我以String类型做为演示画图: 服务器
int expireIfNeeded(redisDb *db, robj *key) {
if (!keyIsExpired(db,key)) return 0;
/* If we are running in the context of a slave, instead of * evicting the expired key from the database, we return ASAP: * the slave key expiration is controlled by the master that will * send us synthesized DEL operations for expired keys. * * Still we try to return the right information to the caller, * that is, 0 if we think the key should be still valid, 1 if * we think the key is expired at this time. */
if (server.masterhost != NULL) return 1;
/* Delete the key */
server.stat_expiredkeys++;
propagateExpire(db,key,server.lazyfree_lazy_expire);
notifyKeyspaceEvent(NOTIFY_EXPIRED,
"expired",key,db->id);
return server.lazyfree_lazy_expire ? dbAsyncDelete(db,key) :
dbSyncDelete(db,key);
}
复制代码
咱们发现,当key有设置了过时时间,而后key已通过期的话,那么redis会判断是否开启了lazyfree_lazy_expire
,若是开启的话,那么异步删除.没有则同步直接删除.(4.0以后的特性,当大key删除的时候很是有用)dom
当有了惰性删除以后,知足了一部分的需求,但是在实际应用中,会存在有过时而没有被访问到的key,这样就会平白的占据着内存.那么redis是经过怎样去解决的呢?异步
redis会有一个定时任务,每秒跑10次。性能
因为redis是单线程,若是任由上面定时随机删除策略的话,那么当有大量的key过时的时候,redis会存在没法处理客户端请求的状况?不不不,其实redis在作定时随机删除的时候,有一个限制,就是设置扫描时间的上限,默认至多为25ms(timelimit = 1000000*ACTIVE_EXPIRE_CYCLE_SLOW_TIME_PERC/server.hz/100;),因此当客户端请求到来时,服务器正处于过时扫描期间,客户端会等到至多25ms而后进行其业务处理.this
那么若是redis设置超时时间太短的话,有可能出现大量超时链接,为了不这个问题,建议是在设置过时时间是时候,加多一个随机范围,避免大量的key同时过时~spa
当有作主从的时候,从库是不会开启定时随机删除的,都是依赖master开启的aof文件中增长一条del命令,而后从库去执行该语句实现删除该过时key线程
咱们知道redis是纯内存数据库,若是redis使用超出了内存限制的时候,便会产生swap行为. 使用磁盘来操做相比内存来讲,性能降低的不是一丁半点。 这时候咱们须要设置redis最大使用内存code
maxmemory <bytes>
复制代码
经过设置maxmemory,当使用内存超过maxmemory的时候,redis提供了几种可选的策略来控制内存的使用量
端午三天就这样过去啦~愿各位看官好好休息,而后继续起来搬砖~hhhhh