Redis数据库结构以及键空间的操作
Redis结构
Redis服务器将所有数据库都保存在服务器状态RedisServer结构的db数组中。
db数组中的每个元素都是一个redisDb结构,每个redisDb代表一个数据库。
typedef struct redisServer{
redisDb *db; //一个数组,保存了服务器中的所有数据库。
int dbnum; //服务器数量 默认是16
}
切换数据库
客户端想要切换数据库,可以使用select 数据库编号
切换。
例如:select 0
切换到0号数据库。
客户端状态下的redisClient结构中有个属性记录了客户端当前的数据库,这个属性是一个指向redisServer结构中redisDb数组的指针。通过改变这个指针的指向来达到切换数据库的效果。这就是select命令实现的原理。
友好提示:在执行删除键或者flush数据库的时候,记得先select选中数据库,因为有的客户端工具是不会显示当前数据库的编号的。
数据库键空间
typedef struct redisDb{
dict *dict;//键空间是保存当前数据库中所有键值对的字典
} redisDb;
键空间和用户所见的数据库是直接对应的。
键空间是键的一个字符串对象,值可以是字符串对象,列表,集合,有序集合,哈希对象。
键空间的操作
FLUSHDB
命令是清空dict键。RANDOMKEY
是随机返回键空间中一个键。DBSIZE
返回键空间中键值对的数量。
还有常见的增删改查等操作。
读写键空间的维护操作
- 在读取一个键之后,服务器会更新服务器键空间命中次数和不命中次数。这两个属性可以通过
info stats
命令查看,对应的两个字段是keyspace.hit属性和keyspace.misses属性查看。 - 更新键之后,服务器会更新键的LRU时间。这个LRU时间主要用来计算键的闲置时间。查看key的闲置时间
object idletime <key>
。 - 如果服务器发现有键过期会删除过期键。
- 如果客户端使用
watch
命令监视某个键,那么服务器在对这个被监视的键修改后,会将这个键标记为脏,告诉事务程序,这个键已经被修改过。 - 服务器每次修改键,都会将脏键计数器+1;
AOF和RDB复制功能对过期键的处理
RDB处理过期键
当主服务器启动时候,载入RDB文件的同时不会载入过期键;当以从服务器启动,文件中会保存所有键。
当生成RDB文件(执行save,bgsave命令),过期键不会被保存在RDB文件中。
AOF处理过期键
如果数据库中的某个键已经过期,但是还没被惰性删除或定期删除,那么AOF文件不会因为这个过期键而产生任何影响。
如果这个过期键已经被删除,程序会向AOF文件中追加一条DEL命令,显示记录该键已经被删除。
执行BGREWRITEAOF
: 程序会对数据库中的键进行检查,不会载入过期键。
主从复制下的过期键删除策略
当服务器运行在主从复制模式下,从服务器的过期键由主服务控制。
- 当从服务器向主服务器发送get message;从服务器发现message键已过期,但是还没收到主服务器的通知,因此他不会删除这个过期键而是将过期键对应的值直接返回给客户端。
- 当主服务器收到get message命令,发现message键已过期,因此删除这个键,向客户端返回空回复,并向从服务器发送DEL message命令,从服务器收到主服务器的通知,才会删除过期键,之后主从都不保存这个过期键。
键空间通知:针对某个键做了什么事。
键事件通知:某个命令被哪些键执行了。
以上来自《Redis设计与实现》笔记整理
上一篇: 王娡二婚入宫,册封皇后还生下千古一帝
下一篇: C动态分配内存注意事项