/* 示例代码:Redis过期键删除策略和内存淘汰策略 */
#include "redis.h"
void activeExpireCycle(redisDb *db, unsigned int max_loops) {
// 迭代数据库,处理过期键
dictEntry *de;
int timelimit_exit = 0;
long long start_cycle, now;
unsigned int i, expired, num, visited;
start_cycle = mstime();
now = start_cycle;
expired = 0;
visited = 0;
if (max_loops <= 0) max_loops = 1000000;
for (i = 0; i < db->dict->size && max_loops--; i++) {
// 遍历数据库中的所有键
de = dictGetRandomKey(db->dict);
if (de == NULL) break; /* 如果已经遍历完所有键,则退出 */
// 检查键是否过期
if (activeExpireCycleTryExpire(db,de,now)) expired++;
if (i == 0 && mstime()-start_cycle > 1000) timelimit_exit = 1;
visited++;
}
/* 如果达到时间限制,则下次继续从此处开始 */
if (timelimit_exit) {
db->active_expire_cycle = dictGetKey(de);
return;
}
/* 如果没有可过期的键,则清除active_expire_cycle标志 */
if (!expired) db->active_expire_cycle = NULL;
/* 计算平均迭代次数 */
if (visited) server.stat_expired_stale_perc = (float)expired/visited;
}
/* 尝试过期键 */
int activeExpireCycleTryExpire(redisDb *db, dictEntry *de, long long now) {
int retval;
robj *key, *val;
// 获取键值对
key = dictGetKey(de);
val = dictGetVal(de);
// 检查键是否过期
retval = 0;
if (val->lru <= LRU_CLOCK()) {
retval = expireIfNeeded(db,key,val);
}
return retval;
}
/* 主动过期键 */
int expireIfNeeded(redisDb *db, robj *key, robj *val) {
mstime_t when = val->lru - LRU_CLOCK();
// 如果键已经过期,执行过期删除
if (when <= 0) {
propagateExpire(db,key,val);
return dbDelete(db,key);
}
return 0;
}
/* 传播过期 */
void propagateExpire(redisDb *db, robj *key, robj *val) {
// 发布过期事件
redisAssertWithInfo(NULL,key,db->id == 0 && val->type == REDIS_STRING);
redisExpire(NULL,db,key->ptr);
}
/* 内存淘汰策略 */
int activeExpireCycleTryAOFAndRefresh(redisDb *db, dictEntry *de, long long now, int *expired, int *freq) {
robj *key, *val;
// 获取键值对
key = dictGetKey(de);
val = dictGetVal(de);
// 尝试根据键值对执行AOF日志同步
if (val->type == REDIS_STRING && val->refcount == 1 &&
/* 假设条件 */
(now - val->lru) > 120 * REDIS_AUTOSAVE_INTERVAL)
{
// 执行AOF日志同步
sds aof_
评论已关闭