1、redis并没有直接使用主要数据结构,比如简单动态字符串SDS、双端链表、字典、压缩列表、整数集合等等,而是基于数据结构创建一个对象系统包含字符串对象、列表对象、hash对象、集合对象、和有序集合对象,执行命令之前判断一个对象是否可以执行给定的命令,另一个好处是,可以针对不同的使用场景为对象设置多种不同的数据结构实现,从而优化对象在不同场景下的使用效率
2、Redis对象还实现了基于引用计数技术的内存回收机制,内存自动释放,对象共享机制,空转时较大的那些键可能会被优先被服务器删除
3、redis新创建一个键值对,至少两个对象,一个是键对象,一个是值对象
4、redisobject结构
type属性,常量:redis_string redis_list redis_hash redis_set redis_zset
type key 命令查看对象类型
ptr指针指向对象底层实现数据结构,这些数据结构由对象的encoding属性决定
encoding属性记录对象使用的编码
int long类型整数
embstr embstr编码的简单动态字符串
raw 简单动态字符串
ht 字典
linkedlist 双端链表
ziplist 压缩列表
intset 整数集合
skiplist 跳跃表和字典
每种类型对象至少有两种不同编码,使用encoding属性来设定对象所使用的编码,而不是为特定类型的对象关联一种固定的编码,极大提升了redis得灵活性和效率
5、字符串对象,编码:int raw embstr
数值小于long,则int编码,字符串大于32字节,则raw,小于等于32字节,则embstr
embstr编码是专门用于保存端字符串的一种优化编码方式,这种编码和raw编码都是使用redisobject结构和sdshdr结构来表示字符串对象,但是raw编码调用两次内存分配函数分别创建redisobject结构和sdshdr结构,而embstr编码通过调用一次内存分配函数分配一块连续的空间,包含redisobject和sdshdr,释放内存也只调用一次释放函数
浮点类型也是字符串存储
5.1、int 编码字符串对象和embstr编码的字符串对象再条件满足下,会被转换成raw编码
6、列表对象编码可以是ziplist和linkedlist
列表对象满足 所有字符串长度小于64字节,列表对象保存数量小于512使用ziplist,否则使用linkedlist,
以上两个条件可以修改,配置文件 list-max-ziplist-value list-max-ziplist-entries
7、hash对象 编码可以是ziplist或者hashtable
7.1、ziplist编码的hash对象使用压缩列表作为底层实现,新的键值对,推入到压缩列表表尾
hashtable ,底层使用字典结构
7.2、编码转换,ziplist编码使用条件,所有键值对,键和值的长度小于64字节,键值对数量小于512,可以修改hash-max-ziplist-value hash-max-ziplist-entries来修改
8、集合对象 编码可以是intset hashtable
8.1、集合转换,使用intset条件 所有元素都是整数值,所有元素数量不超过512,set-ma-intset-entries来修改第二个配置参数
9、有序集合编码可以是zipliist或者skiplist
ziplist编码的压缩列表对象使用压缩列表作为底层实现,紧挨着,第一个保存元素成员,第二个保存元素分值
skiplist编码的有序集合对象使用zset结构作为底层实现,一个zset结构同时包含一个字典和一个跳跃表,包含zsl跳跃表按照分数从小到大保存所有集合元素,每个跳跃表节点都保存了一个集合元素,跳跃表节点object属性保存了元素的成员,跳跃表节点score保存分数,
dict字典为有序结婚,创建一个成员到分数的映射,o(1) 复杂度找到给定成员的分值
9.1、编码转换,ziplist使用条件:数量小于128 所有元素成员长度小于64字节,不满足使用ziplist,可以使用zset-max-ziplist-entries zset-max-ziplist-value选项说明
10、命令检查和多态实现
11、对象共享,整数值
让多个键共享同一个值需要执行以下两个步骤
将数据库键的值指针指向一个向右的值对象,将被共享对象的引用计数增一
为什么redis不同享包含字符串的对象,整数值负责度o(1) 费防护层那o(n) 多个值o(n的平方)
12、空转时长
redisobject最后一个属性lru,该属性记录对象最后一次被命令程序访问的时间,如果服务器打开了maxmemory选项,如武器回收内存算法为volatile-lry或者allkeys-lru那么服务器内存超时,空转时长较高时候那部分键会优先被服务器释放,从而回收内存