《Redis设计与实现》读书笔记(十一) ——Redis数据库与键空间

《Redis设计与实现》读书笔记(十一) ——Redis数据库与键空间

(原创内容,转载请注明来源,谢谢)

一、redis数据库

redis服务器将所有数据库都保存在redisServer结构里的db数组,数组里面的每个元素都是一个redisDb结构,每个redisDb代表一个数据库。

typedef structredisServer{
//省略其他内容....
redisDb *db;
int dbnum;
};

其中,dbnum表示数据库的数量,初始化服务器的时候,会根据此值创建数据库个数。该属性由配置文件中的database选项决定。

结构如下图:

二、切换数据库

默认情况下,客户端操作0号数据库,客户端可以通过select命令切换数据库。在服务器内部,客户端状态结构redisClient的db属性,记录客户端当前目标的数据库,该属性是指向redisServer的db数组中的某个具体redisDb结构的指针。

typedef structredisClient{
redisDb *db;
}redisClient;

如下图所示:

如果此时在客户端select 0,则redisClient的db指针又会指向db[0]。因此,select命令的原理,就是通过修改redisClient的db指针的指向,来实现数据库的切换。

由于redis没有指示当前在哪个数据库的命令,因此切换数据库后要注意相应的操作。尤其对于flushall这种命令,最好执行命令前,要先执行select到某个数据库,再次确认在当前要操作的数据库。

三、数据库键空间

redis是存储键值对的数据库服务器,每个数据库都是一个redisDb结构,其中用dict字典来保存每个键值对。

typedef structredisDb{
dict *dict;
}redisDb;

dict存储数据库中的所有键值对,也成为键空间。键空间的键就是数据库的键,每个键都是一个字符串对象;键空间的值,就是数据库的值,可以是redis5中对象中的任一种。

redis数据库中同时有多个键的情况,如下图所示:

由于键空间是个数据库字典,因此对键值的增删改查都是通过字典的操作进行的,主要如下:

1)添加新键,就是将新的键值对放在数据库字典里面。

2)删除键,就是从键空间的字典中,删除键值对对象。

3)更新键,实质是对键空间中键对应的值进行更新。

4)对键取值,实质上就是取出键空间中,键对应的值的对象。

除此之外,如flushdb即清空整个dict字典;randomkey即从dict字典中随机取一个键,再返回键对应的值对象;dbsize即返回dict字典键值对的总数量;exists、rename、keys等命令则是直接操作dict的键,或直接获取键并进行返回。

redis对于读写键空间,除了上述的正常读写,还会有相应的维护操作。其中,写操作都会先读键,因此下列的读,也包括写之前的读操作。主要如下:

1)读取一个键以后,服务器会根据键是否存在,来更新服务器中的键空间命中次数(hit)或未命中次数(miss)。这两个值可以在info status命令的keyspace_hits属性和keyspace_misses属性查看。

2)读取一个键以后,服务器会更新键的LRU,即最后访问时间,redis可以通过当前时间减去lru,确认该键的闲置时间。可以通过命令object ideltime key来查看key键的当前闲置时间。

3)读取一个键以后,发现该键已经过期,会先删除该键,然后再进行后续的操作。

4)如果客户端使用watch命令监视某个键,则修改键的值后,键会被标记为脏(dirty),从而让事务程序注意到该键已经被修改过。

5)服务器每次修改一个键后,都会对脏键计数器值增1,这个值会触发服务器持久化以及复制操作。

6)如果服务器开启数据库通知功能,则修改键后,服务器将按照配置,发送相应的数据库通知。

——written by linhxx 2017.09.03

原文发布于微信公众号 - 决胜机器学习(phpthinker)

原文发表时间:2017-09-03

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java帮帮-微信公众号-技术文章全总结

web前端之锋利的jQuery八:jQuery插件的使用(表单验证、表单提交)

插件也称扩展,是一种遵循一定规范的应用程序接口编写出来的程序。 1.jQuery表单验证插件-Validation: 最常使用JavaScript的场合就是表...

2845
来自专栏流媒体

dll生成和使用

592
来自专栏技术专栏

慕课网Flask构建可扩展的RESTful API-7. 权限控制

1.204 的HTTP状态码代表的是NO CONTENT,无内容。所以如果状态码是204,那么无论返回什么,前端都接受不到,但是我们要尽量返回格式化的信息,让前...

604
来自专栏大闲人柴毛毛

Linux Shell(一)——Shell变量

1 变量的分类 在Linux中,变量分为环境变量 和 局部变量。 环境变量能被子进程继承,而局部变量只能在当前进程中使用。 并且,不论是环境变量还是局...

3167
来自专栏Coding迪斯尼

java开发系统内核:创建文件操作API

1173
来自专栏finleyMa

Chrome 功能总结

原文:https://developers.google.com/web/updates/2017/08/devtools-release-notes#awai...

702
来自专栏蓝天

SHELL参数介绍

$0 = shell名称或shell脚本名称 $1 = 第一个shell参数 ... $9 = 第九个shell参数 $# = 位置参数的个数 "$*" = "...

604
来自专栏架构之路

mysql 通过慢查询日志查写得慢的sql语句

MySQL通过慢查询日志定位那些执行效率较低的SQL 语句,用--log-slow-queries[=file_name]选项启动时,mysqld 会写一个包含...

2994
来自专栏nummy

Tornado入门(五)应用结构

Tornado web应用的结构通常包含一个或者多个RequestHandler子类,一个将请求转发至处理器的Application对象,以及一个main()函...

571
来自专栏流柯技术学院

Loadrunner中web_find和web_reg_find函数的使用与区别

总结一下Loadrunner中的检查点函数,主要介绍两个函数:web_find()和web_reg_find();这两个函数均用于内容的查找,但两者也有本质的区...

682

扫描关注云+社区