7.7 类型检查与命令多态
7.7.1 出现的原因
Redis中操作键的命令分两种:一种可以操作任何类型的键,一种只能操作特定类型的键
操作任何类型键命令:DEL、EXPIRE、RENAME、TYPE、OBJECT
操作特定类型键命令:
7.7.2 类型检查的实现
执行一个类型特定命令之前,Redis会先检查输入键的类型是否正确,然后再决定是否执行此命令
- 实现:通过redisObject的type属性来判断
执行一个类型特定命令之前,服务器会先检查输入数据库键的值对象是否为执行命令所需的类型,是的话,才对键执行指定的命令,不是的话,拒绝并返回给客户端一个类型错误
例子:LLen命令
7.7.3 多态命令的实现
Redis除了进行类型检查外,还会根据值对象的编码方式,选择正确的命令实现代码来执行命令
例子:LLEN命令,除了做类型检查外,还需要根据键的至对象所使用的编码来选择正确的LLEN命令实现:
注意:
7.7.4 执行流程总结
例子:LLEN命令
7.8 内存回收
7.8.1 出现的原因
C语言不支持自动内存回收功能,Redis在自己的对象系统中构建了一套基于引用计数技术的内存回收机制;通过这一机制,程序可以通过跟踪对象的引用计数信息,在适当的时候自动释放对象并进行内存回收
7.8.2 实现
由redisObject结构的refcount属性记录:’
对象的引用计数信息会随着对象的使用状态变化而变化:
- 相关API:
- 生命周期:创建对象、操作对象、释放对象
例子:字符串对象
7.9 对象共享
7.9.1 出现的原因
节约内存。如有两个不同的键使用了相同的值,可以给不同键创建两个不同的值对象,也可以使用同一个值对象;很明显,后者更节约内存,例子如下:键A、B共享整数值为100的字符串对象,服务器程序是初始存在的,其引用计数为3
7.9.2 实现
依然是由redisObject结构的refcount属性实现
让多个键共享同一个值对象的算法步骤:
当前机制:Redis会共享0-9999的字符串对象
当然,创建共享字符串对象的数量可以通过redis.h/REDIS_SHARED_INTEGERS常量进行修改
共享对象的使用:不仅是字符串键,那些在数据结构中嵌套了字符串对象的对象,如linkedlist编码的列表对象、hashtable编码的哈希对象、hashtable编码的集合对象和zset编码的有序集合对象都可以使用这些共享对象
注意:只对包含整数值的字符串对象进行共享,共享其他的复杂度太高,得不偿失
7.10 对象的空转时长
7.10.1 出现的原因
可以得到一个键没被使用的总时间
如果服务器打开了maxmemory选修,并且服务器用于回收内存的算法为volatile-lru或者allkeys-lru,则当服务器占用的内存数超过了maxmemory选项所设置的上限值时,空转时长较高的那部分键会优先被服务器释放,从而回收内存
配置文件的maxmemory选项和maxmemory-policy选项介绍了更多信息
7.10.2 实现
redisObject属性:type、encoding、ptr、refcount、lru,lru记录了对象最后一次被命令程序访问的时间
空转时长公式:当前时间 - 键的值对象的lru时间