Redis数据结构底层实现

内容均为个人学习后整理,如需转载请注明出处。

redis数据模型-自整理.png

adlist

typedef struct listNode {
    struct listNode *prev;
    struct listNode *next;
    void *value;
} listNode;

typedef struct list {
    listNode *head;
    listNode *tail;
    void *(*dup)(void *ptr);
    void (*free)(void *ptr);
    int (*match)(void *ptr, void *key);
    unsigned long len;
} list;

quicklist(由ziplist构成)

typedef struct quicklistNode {
    struct quicklistNode *prev;
    struct quicklistNode *next;
    unsigned char *zl;
    unsigned int sz;             /* ziplist size in bytes */
    unsigned int count : 16;     /* count of items in ziplist */
    unsigned int encoding : 2;   /* RAW==1 or LZF==2 */
    unsigned int container : 2;  /* NONE==1 or ZIPLIST==2 */
    unsigned int recompress : 1; /* was this node previous compressed? */
    unsigned int attempted_compress : 1; /* node can't compress; too small */
    unsigned int extra : 10; /* more bits to steal for future usage */
} quicklistNode;

typedef struct quicklist {
    quicklistNode *head;
    quicklistNode *tail;
    unsigned long count;        /* total count of all entries in all ziplists */
    unsigned long len;          /* number of quicklistNodes */
    int fill : 16;              /* fill factor for individual nodes */
    unsigned int compress : 16; /* depth of end nodes not to compress;0=off */
} quicklist;

dict

typedef struct dictht {
    dictEntry **table;
    unsigned long size;
    unsigned long sizemask;
    unsigned long used;
} dictht;

typedef struct dict {
    dictType *type;
    void *privdata;
    dictht ht[2];
    long rehashidx; /* rehashing not in progress if rehashidx == -1 */
    unsigned long iterators; /* number of iterators currently running */
} dict;

zskiplist

typedef struct zskiplistNode {
    robj *obj;
    double score;
    struct zskiplistNode *backward;
    struct zskiplistLevel {
        struct zskiplistNode *forward; 
        unsigned int span;
    } level[];
} zskiplistNode;

typedef struct zskiplist {
    struct zskiplistNode *header, *tail;
    unsigned long length; 
    int level;  
} zskiplist;

intset

typedef struct intset {
    uint32_t encoding;
    uint32_t length;
    int8_t contents[];
} intset;

五种对象类型:

127.0.0.1:6379> set msg "hello world"
OK
127.0.0.1:6379> type msg
string
127.0.0.1:6379> rpush numbers 1 3 5
(integer) 3
127.0.0.1:6379> type numbers
list
127.0.0.1:6379> hmset person name Sonya age 23 career Programmer
OK
127.0.0.1:6379> type person
hash
127.0.0.1:6379> sadd fruits apple banana cherry
(integer) 3
127.0.0.1:6379> type fruits
set
127.0.0.1:6379> zadd price 8.5 apple 5.0 banana 6.0 cherry
(integer) 3
127.0.0.1:6379> type price
zset

编码类型:

127.0.0.1:6379> set msg "hello world"
OK
127.0.0.1:6379> object encoding msg
"embstr"
127.0.0.1:6379> set story "long long long long long long long long ago..."
OK
127.0.0.1:6379> object encoding story
"raw"
127.0.0.1:6379> sadd numberSet 1 2 3
(integer) 3
127.0.0.1:6379> object encoding numberSet
"intset"
127.0.0.1:6379> sadd numberSet "Sonya"
(integer) 1
127.0.0.1:6379> object encoding numberSet
"hashtable"

字符串对象编码、编码转换

127.0.0.1:6379> set number 123
OK
127.0.0.1:6379> object encoding number
"int"
127.0.0.1:6379> incr number
(integer) 124
127.0.0.1:6379> object encoding number
"int"
127.0.0.1:6379> set pi 3.14
OK
127.0.0.1:6379> object encoding pi
"embstr"
127.0.0.1:6379> INCRBYFLOAT pi 1.0
"4.14"
127.0.0.1:6379> object encoding pi
"embstr"
127.0.0.1:6379> append number ", wooden boy"
(integer) 15
127.0.0.1:6379> object encoding number
"raw"
127.0.0.1:6379> append pi " is a float"
(integer) 15
127.0.0.1:6379> object encoding pi
"raw"
127.0.0.1:6379> set msg "hello world"
OK
127.0.0.1:6379> object encoding msg
"embstr"
127.0.0.1:6379> append msg ", redis"
(integer) 18
127.0.0.1:6379> object encoding msg
"raw"

列表对象

127.0.0.1:6379> rpush sayHi hello world redis
(integer) 3
127.0.0.1:6379> object encoding sayHi
"quicklist"

quicklist结构是在redis 3.2版本中新加的数据结构,用在列表的底层实现。

quicklist是由ziplist组成的双向链表,链表中的每一个节点都以压缩列表ziplist的结构保存着数据,而ziplist有多个entry节点,保存着数据。相当与一个quicklist节点保存的是一片数据,而不再是一个数据。

哈希对象

127.0.0.1:6379> hset booki name "Redis Design"
(integer) 1
127.0.0.1:6379> object encoding booki
"ziplist"
127.0.0.1:6379> hset booki description RedisLongLongLongLongLongLongLongLongLongLongLongLongLongDescription
(integer) 1
127.0.0.1:6379> object encoding booki
"hashtable"

集合对象

127.0.0.1:6379> sadd numberset 1 2 3
(integer) 3
127.0.0.1:6379> object encoding numberset
"intset"
127.0.0.1:6379> sadd numberset "str"
(integer) 1
127.0.0.1:6379> object encoding numberset
"hashtable"
127.0.0.1:6379> 
127.0.0.1:6379> 
127.0.0.1:6379> EVAL "for i=1, 512 do redis.call('SADD',KEYS[1], i) end" 1 integers
(nil)
127.0.0.1:6379> scard integers
(integer) 512
127.0.0.1:6379> object encoding integers
"intset"
127.0.0.1:6379> sadd integers 513
(integer) 1
127.0.0.1:6379> object encoding integers
"hashtable"

有序集合对象

127.0.0.1:6379> EVAL "for i=1, 128 do redis.call('ZADD', KEYS[1], i, i) end" 1 datas
(nil)
127.0.0.1:6379> object encoding datas
"ziplist"
127.0.0.1:6379> zcard datas
(integer) 128
127.0.0.1:6379> zadd datas 3.14 pi
(integer) 1
127.0.0.1:6379> zcard datas
(integer) 129
127.0.0.1:6379> object encoding datas
"skiplist"
127.0.0.1:6379>
127.0.0.1:6379>
127.0.0.1:6379>
127.0.0.1:6379> zadd objs 1.0 www
(integer) 1
127.0.0.1:6379> object encoding objs
"ziplist"
127.0.0.1:6379> zadd objs 2.0 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
(integer) 1
127.0.0.1:6379> object encoding objs

学习内容来源: 《Redis设计与实现》

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容

  • 1、黑暗中发现黄金工作坊中,在宽恕步骤讲解里,找每个人的人生剧本,我由目前现状找出的人生剧本是:我是一个浑浑噩噩、...
    李信兰阅读 200评论 0 0
  • 夏雨刚暂停,秋雨又来临,下、下、下,真是着急人,有感: 我要远离 冯玉华 我很生气 我要远离 远离那爱笑的风 远离...
    冯玉华书法阅读 533评论 0 0
  • 如果一件事情你开始就知道结果,那么你果是否还会去做 你有坚持过十年的事情吗? 没有 那么五年呢? 也没有 昨天晚上...
    格言夜读阅读 303评论 2 0
  • 戏如人生,人生如戏,知否知否中各种演戏,倒也是各种伎俩都出来了!但还好是此山还比那山高,祖母确实是精明能...
    寂然的莫迪阅读 177评论 0 0
  • 其实我也不知道我画的这堆算啥…… 今天国画颜料到了,当当下的各个绘画书也到了,满怀激动的心情打开包裹,还发现两本被...
    疯小妮阅读 667评论 7 8