(一)基本数据结构
1)redisServer
Redis服务器使用redisServer结构保存服务器的状态,其中,dbnum表示服务器的数据库数量,一个redisDb类型的数组保存所有的数据库。
struct redisServer {
//服务器的数据库数量
int dbnum;
//一个数组,保存服务器中的所有数据库
redisDb *db;
}
2)redisClient
Redis客户端使用redisClient结构来记录客户端当前的状态,其中,一个redisDb类型的指针指向了客户端当前使用的数据库。
struct redisClient {
//记录客户端当前正在使用的数据库
redisDb *db;
}
redisClient.db指针指向redisServer.db数组中的一个元素,被指向的元素就是客户端的目标数据库。通过修改redisClient.db指针,让它指向服务器中的不同数据库,从而实现切换目标数据库的功能。
3)redisDb
Redis是一个键值对(key-value pair)数据库服务器,服务器中的每个数据库都由一个redisDb结构表示,其中,redisDb结构的dict字典保存了数据库中的所有键值对,即键空间。
struct redisDb {
//数据库键空间,保存这数据库中所有的键值对
dict *dict
}
键空间的键也就是数据库的键,每个键都是一个字符串对象。键空间的值也就是数据库的值,每个值可以是字符串对象、列表对象、哈希表对象、集合对象或有序集合对象中的任意一种。如下图所示,alphabet是一个列表键,book是一个哈希表键,message是一个字符串键。所有对数据库的操作,如添加一个键值对到数据库,从数据库删除一个键值对,更新某个键值对,或者获取某个键值对,都是通过对键空间字典进行操作来实现的。
(二)读写键空间的维护操作
当使用Redis命令对数据库进行读写时,服务器不仅会对键空间执行指定的读写操作,还会执行一些额外操作:
在读取一个键之后,服务器会根据键是否存在来更新服务器的键空间命中(hit)次数或键空间不命中(miss)次数。
在读取一个键之后,服务器会更新键的LRU时间,该值可以用于计算键的闲置时间。
如果服务器读取一个键时发现该键已经过去,那么会先删除这个过期键,然后才执行其他操作。
服务器每次修改一个键之后,都会对脏(dirty)键计数器的值增1,这个计数器会触发服务器的持久化以及复制操作。
如果有客户端使用WATCH命令监视了某个键,那么服务器在对被监视的键进行修改之后,会将这个键标记为脏(dirty),从而让事务程序注意到这个键已经被修改过。
如果服务器开启了数据库通知功能,那么在对键进行修改之后,服务器将按配置发送相应的数据库通知。