Redis中的类型和数据结构

redis对外有5中基本类型,分别是string

1
t_string.c
, list
1
t_list.c
, hash
1
t_hash.c
, set
1
t_set.c
和 zset (ordered set)
1
t_zset.c
. 这5种类型是“接口”而不是“实现”,因此redis得以根据不同的情形自由选择不同数据结构的实现,这也是redis在设计上的高明之处。

5种基本类型对应了int

1
object.c
, embstr
1
object.c
, raw
1
sds.c
, linkedlist
1
adlist.c
, ziplist
1
ziplist.c
, skiplist
1
t_zset.c
, ht
1
dict.c
, intset
1
intset.c
这8种数据结构的实现。

类型与数据结构实现的对应关系如图。

redis types

实用

1
type KEYNAME
可以查看某个key对应的类型,而
1
object encoding KEYNAME
可以查看该key内部的实现。

string

string 有三种实现方式,分别是

1
int
,
1
embstr
1
raw
. 长度比较短的整数会使用
1
int
实现。长度比较短的字符串会使用
1
embstr
, 更长的会使用
1
raw
1
embstr
1
raw
的区别在于,
1
embstr
1
redisObject
1
sds
放在一块连续空间里面,这样申请内存和释放内存都只需要一次调用。带来的坏处是,
1
embstr
是只读的,如果调用
1
append
等操作则自动升级为
1
raw

对于

1
int
实现的string,如果调用
1
strlen
1
gettrange
等会产生额外开销。如果需要强制使用
1
raw
来实现, 可以用
1
setrange

zset

zset在元素较少时,使用

1
intset
实现。 在元素较多时,使用
1
skiplist
1
dict
一起实现。其中
1
skiplist
用于提供顺序相关的操作,而
1
dict
用于快速查询score.

关于skiplist: 这是一种用多级链表加快查询速度的数据结构。Insert, delete, search的复杂度均为o(logn), 还可以进行高效的range query, 功能与性能与红黑树,B树相当,但实现更简单。CLRS里有详细的解释。