redis系列(二):redis存储

服务器中的数据库

redisServer

redis是内存数据库。所以,一个redis数据库,就对应了一个结构体。

struct redisServer {

    // 一个数组,保存着服务器中的所有数据库
    redisDB *db;
    
    // 服务器中数据库的数量
    int dbnum;
}

客户端通过select [0-15] 来选择一个redis实例中的哪个数据库。

数据库默认的个数是16个。

数据库结构体.png

redisDB

下面来看看redisDB


typedef struct redisDB {

    // 数据库键空间,dict字典保存着数据库中的所有键值对
    dict *dict;
    
    // 过期字典,保存着所有键的过期时间
    dict *expires;
}

键空间和用户所看见的数据库是直接对应的。
dict的键,就是数据库的key。字符串对象。
dict的值,就是数据库的value,robj对象。

如果对数据执行如下命令


select.png

可以看到数据库从6号变成了8号。当前8号的数据库键空间字典就是这样的


键空间.png

对数据库的增删改查,都是对dict这个map的增删改查。

对数据里面的数据结构的增删改查,比如对book的增删改查,都是对book对应的map的增删改查。

键的过期时间

设置过期时间有4个命令:

  • expire 后面加 秒
  • pexpire 后面加 毫秒
  • expireat 后面加 秒级时间戳 表示直到这个时间点
  • pexpireat 后面加 毫秒级时间戳 表示直到这个时间点

该四个方法,最终都会转换成
pexpireat执行

过期时间.png

过期时间保存在过期字典里。

过期字典的key,就是数据库的key。
过期字段的value,就是毫秒精度的unix时间戳,表示过期时间。

redis通过当前时间 和 过期时间戳 的时间差,来判断是否过期。

现在知道了过期时间是怎么存的了,那过期的键怎么删除呢???

  • 定时删除
    到了过期时间就删除。在设置键的过期时间时,创建一个回调事件,当过期时间达到时,由时间处理器自动执行键的删除操作。
    好处:内存友好。
    缺点:对cpu不友好,会有大量的事件cpu资源用在了删除上。

  • 惰性删除
    在对key操作的时候,发现key是过期的,才删除。
    好处:对cpu友好。
    缺点:对内存不友好,会导致内存泄露,这个key没有再用到,就永远不会删除了。

  • 定期删除
    定时任务,定期删除。
    缺点:很难确定执行的时长和频率。

redis实际使用的是惰性删除和定期删除。通过配合使用这两种策略,服务器可以在cpu和内存之间取得一个很好的平衡。

具体怎么做的呢
比如redis-3.0.0中hz默认值是10,表示每秒钟调用10次后台清理任务。

典型的方式为,redis每秒做10次如下的步骤:

  • 随机测试100个设置了过期时间的key
  • 删除所有发现的已过期的key
  • 若删除的key超过25个则处重复步骤1

总结:redis会在hz的频率下(n次每秒),会在一定时间限制内尽可能多的删除过期key。

你可能感兴趣的:(redis系列(二):redis存储)