Redis处理过期的key
Redis会将每个设置了过期时间的key保存在一个独立的字典中,以后会定期扫描这个字典来删除过期了的key。除了定期扫描删除策略之外,Redis同时采用惰性删除策略,在客户端访问key的时候,Redis会对这个key做过期检查,如果key已过期,则删除这个key。
定期扫描策略
redis默认会每秒进行10次过期扫描,过期扫描的时候不会扫描过期字典中所有的key,而是采用一种贪心策略:
- 每次从过期字典中获取20个key。
- 将这20个key中过期的key删除
- 如果过期的key的比例超过25%,则重复1步骤
为了保证扫描不出现循环过度,导致线程卡死,一次扫描时间的上限为25ms。 如果Redis中所有的key在同一时间都过期了,Redis会持续扫描,从而造成顿卡现象,所以在设计缓存时间的时候,要给过期时间设计一个随机值,让过期的key不在同一时间都过期。
从库过期策略
从库不会进行过期扫描,主库在key过期的时候,会在AOF文件中写入一条del命令,从库是通过同步主库的时候执行该命令删除过期的key,由于同步操作是异步的,所以会存在主库删除了但是从库还存在这个key的现象。
内存淘汰策略
当Redis使用内存超过物理内存限制的时候,内存的数据就开始和磁盘进行交换,这个操作是很耗时的,会严重降低Redis的性能。在Redis中,通过maxmemory限制了最大内存的使用。如果超过设置的值,Redis提供了多种策略决定如何释放内存。
- noeviction:不会继续服务写请求(除了del命令外),可以继续读请求,这样线上的读操作还可以继续,但是遇到写的操作将不可以,Redis默认为该策略。
- volatile-lru:淘汰设置了过期时间的key,最少使用的key优先淘汰。
- volatile-ttl:淘汰设置了过期时间的key,key的ttl时间越小的优先淘汰。
- volatile-random:淘汰设置了过期时间的key,随机淘汰。
- allkeys-lru:淘汰所有的key,最少使用的key优先淘汰。
- allkeys-random:淘汰所有的key,随机淘汰。
惰性删除
删除指令del会直接释放对象的内存,但如果对象特别大,删除操作会导致线程顿卡。redis为解决该问题,在4.0版本中引入了unlink命令,他对删除操作进行懒删除,将释放内存的操作放入后台的异步线程处理。
Redis提供的flushdb和flushall指令可以清空数据库,这个操作很耗时,在4.0后,通过在指令后面增加async参数,异步处理清空操作。