最近javaeye上memcached相当火,不少人把它当作sna架构的中心session服务器来用。由于memcached是作为一个cache服务器而设计的,而session的存放有自己特点,其中一个就是session的失效时间。通常session的失效算法是“当前时间>=session最后访问时间+失效时间”,那么memcache的缓存失效是怎么实现的呢?我们看看代码:
1、失效时间的计算:
[code]
rel_time_t realtime(time_t exptime) {
/* no. of seconds in 30 days - largest possible delta exptime */
if (exptime == 0) return 0; /* 0 means never expire */
if (exptime > REALTIME_MAXDELTA)
return (rel_time_t) (exptime - stats.started);
else {
return (rel_time_t) (exptime+ current_time);
}
}
[/code]
代码很简单,假如失效时间是120妙,那么计算后的失效时间就是120+current_time(当前时间和server启动时间差)
2、失效算法:
[code]
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;
}
[b]if (it != NULL && it->exptime != 0 && it->exptime <= current_time) {
do_item_unlink(it); // MTSAFE - cache_lock held
it = 0;
}[/b]
if (it != NULL) {
it->refcount++;
DEBUG_REFCNT(it, '+');
}
return it;
}[/code]
失效算法是通过比较it->exptime <= current_time来实现的,而it->exptime值,只有在cache值update的时候(set/add/replace)才回更新,仅仅get操作是不会更新这个时间的!
所以如果想让memcached正确的处理session的失效,必须在每次访问的时候,[quote]执行一次add操作(add操作当cache已存在时,仅仅更新exptime时间)[/quote]
[b]更正:昨天晚上又看了下代码,发现add操作如果cache已存在,并不更新exptime,仅仅刷新最后访问时间,所以应该使用set或replace操作。[/b]
1、失效时间的计算:
[code]
rel_time_t realtime(time_t exptime) {
/* no. of seconds in 30 days - largest possible delta exptime */
if (exptime == 0) return 0; /* 0 means never expire */
if (exptime > REALTIME_MAXDELTA)
return (rel_time_t) (exptime - stats.started);
else {
return (rel_time_t) (exptime+ current_time);
}
}
[/code]
代码很简单,假如失效时间是120妙,那么计算后的失效时间就是120+current_time(当前时间和server启动时间差)
2、失效算法:
[code]
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;
}
[b]if (it != NULL && it->exptime != 0 && it->exptime <= current_time) {
do_item_unlink(it); // MTSAFE - cache_lock held
it = 0;
}[/b]
if (it != NULL) {
it->refcount++;
DEBUG_REFCNT(it, '+');
}
return it;
}[/code]
失效算法是通过比较it->exptime <= current_time来实现的,而it->exptime值,只有在cache值update的时候(set/add/replace)才回更新,仅仅get操作是不会更新这个时间的!
所以如果想让memcached正确的处理session的失效,必须在每次访问的时候,[quote]执行一次add操作(add操作当cache已存在时,仅仅更新exptime时间)[/quote]
[b]更正:昨天晚上又看了下代码,发现add操作如果cache已存在,并不更新exptime,仅仅刷新最后访问时间,所以应该使用set或replace操作。[/b]