redis 代码解析(1)

1.衔接上文 

上文已经说过了各种redis数据的实现和使用,这时我们将从整体代码出发看redis使用

https://github.com/huangz1990/redis-3.0-annotated 这是redis设计与实现的作者整合的代码解析,可以看一波=^_^=.

2.数据库

保存在redis.h/redisServer结构中

struct redisService{
    redisDb *db;//数组实现 保存所有的数据库
    // 可以通过 下标访问到数据库,select index 选择使用一个数据库
    //就是改变redisClient.db指针,指向数据库
    
    int dbnum;//初始化时的数据库数目,默认是16 即dbnum=16;
    
}
数据库结构
struct redisDB{
    dict *dict;//数据库键空间,保存所有的键值对
}redisDb;

关系图如下图所示,展示了如何实现

image.png

将键对象与值对象关联起来,在对象中实现了基本数据结构的存储.

set:更新值,添加键就是在dict数组中加入键值对象;在dict中保存键对象;

del:在dict数组中删除键对象,

get:取值在键空间中查找message,然后接着取得对应的值对象

清除整个键值空间flushdb;

dbsize:返回键数量

相关操作之后的维护:当进行读写时,服务器还会执行一些额外的维护操作,

1)在读取一个键之后,(读写操作都会),服务器会根据键是否存在,更新键的命中次数和不命中次数 使用 info stats keyspace_hits看

2)读取一个键后,服务器更新LRU时间,这个值用于计算键的闲置时间

3)在读取一个键时发现这个键已经过期,服务器会删除这个键

4)使用watch监视了某个键,那么服务器在对被监视的键进行修改之后会被标记为脏,让事务注意到这个键

5)每次修改一个键,就会对脏键计数器增1,计数器会触发服务器的持久化及复制操作

6)如果服务器开启了数据库通知功能,那对键进行修改后,会发送通知

设置键的生存时间或过期时间:

expire pexpire 设置生存时间(TTL)(秒,毫秒),在生存时间到后服务器自动删除键

ttl pttl 对于一个带生存时间的键 将返回一个剩余生存周期

这些过期时间要保存:dict *expires字典保存了所有键的过期时间(过期字典),键是一个指针,指向一个键对象,值是long long的整数,保存了一个毫秒精度的unix时间戳.

persist jian 解除键和值(过期时间)在过期字典的关联(消除过期时间);

过期键删除策略:

1)定期删除:在设置键的过期时间的同时,创建一个定时器(timer),让定时器在键过期时间来临时,立即执行对键的删除操作.(对cpu时间是不友好的,要创建大量的定时器,时间事件的实现方式是,无序链表)

2)惰性删除,放任键过期不管,但每次从键空间获取键时,都检查取得的键是否过期,如果过期就删除,没过期就返回改键.(对内存不友好,一个键过期,等要访问的时候才会被删掉,可能导致内存泄漏)

3)定期删除:每隔一段时间,程序就对数据库进行一次检查,删除里面的过期键,(1,2是主动删除,3是被动删除),(难点就是确定操作执行的时长和频率)

redis的过期删除策略:使用惰性删除和定期删除两种策略

AOF RDB和复制功能对过期键的处理

RDB

image.png

当以主服务器模式运行时:载入RDB时正好相同,过期键被忽略,未过期的键会被载入到数据库中,

当以从从服务器模式运行:载入RDB文件所有的键都被载入,无论过期

AOF

image.png

读取AOF时和RDB相同

复制

在复制模式下:从服务器的过期键删除由主服务器控制:

当主服务器删除一个过期键时:显示发送一个DEL命令,让从从服务器删除

从服务器在执行客户端发送的命令,即使碰到过期键也不删除(由主控制)只有收到主的DEL;

数据库通知

<

p style=”line-height: normal; margin-bottom: 5px; margin-top: 5px; text-indent: 0em;”>在redis新增加了功能:




.


评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注