单机数据库

数据库

所有数据库都保存在redis.h/redisServer结构的db数组中

struct redisServer{
    redisDb *Db;//所有数据库

    int dbnum;//初始化数据库数量
}

typedef struct redisClient{
    redisDb *Db;//指向当前正在使用的数据库
}

redis是键值对数据库,其中redisDb中的dict保存了所有的键值对。通常键保存名称,值可以有多种类型(list,hash,string等)

typedef struct redisDb{
    dict *dict;
}

对dict的键操作通常也是CRUD,同时可以为键设置生存时间(EXPIRE和PEXPIRE命令),下面重点来说下过期键的问题。

过期键

redisDb中expires字段保存了过期时间,是一个longlong类型,PERSIST命令可以移除键过期时间。

过期删除策略

  • 定时删除:设置定时器到期删除
  • 惰性删除:获取时进行判断,如果过期就删除
  • 定期删除:定期检查删除

定时删除是对内存最友好的方法,他的缺点是对CPU时间是不友好的,在过期键比较多的情况下,删除行为会占用相当长的时间,进而对服务器响应造成影响。同时创建定时器需要使用无序链表,对时间处理是O(N)的复杂度,现阶段创建大量计时器删除的策略并不现实。

惰性删除对CPU时间是有好的,但是缺点是对内存不友好。过期键即使过期也会占用内存,这可以理解为一种内存泄漏,服务器不会主动去释放他们,如某些log在某些时间之后再也不会去访问,但这类数据仍然积压在数据库中。

定期删除是一种折中的方案,每隔一段时间执行一次删除过期键操作。问题是如何根据实际业务合理的设置操作频率和时长。

删除策略的具体实现书中作者用python伪代码进行详细说明,这里就不再赘述。