Redis设计与实现之数据库键空间
什么是数据库键空间
redis是一个键值对数据库服务器, 服务器中每一个数据库都由一个 server.h/redisDb
的结构表示, 其中, redisDb 结构中的 dict字典
保存了数据库中所有的键值对, 这个字典即位键空间(keyspace)
键空间和用户所见的数据库是直接对应的
- 键空间的键也就是数据库的键, 每个键都是一个字符串对象
- 键空间的值也就是数据库的值, 每个值可以是字符串对象、列表对象、哈希表对象、集合对象、有序集合对象中的任意一种Redis对象
举例, 假如我们在一个空白的数据库中依次执行以下命令
上述指令执行完成之后, 数据库的键空间如下图所示:
添加新键
添加一个新键到数据库, 实际上就是讲一个新键值对添加到键空间字典里面, 其中键为字符串对象, 而值为任意一种类型的Redis对象。
举例,如果数据库空间如上图(图9-4)所示, 那么在执行以下命令后
redis> set date "2013.12.1"
OK
键空间将新增加一个键值对, 这个新键值对的键是一个包含字符串 "date" 的字符串对象, 而键值则是一个包含字符串 "2013.12.1" 的字符串对象, 如下图
删除键
删除数据库中的一个键, 实际上就是在键空间里面删除一个键值对所对应的对象
举例, 加入初始键空间如图9-4所示, 那么执行以下命令:
redis> del book
(integer) 1
键book以及它的值将会从键空间被删除, 如下图所示:
更新键
对一个数据库的键更新, 实际上就是对监控里面键空间里面键所对应的值对象进行更新, 根据值对象类型的不同, 更新的具体方法也会有所不同.
举例, 键空间依旧如 9-4 所示, 那么执行以下命令
redis> set message "blah blah"
OK
键message的值对象, 将会从之前包含 "hello world" 字符串 更新为包含 "blah blah" 的字符串, 如下图所示
在上述结果的基础之上, 继续执行如下命令
redis> hset book page 320
(integer) 1
那么键空间中, book键的值对象(一个哈希对象)将会被更新, 新的键值对 page 和 320 键会被添加到 值对象里面, 如下图所示:
对键取值
对于一个数据库键进行取值, 实际上就是在键空间中, 取出键所对应的值对象, 根据值对象的类型不同, 具体的取值方法也会有所区别.
如果当前键空间如图 9-4 所示, 执行以下命令:
redis> get message
"hello world"
get命令将首先在键空间中查找键message, 找到键之后, 取得该键所对应的字符串对象值, 之后在返回值对象所包含的字符串 "hello world" , 取值过程如下:
如果继续执行如下命令:
redis> lrange alphabet 0 -1
1) "a"
2) "b"
3) "c"
lrange 命令将首先在键空间中查找键 alphabet, 找到键之后, 取出键所对应的列表对象值, 之后在返回列表所包含的三个字符串对象值, 取值过程如下图:
其他键空间操作
除了基础的添加、删除、更新、取值之外, 还有很多针对数据库本身的redis命令, 也是通过对键空间进行处理完成的.
如: 清空整个数据库的命令 flushdb, 就是通过删除键空间中所有键值对实现的
如: 随机返回数据库中某个键的 randomkey 命令, 就是通过在键空间中随机返回一个键来实现的.
如: 用户返回数据库键数量的 dbsize 命令, 通过返回键空间中键值对的数量来实现
类似的命令还有: exists、reanme、keys等
读写键空间时的维护操作
当使用Redis命令对数据库进行读写时, 服务器不仅会对键空间执行指定的读写操作, 还会执行一些额外的维护操作.
- 在读取一个键之后(读操作和写操作都要对键进行读取), 服务器会根据键是否存在, 更新服务器键空间中的命中(hit)次数或者未命中(miss)次数, 即对应 info stats 中的 keyspace_keys 与 keyspace_misses
- 读取一个键之后, 服务器会更新键的LRU(最后一次使用时间), 这个值可以用于计算key的闲置时间, 可使用
object idletime <key>
来获取. - 如果服务器在读取一个键时, 发现该键已过期, 服务器会先删除这个过期的键, 再执行余下的其他操作
- 如果有客户端使用 watch 监控了某个键, 那么服务器在对被监视的键进行修改之后, 会将这个键标记为脏(dirty), 从而让十五程序注意到这个键已经被修改过.
- 服务器每次修改一个键之后, 都会对脏(dirty)键计数器加1, 这个计数器会出发服务器的持久化以及复制操作.
- 如果开启了数据库通知功能, 那么在对键进行修改之后, 服务器将会按照配置发送相应的数据库通知.
参考资料
参考内容
书籍
: 《Redis 设计与实现》
实体书
: 可在京东搜索购买
注意事项
《Redis 设计与实现》 本书讲解基于redis 3.x 版本, 本人整理基于redis 5.0.6,期间跨了两个大版本, 部分功能具体实现已发生变化, 如发现整理内容与 《Redis 设计与实现》 讲解不一致, 可加 QQ : 2215508028 沟通,或在相关章节评论留言,会自动同步至issue
整理内容时参考的redis源码
版本
: 5.0.6
官方git
: redis官方GIT (commit :bb78454b0fef0dc5903328d037ac2520108e0044 (5.0.6版本,redis官方的commit))