struct redisServer {
...
unsigned lruclock:22;
...
};
#define REDIS_LRU_CLOCK_MAX ((1<lru redis_lru_clock_resolution lru clock resolution in seconds typedef struct redisobject bits unsigned type:4 notused:2 not used encoding:4 lru:22 time to server.lruclock int refcount void robj redis cron servercron aeeventloop long id ...... we have just per object
for
information. so
use
an wrapping with resolution. is more
or
less years. note that even
if
this will wrap after years it a problem everything still work but some appear younger redis. happen given should never be touched you can change the altering define. updatelruclock redis_lru_clock_max>
<h3>TTL 数据淘汰机制</h3>
<p>redis 数据集数据结构中保存了键值对过期时间的表,即 redisDb.expires。和 LRU 数据淘汰机制类似,TTL 数据淘汰机制是这样的:从过期时间的表中随机挑选几个键值对,取出其中 ttl 最大的键值对淘汰。同样你会发现,<strong>redis 并不是保证取得所有过期时间的表中最快过期的键值对,而只是随机挑选的几个键值对中的。</strong></p>
<h3>总结</h3>
<p>redis 每服务客户端执行一个命令的时候,会检测使用的内存是否超额。如果超额,即进行数据淘汰。</p>
<pre
class
=
"brush:php;toolbar:false"
>
int processCommand(redisClient *c) {
......
if
(server.maxmemory) {
int retval = freeMemoryIfNeeded();
if
((c->cmd->flags & REDIS_CMD_DENYOOM) && retval == REDIS_ERR) {
flagTransaction(c);
addReply(c, shared.oomerr);
return
REDIS_OK;
}
}
......
}
int freeMemoryIfNeeded(void) {
size_t mem_used, mem_tofree, mem_freed;
int slaves = listLength(server.slaves);
mem_used = zmalloc_used_memory();
if
(slaves) {
listIter li;
listNode *ln;
listRewind(server.slaves,&li);
while
((ln = listNext(&li))) {
redisClient *slave = listNodeValue(ln);
unsigned long obuf_bytes = getClientOutputBufferMemoryUsage(slave);
if
(obuf_bytes > mem_used)
mem_used = 0;
else
mem_used -= obuf_bytes;
}
}
if
(server.aof_state != REDIS_AOF_OFF) {
mem_used -= sdslen(server.aof_buf);
mem_used -= aofRewriteBufferSize();
}
if
(mem_used expires. */
if
(server.maxmemory_policy == REDIS_MAXMEMORY_VOLATILE_LRU)
de = dictFind(db->dict, thiskey);
o = dictGetVal(de);
thisval = estimateObjectIdleTime(o);
if
(bestkey == NULL || thisval > bestval) {
bestkey = thiskey;
bestval = thisval;
}
}
}
else
if
(server.maxmemory_policy == REDIS_MAXMEMORY_VOLATILE_TTL) {
for
(k = 0; k id);
decrRefCount(keyobj);
keys_freed++;
if
(slaves) flushSlavesOutputBuffers();
}
}
if
(!keys_freed)
return
REDIS_ERR;
}
return
REDIS_OK;
}