日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

redis 数据结构

發(fā)布時間:2024/4/13 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 redis 数据结构 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

2019獨角獸企業(yè)重金招聘Python工程師標準>>>

?

redis對象redis 數(shù)據(jù)結(jié)構
字符串對象?SDS(簡單動態(tài)字符串)
列表對象?壓縮列表(ziplist) 或 鏈表(linkedlist)
哈希對象?壓縮列表 或 字典
集合對象?整數(shù)集合 或 字典
有序集合對象?壓縮列表 或 跳躍表和字典

?

類型編碼對象
REDIS_STRINGREDIS_ENCODING_INT使用整數(shù)值實現(xiàn)的字符串對象。
REDIS_STRINGREDIS_ENCODING_EMBSTR使用?embstr?編碼的簡單動態(tài)字符串實現(xiàn)的字符串對象。
REDIS_STRINGREDIS_ENCODING_RAW使用簡單動態(tài)字符串實現(xiàn)的字符串對象。
REDIS_LISTREDIS_ENCODING_ZIPLIST使用壓縮列表實現(xiàn)的列表對象。
REDIS_LISTREDIS_ENCODING_LINKEDLIST使用雙端鏈表實現(xiàn)的列表對象。
REDIS_HASHREDIS_ENCODING_ZIPLIST使用壓縮列表實現(xiàn)的哈希對象。
REDIS_HASHREDIS_ENCODING_HT使用字典實現(xiàn)的哈希對象。
REDIS_SETREDIS_ENCODING_INTSET使用整數(shù)集合實現(xiàn)的集合對象。
REDIS_SETREDIS_ENCODING_HT使用字典實現(xiàn)的集合對象。
REDIS_ZSETREDIS_ENCODING_ZIPLIST使用壓縮列表實現(xiàn)的有序集合對象。
REDIS_ZSETREDIS_ENCODING_SKIPLIST使用跳躍表和字典實現(xiàn)的有序集合對象。

?

REDIS_STRING

編碼raw結(jié)構

sds字符串?

?

struct sdshdr{

?? ?? //記錄 buf 數(shù)組中已使用字節(jié)的數(shù)量

int len;?

//紀錄buf未使用字節(jié)的數(shù)量

int free

//存放字符串

char buf[];

};

作用 : 作為redis 的部分鍵 和 值

REDIS_LIST?

?

列表實現(xiàn)通過 鏈表和壓縮列表

linkedlist?

?

typedef struct listNode {// 前置節(jié)點struct listNode *prev;// 后置節(jié)點struct listNode *next;// 節(jié)點的值void *value;} listNode; typedef struct list {// 表頭節(jié)點listNode *head;// 表尾節(jié)點listNode *tail;// 鏈表所包含的節(jié)點數(shù)量unsigned long len;// 節(jié)點值復制函數(shù)void *(*dup)(void *ptr);// 節(jié)點值釋放函數(shù)void (*free)(void *ptr);// 節(jié)點值對比函數(shù)int (*match)(void *ptr, void *key);} list;

作用 :鏈表為列表鍵 鏈表節(jié)點為值 ?實現(xiàn)redis?發(fā)布與訂閱, 慢查詢, 監(jiān)視器, 等等。

?

REDIS_HASH

哈希鍵的實現(xiàn) 字典 /壓縮列表

字典的實現(xiàn)

typedef struct dict {// 類型特定函數(shù)dictType *type;// 私有數(shù)據(jù)void *privdata;// 哈希表 rehash 時使用ht[1]dictht ht[2];// rehash 索引// 當 rehash 不在進行時,值為 -1int rehashidx; /* rehashing not in progress if rehashidx == -1 */} dict;

?

哈希表的實現(xiàn)

typedef struct dictht {// 哈希表數(shù)組dictEntry **table;// 哈希表大小unsigned long size;// 哈希表大小掩碼,用于計算索引值// 總是等于 size - 1unsigned long sizemask;// 該哈希表已有節(jié)點的數(shù)量unsigned long used;} dictht;

哈希表的節(jié)點

typedef struct dictEntry {// 鍵void *key;// 值union {void *val;uint64_t u64;int64_t s64;} v;// 指向下個哈希表節(jié)點,形成鏈表struct dictEntry *next;} dictEntry;

通過鏈表解決沖突問題

負載因子為0.5 時擴張 小于0.1收縮

?

REDIS_SET ?

通過整數(shù)集合和字典實現(xiàn)

?

整數(shù)集合結(jié)構 只有小整數(shù) 才會在這里 其余都是在字典中實現(xiàn)

typedef struct intset {// 編碼方式uint32_t encoding;// 集合包含的元素數(shù)量uint32_t length;// 保存元素的數(shù)組int8_t contents[];} intset;

REDIS_ZSET

?

有序集合通過跳躍表和字典實現(xiàn)或壓縮列表

有序集合的跳躍表和字典實現(xiàn)

跳躍表的實現(xiàn)

?

typedef struct zskiplist {// 表頭節(jié)點和表尾節(jié)點struct zskiplistNode *header, *tail;// 表中節(jié)點的數(shù)量unsigned long length;// 表中層數(shù)最大的節(jié)點的層數(shù)int level;} zskiplist;

跳躍表的節(jié)點實現(xiàn)

typedef struct zskiplistNode {// 后退指針struct zskiplistNode *backward;// 分值 double 類型的浮點數(shù), 跳躍表中的所有節(jié)點都按分值從小到大來排序double score;// 成員對象 指向sds對象 值robj *obj;// 層 層高范圍1-32 第一層level[0]struct zskiplistLevel {// 前進指針 指向當前層的下一個節(jié)點struct zskiplistNode *forward;// 跨度 紀錄與同層下一節(jié)點之間的距離unsigned int span;} level[];} zskiplistNode;

?

有序集合的實現(xiàn)

typedef struct zset {zskiplist *zsl; // 跳躍表dict *dict; // 字典} zset;

zset?結(jié)構中的?dict?字典為有序集合創(chuàng)建了一個從成員到分值的映射, 字典中的每個鍵值對都保存了一個集合元素: 字典的鍵保存了元素的成員, 而字典的值則保存了元素的分值。 通過這個字典, 程序可以用?O(1)?復雜度查找給定成員的分值,?ZSCORE?命令就是根據(jù)這一特性實現(xiàn)的, 而很多其他有序集合命令都在實現(xiàn)的內(nèi)部用到了這一特性。

為什么有序集合需要同時使用跳躍表和字典來實現(xiàn)?

在理論上來說, 有序集合可以單獨使用字典或者跳躍表的其中一種數(shù)據(jù)結(jié)構來實現(xiàn), 但無論單獨使用字典還是跳躍表, 在性能上對比起同時使用字典和跳躍表都會有所降低。

舉個例子, 如果我們只使用字典來實現(xiàn)有序集合, 那么雖然以?O(1)?復雜度查找成員的分值這一特性會被保留, 但是, 因為字典以無序的方式來保存集合元素, 所以每次在執(zhí)行范圍型操作 —— 比如?ZRANK?、?ZRANGE?等命令時, 程序都需要對字典保存的所有元素進行排序, 完成這種排序需要至少?O(N \log N)?時間復雜度, 以及額外的?O(N)?內(nèi)存空間 (因為要創(chuàng)建一個數(shù)組來保存排序后的元素)。

另一方面, 如果我們只使用跳躍表來實現(xiàn)有序集合, 那么跳躍表執(zhí)行范圍型操作的所有優(yōu)點都會被保留, 但因為沒有了字典, 所以根據(jù)成員查找分值這一操作的復雜度將從?O(1)?上升為?O(\log N)?。

因為以上原因, 為了讓有序集合的查找和范圍型操作都盡可能快地執(zhí)行, Redis 選擇了同時使用字典和跳躍表兩種數(shù)據(jù)結(jié)構來實現(xiàn)有序集合。

參考文獻 《redis設計與實現(xiàn)》

?

轉(zhuǎn)載于:https://my.oschina.net/haloooooo/blog/872961

總結(jié)

以上是生活随笔為你收集整理的redis 数据结构的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。