目的:清楚Redis如何实现单机数据库
redis.h/redisServer结构的db数组中,db数组的元素为redis.h/redisDb结构,每个redisDb结构代表一个数据库:
服务器的初始化:程序会根据redisServer的dbnum属性来决定应该创建多少个数据库,dbnum属性的值由服务器配置的database选项决定,默认为16,即创建16个数据库:
每个Redis客户端有自己的目标数据库,默认情况下为0号数据库
redisClient的db属性记录了当前使用的数据库,该属性是一个指向redisDb的指针,指向redisServer的db数组中的一个元素:
切换数据库:使用SELECT命令,修改redisClient.db指针,指向redisServer.db的不同元素即可
例子:select 2
所有的键值对都保存在redisDb.dict属性中,这个dict字典被称为键空间:
键为字符串对象,值为五种对象之一
数据库的crud实际上都是通过对键空间字典进行操作实现的
将一个新键值对添加到键空间字典里,键为字符串对象,值为任意的对象
在键空间里面删除键所对应的键值对对象
对键空间里面键所对应的值对象进行更新,值对象类型不同,更新方法也不同
如字符串对象,则直接替换值对象;如哈希对象,如键相同,值对象的键值对没有出现过,则添加进去,也等于是更新键
在键空间里面取出键所对应的值对象,值对象类型不同,取值方法也不同
如字符串对象,GET message,则查找message键,找到键后,获取该键所对应的字符串对象值,再返回此值对象所包含的字符串;如列表对象,LRANGE xxx 0 -1,找到xxx键之后,获取对应的列表对象值,再返回列表对象中包含的三个字符串对象的值
1.6、1.7是关于过期键的讲解,请看:《Redis设计与实现》第九章总结二:过期键相关操作
作用:可以让客户端通过订阅给定的频道或者模式来获知数据库中键的变化以及数据库中命令的执行情况
例子1:客户端获取0号数据库针对message键执行的所有命令
例子2:客户端获取0号数据库所有执行DEL命令的键:
键空间通知:关注“某个键执行了什么命令”的通知,如上述例子1
键事件通知:关注“某个命令被什么键执行了”的通知,如上述例子2
服务器配置的notify-keyspace-events选项决定了服务器所发送通知的类型:
发送数据库通知的功能是由notify.c/notifyKeyspaceEvent函数实现的:
void notifyKeyspaceEvent(int type, char* event, robj * key, int dbid)
参数解释:type参数是当前想要发送的通知的类型,程序会根据这个值来判断通知是否就是服务器配置notify-keyspace-events选项所选定的通知类型,从而决定是否发送通知;event是事件的名称;key是产生事件的键;dbid是产生事件的数据库号码。
例子:SADD命名的实现函数saddCommand事件通知代码: