【文章仅供非商业用途或交流学习使用】
简介
使用ANSI C语言编写,遵守BSD协议。
Redis用结构化的value满足业务的多样性需求,常用的类型有5种:string、list、set、map、sorted-set。
一、String类型
1 简介
Redis的String类型能够表达3种类型:字节串、整数、浮点数
三种类型之间根据具体场景由Redis完成相互间的自动转型,并且根据需要选取底层的承载方式。
针对String类型的value还具备简单的CAS操作,根据指定Key是否存在设置value值。
2 内存数据结构
在Redis内部,作为字节串承载的String型value内部以int,sds(simple dynamic string)作为结构存储。int用来存放整形数据,sds存放字节 / 字符串和浮点型数据。
二、List类型
1 简介
List即列表对象,用于存储String队列。
2 内存数据结构
List类型的value对象内部以linkedlist或ziplist承载。当List的元素个数和单个元素的长度较小时,Redis会采用ziplist实现以减少内存占用,否则采用linkedlist结构。
3 linkedlist实现
linkedlist内部实现是双向链表
4 ziplist实现
ziplist作为List对象承载实现时,通常用于List的元素个数不多且元素本身长度不大的情况。
三、Map类型
1 简介
Map型的value在Redis中又叫Hash,顾名思义,它的最初实现是一个哈希表。Map的语义和多数程序语言语义一致:包含若干个key-value,其中key不重复。
map内部key和value不能再嵌套map了,它只能是String所能表达的内容:整形、浮点型、字节串。
2 内存数据结构
map可以用hashtable和ziplist两种承载方式来实现。对于数据量较小的map,采用ziplist实现。
3 hashtable实现
4 ziplist实现
这里的ziplist和List的ziplist实现相似,都是通过entry来存放element,和List不同的是,map的ziplist的奇数位存放key,偶数位存放对应的value,通常情况下,只有很少几个kv对的map,采用ziplist效率反而更高,省去了hash计算、内存寻址等操作。尤其对于长字符串key,其hash值计算本身的开销甚至远大于顺序遍历时字符串比较的开销。
四、Set类型
1 简介
Set类似List,但它是一个无序集合,其中的元素不重复。
2 内存数据结构
Set在Redis中以insert或hashtable来存储。后者前述章节已介绍,对于Set,hashtable中的vlaue永远为NULL。当Set中只包含整数型的元素时,采用intset作为实现。
3 intset
intset的核心元素是一个字节数组,其中从小到大有序地存放着set的元素,intset同样针对小证书进行了性能优化,对不同类型的整数采用变长的存储,在元素均不大的情况下减少了内存开销。
五、Serted-Set类型
1 简介
Sorted-Set是Redis特有的数据类型,类似Map是一个key-value对,但它是一个有序的key-value对:
key:key-value对中的键,在一个sorted-set中不重复。
value:是一个浮点数,成为score。
有序:sorted-set内部按照score从小到大排序。
2 内存数据结构
Sorted-Set类型的value对象内部以ziplist或skiplist+hashtable来实现。
ziplist适用于元素个数不多、元素内容不大的场景。
对于更通用的场景,sorted-set采用skiplist(跳表)来实现。
3 skiplist
关于skiplist介绍:https://www.jianshu.com/writer#/notebooks/36290124/notes/45470984
4 hashtable
跳表是一种实现顺序相关操作的较高效的数据结构,但它对于简单的ZSCORE操作效率并不高,Redis在实现sorted-set时,同时使用hashtable和skiplist。