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;
关系图如下图所示,展示了如何实现
将键对象与值对象关联起来,在对象中实现了基本数据结构的存储.
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
当以主服务器模式运行时:载入RDB时正好相同,过期键被忽略,未过期的键会被载入到数据库中,
当以从从服务器模式运行:载入RDB文件所有的键都被载入,无论过期
AOF
读取AOF时和RDB相同
复制
在复制模式下:从服务器的过期键删除由主服务器控制:
当主服务器删除一个过期键时:显示发送一个DEL命令,让从从服务器删除
从服务器在执行客户端发送的命令,即使碰到过期键也不删除(由主控制)只有收到主的DEL;
数据库通知
<
p style=”line-height: normal; margin-bottom: 5px; margin-top: 5px; text-indent: 0em;”>在redis新增加了功能:
.
发表回复