struct redisServer{ //.. //数组,保存服务器中所有的数据库 redisDb *db; //服务器中数据库的数量 int dbnum; } typedef struct redisClient{ //... //记录客户端当前正在使用的数据库 redisDb *db; }
-
redis中的dbnum属性服务器中的数据库数量,默认有16个数据库。
-
每个客户端都有自己的数据库,默认情况下客户端的目标数据库为0号数据库,可以通过SELECT命令来切换。
-
在服务器内部,redisClient结构的db属性来记录客户端当前目标数据库,这个属性是指向redisDb的指针,指向redisServer中的db属性,代表当前客户端所连接的数据库,SELECT命令可改变redisClient中这个属性。
typedef struct redisDb{ //... //数据库键空间,保存数据库中所有的键值对 dict *dict; //过期字典,保存着键的过期时间 dict *expires; }
-
键空间的键就是redis中的键,都是String,而值就是String,list,hash,set,zset。
-
redis中对键值对 *** 作的时候,都需要 *** 作到redisDb中的dict,对键值对的普通增删改查 *** 作,都是先找到键的值,之后进行 *** 作值对象。
-
FLUSHDB,清空键空间中的所有键,以及其对应的值对象。
RANDOMKEY,随机返回一个键
DBSIZE,返回数据库中键的数量
EXISTS,判断是否存在这个键
RENAME,重命名键
KEYS,返回相匹配的所有key,例:KEYS feng*
-
EXPIRE,PEXPIRE,设置键的过期时间,后者精确到毫秒
EXPIREAT,PEXPIREAT,设置键的过期时间,UNIX时间戳,后者精确到毫秒,在代码中所有的命令最终都会转化为 PEXPIREAT
SETEX,只能用于string类型
TTL,PTTL,返回键的剩余过期时间,后者精确到毫秒,没有设置过期时间返回-1
PERSIST,移除过期时间
-
键空间的维护,在读取一个键时,服务器会记录这个键的命中次数(hit)和未命中次数(miss),
在读取一个键之后,服务器更新键的LRU时间,这个时间用来计算键的闲置时间。
-
如果有客户端使用WATCH命令监视了一个键,并且服务器对这个键进行修改之后,会将这个键标记为(dirty),从而让事务程序注意到。服务器每改一个键之后,都会对dirty加1,这个计数器会触发服务器的持久化以及复制 *** 作。如果服务器开启了数据库通知功能,那么在对键修改之后,会按照配置发送相应的数据库通知。
-
redisDb中的expires字典保存了数据库中所有键的过期时间,通常称之为过期字典,里面保存了long long类型的整数,整数则保存着毫秒精度的UNIX时间戳。
-
过期键的删除策略:
1.定时删除,设置键过期时间时,创建一个定时器(timer),在键的过期时间来临时,立即执行对键的删除 *** 作。(浪费CPU,节省内存)
2.惰性删除,每次获取键的时候,检查键是否过期。(非常浪费内存)
3.定期删除,每个一段时间,对数据库进行检查,主动删除过期键,由算法实现。(适中,难点在于如何确定定期删除的频率)
过期键的判定:1.检查键是否存在于过期字典,2.检查当前UNIX时间戳是否大于键的过期时间。
-
AOF,RDB,复制功能,对过期键的处理
使用SAVE,BGSAVE命令创建RDB文件时,不会保存过期键。载入RDB文件时,主服务器不会导入过期键,从服务器会导入,但是主从同步的时候,从服务器也会删掉这个过期键
当服务器以AOF持久化运行时,如果某个键已经过期,但是没有被惰性删除,AOF文件不会产生影响,如果之后键被删除,则会在AOF文件中追加一个DEL命令,显示记录此键已被删除。AOF重写时,过期的键不会被保存到重写后的AOF文件中
当使用主从复制时,主服务器中键过期后,会向所有的从服务器发送DEL命令
(待续。。。)
三:事件(待续。。。)
四:客户端与服务器(待续。。。)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)