memcached有效时间策略

memcached作为缓存服务器,其内存管理依赖于有效时间和回收对象策略。当当前时间大于对象更新时间加上失效时间时,对象被视为过期。有效时间包括设置方式和更新时间,而回收策略聚焦于何时回收对象。在清空缓存时,item_flush_expired()处理过期项。启用LRU算法可以回收失效缓存,但需谨慎设置内存大小以避免未过期对象被误删。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

memcached是作为一个cache服务器而设计的。内存失效判断是:当前时间>=对象更新时间+失效时间。
memcache的缓存有效对象实现包括:

(1)有效时间计算

(2)回收对象策略

1、有效时间

(1)有效时间方式

有效时间有两种方式
1)相对时间:多长时间,给出过期的时间长度
2)绝对时间:到期时间,给出过期的最后期限
 
时间处理(服务端memcached.c)
#define REALTIME_MAXDELTA 60*60*24*30                     			// 定义30天的秒数
//对象剩下生命时间(单位秒)
static rel_time_t realtime(const time_t exptime) {
       if (exptime == 0) return 0;
       if (exptime > REALTIME_MAXDELTA) {                       // 超过30天,使用绝对时间
              if (exptime <= process_started)                         // 小于进程启动日期
              	return (rel_time_t)1;                                 //过期
              return (rel_time_t)(exptime - process_started);   // 返回进程启动之后的时间差
       } else {                                                                   // 不超过30天,是相对时间
              return (rel_time_t)(exptime + current_time);       // exptime + (tvsec - process_started)
       }
}

相对时间时,返回的值是:服务器当前时间之后的exptime - process_started秒
绝对时间时,返回的值是:服务器当前时间之后的(exptime -服务器当前时间) - process_started秒
 
可以看到,如果Client和Server时间不一致,使用绝对时间很容易导致缓存过期。
所以使用相对时间是比较安全的做法。

(2)更新对象有效时间

对象有效时间(exptime),只有在cache值更新的时候(set/replace操作)才会更新,get操作不会更新这个时间。 
add操作如果cache已存在,并不更新exptime,仅仅刷新最后访问时间,所以应该使用set或replace操作。

2、回收对象策略

(1)回收对象时机

1)对于失效的cache,在get操作的时候,才真正回收(可供新的cache使用).

代码如下:

item *do_item_get_notedeleted(const char *key, const size_t nkey, bool *delete_locked) {  
    item *it = assoc_find(key, nkey);  
    if (delete_locked) *delete_locked = false;  
    if (it && (it->it_flags & ITEM_DELETED)) {  
        /* it's flagged as delete-locked.  let's see if that condition 
           is past due, and the 5-second delete_timer just hasn't 
           gotten to it yet... */  
        if (!item_delete_lock_over(it)) {  
            if (delete_locked) *delete_locked = true;  
            it = 0;  
        }  
    }  
    if (it != NULL && settings.oldest_live != 0 && settings.oldest_live <= current_time &&  
        it->time <= settings.oldest_live) {  
        do_item_unlink(it);           // MTSAFE - cache_lock held  超过设置的最大时间也减少其引用计数
        it = 0;  
    }  
    if (it != NULL && it->exptime != 0 && it->exptime <= current_time) {  
        do_item_unlink(it);           // MTSAFE - cache_lock held  过期对象减少引用计数
        it = 0;  
    }  
  
    if (it != NULL) {  
        it->refcount++;  
        DEBUG_REFCNT(it, '+');  
    }  
    return it;  
}  

2)方法flush_all:

清空memcached所有缓存时,会执行item_flush_expired()来处理过期失效的cache。 
3)开启LRU算法:

通过-M选项会关闭了LRU算法,如果启用LRU算法,那么在给item分配内存的时候,LRU算法会正确回收失效的缓存。
启用LRU算法时,一定要注意设置足够大的内存,否则未失效的对象也可能被踢出。所以-M选项一定要慎用! 









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值