下面的内容来自《Redis设计与实现》这本书。
Redis内部自己实现的主要数据结构有简单动态字符串(SDS)、双端链表、字典、跳跃表、整数集合和压缩列表。
Redis并没有直接使用这些数据结构来实现键值对数据库,而是基于这些数据结构创建了一个对象系统,这个系统包含字符串对象、列表对象、哈希对象、集合对象和有序集合对象这五种类型的对象,每种对象都用到了至少一种上面所述的数据结构。
通过这五种不同类型的对象,Redis可以在执行命令之前,根据对象的类型来判断一个对象是否可以执行给定的命令。使用对象的另一个好处是,我们可以针对不同的使用场景,为对象设置多种不同的数据结构实现,从而优化对象在不同场景下的使用效率。
除此之外,Redis的对象系统还实现了基于引用计数技术的内存回收机制,当程序不再使用某个对象的时候,这个对象所占用的内存就会被自动释放。另外,Redis还通过引用计数技术实现了对象共享机制,这一机制可以在适当的条件下,通过让多个数据库键共享同一个对象来节约内存。(原来Redis也有内存回收机制!!!)
Redis使用对象来表示数据库中的键和值,每次当我们在Redis的数据库中新创建一个键值对时,我们至少会创建两个对象,一个对象用作键值对的键(键对象),另一个对象用作键值对的值(值对象)。
对于Redis数据库保存的键值对来说,键总是一个字符串对象,而值则可以是字符串对象、列表对象、哈希对象、集合对象或者有序集合对象的其中一种。
通过encoding属性来设定对象所使用的编码,而不是为特定类型的对象关联一种固定的编码,极大地提升了Redis的灵活性和效率,因为Redis可以根据不同的使用场景来为一个对象设置不同的编码,从而优化对象在某一场景下的效率。
字符串对象的编码可以是int、raw或者embstr。其中,raw就是简单动态字符串(SDS)。
列表对象的编码可以是ziplist或者linkedlist。其中,ziplist就是压缩列表。
哈希对象的编码可以是ziplist或者hashtable。其中,hashtable就是字典。
集合对象的编码可以是intset或者hashtable。其中,intset就是整数集合。
有序集合对象的编码可以是ziplist或者skiplist。其中,特别要说明的是,这里的skiplist不单只有跳跃表,其实还有一个字典。也就是对于skiplist编码的有序集合对象,其实是用跳跃表和字典共同实现的。为了让有序集合的查找和范围型操作都尽可能快地执行,Redis选择了同时使用字典和跳跃表两种数据结构来实现有序集合。具体的说明还是看书吧,P78,这里就不详细写了。。。