单机数据库
数据库
所有数据库都保存在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伪代码进行详细说明,这里就不再赘述。