前言
面试中肯定会被问到一个问题:Redis有哪些基础类型,它们的应用场景是什么?或直接问:你实际项目中用到了哪些?
下面会结合一些核心源码来讲解,还会讲一些细节点。
(温馨提示:源码看不懂的可以先跳过,有兴趣的可以研究。不对读一读源码有助于加深理解和记忆,)
一、基础类型
核心的5个基础类型:string、list、hash、set、zset
扩展:HyperLogLog、Geo、Pub/Sub、BloomFilter
对象类型(type):字符串对象、列表对象、哈希对象、集合对象、有序集合对象
存储形式(encoding) :int、raw、embstr、ziplist、quicklist、hashtable、intset、skiplist
encoding对应的值:
#define OBJ_ENCODING_RAW 0 /* Raw representation */
#define OBJ_ENCODING_INT 1 /* Encoded as integer */
#define OBJ_ENCODING_HT 2 /* Encoded as hash table */
#define OBJ_ENCODING_ZIPMAP 3 /* Encoded as zipmap */
#define OBJ_ENCODING_LINKEDLIST 4 /* No longer used: old list encoding. */
#define OBJ_ENCODING_ZIPLIST 5 /* Encoded as ziplist */
#define OBJ_ENCODING_INTSET 6 /* Encoded as intset */
#define OBJ_ENCODING_SKIPLIST 7 /* Encoded as skiplist */
#define OBJ_ENCODING_EMBSTR 8 /* Embedded sds string encoding */
#define OBJ_ENCODING_QUICKLIST 9 /* Encoded as linked list of ziplists */
#define OBJ_ENCODING_STREAM 10 /* Encoded as a radix tree of listpacks */
当哈希,列表,仅由整数组成的集合和有序集合在小于给定元素数且最大元素大小时,以一种非常节省内存的方式进行编码,该方式使用的内存减少多达10倍(其中5节省的时间(平均节省)。所以Redis每一种对象类型都有2种的编码存储方式。
1. String 字符串对象
在字符串长度小于44字节时,使用 embstr 形式存储;当长度超过 44字节时,使用 raw 形式存储。
int 编码用来保存的是可以用 long 类型表示的整数值。
SDS结构体:
#define SDS_TYPE_5 0
#define SDS_TYPE_8 1
#define SDS_TYPE_16 2
#define SDS_TYPE_32 3
#define SDS_TYPE_64 4
struct __attribute__ ((__packed__)) sdshdr5 {
unsigned char flags; /* flags共8位,低三位保存类型标志,高5位保存字符串长度,小于32(2^5-1)*/
char buf[]; /* 保存具体的字符串 */
};
struct __attribute__ ((__packed__)) sdshdr{
8,16,