前言
Redis是内存数据库,缓存中数据可以设置过期时间的属性。那如何过期的数据会如何清理,下面就来学习下。
数据删除策略
关于数据清理,一般情况分为主动删除和被动删除,主动删除常见的策略是定时删除和定期删除,被动删除常见的策略是惰性删除。
- 定时删除:在设置数据过期时间时,会创建一个定时器,让定时器在数据过期时间来临时,立即执行对键的删除。
定时删除的优势是对内存能更快释放存储空间,但是对于CPU不够友好,尤其是当过期数据较多了,更占用大量CPU资源去进行清理工作。
- 定期删除:每隔一段时间,程序就会对数据库进行一次检查,删除里边的过期数据,对于删除多少数据,以及删除几个库的数据都由算法决定;
定期删除策略是每隔一段时间来执行删除动作,是通过限制执行的时长和频率来减少删除操作对CPU时间的影响。合理定期删除能有效降低过期数据对于存储空间的浪费。但是关于难点就是选定执行时间和周期。
- 惰性删除:暂时不管数据的过期时间,当获取数据时,再进行检查数据是否过期,如果已经过期就删除,未过期,返回数据。
由于惰性删除只会在获取数据时进行检查数据过期,进而判断是否需求删除,所以惰性删除相对于前两种删除策略是最对CPU最友好的。不过惰性删除的劣势也很明显,当过期数据不被获取,进不会进行删除,就会一直存在数据库中,占用内存,浪费空间。
Redis的数据删除策略
Redis了为了合理使用CPU时间和避免浪费内存空间之前取得平衡,选取了定期删除和惰性删除两种过期数据删除策略。下面来看下具体的实现细节:
惰性删除策略实现:
Redis过期键的惰性删除策略由db.c/expireIfNeeded函数实现,所有的读写操作的命令在执行之前都是调用该函数对输入键进行检查。
当键以过期时,进行删除;当未过期时,不处理。当然进行获取操作时,如果GET,还会首先判断key是否存在,存在时,才会判断key是否过期。流程图如下:
定期删除策略实现:
Redis过期键的定期删除策略由redis.c/activeExpireCycle实现。Resdis采用了简单的概率算法,当函数每次运行时,都从一定数量的数据库中取出一定数量的随机键进行检查,并删除其中的过期键。每执行完一次会判断删除数据占比是否超过25%,如果超过25%说明内存还存在大量的过期的键,会继续执行,最终时间限定在250ms。
执行流程:
参考:《Redis设计与实现》