Redis 在处理过期键的回收时,为了保证不对正在运行的Redis程序的效率产生严重影响,实现了三种回收策略。Redis并不追求立即回收过期的键。
自动回收
- 主要实现在 expire.c 文件中的 activeExpireCycle 函数中。而且默认启用 ACTIVE_EXPIRE_CYCLE_SLOW模式,ACTIVE_EXPIRE_CYCLE_FAST模式会减少执行时间,增加执行次数。
- effort 影响自动回收的强度,越高,消耗资源越大。
- 开始遍历数据库,选取一定数量的要删除的过期键,下面是最大值,取决于数据库中过期键的数量。
config_keys_per_loop = ACTIVE_EXPIRE_CYCLE_KEYS_PER_LOOP(20) +
ACTIVE_EXPIRE_CYCLE_KEYS_PER_LOOP(20)/4*effort(0-9)
- 如果样本数量不为零并且本次移除的过期键的比例小于等于可接收的百分比,或数据库已经扫描完,停止。
repeat = db_done ? 0 : (data.sampled == 0 || (data.expired * 100 / data.sampled) > config_cycle_acceptable_stale);
- 如果超时,直接退出遍历数据库。
/* Update our estimate of keys existing but yet to be expired.
* Running average with this sample accounting for 5%.
* 更新服务中已过期键的比例。
* */
double current_perc;
if (total_sampled) {
current_perc = (double)total_expired/total_sampled;
} else
current_perc = 0;
server.stat_expired_stale_perc = (current_perc*0.05)+
(server.stat_expired_stale_perc*0.95);
思考
- 如何处理过期字段的删除呢?
/* Interleaving hash-field expiration with key expiration. Better
* call it before handling expired keys because HFE DS is optimized for
* active expiration */
activeExpireHashFieldCycle(type);
还没找到具体处理逻辑。
- 在可以写数据的从节点,如何处理键值的过期?( Expires of keys created in writable slaves)
一般来说在主从结构中从节点为只读模式,但Redis的作者描述了一种场景。
* Note that the use case we are trying to cover here, is a popular one where
* slaves are put in writable mode in order to compute slow operations in
* the slave side that are mostly useful to actually read data in a more
* processed way. Think at sets intersections in a tmp key, with an expire so
* that it is also used as a cache to avoid intersecting every time.
就是在我们可以把计算的结果作为缓存存起来并设置过期时间,避免个Master带来巨大压力。
从节点用了一个64位位图的方式记录了key存在哪个db中,如何id超过63,就遍历所有的db。在删除过期键时,也是采用随机,一定量,时间限制,避免对主线程造成过大的影响。
- 为什么要算平均TTL,以及每隔16次迭代去判断是否超时?
主要是要对数据库中数据存活时间有一个判断便于进行操作。比如数据删除。
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现