亚洲视频二区_亚洲欧洲日本天天堂在线观看_日韩一区二区在线观看_中文字幕不卡一区

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.430618.com 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

不要虛度每一天,你的經驗就是這樣積累出來,然后用在了你的事情上面。
一:摘要概述

很多 redis 的使用者都可以清晰明白的道出Redis中常用的對象如string、list、hash、set、zset,一些場景比較豐富的使用者可能會說布隆過濾器、geo、Hash等。但是對于這些對象底層實現的數據結構卻是知之甚少,將會詳細闡述redis中的底層數據結構。為了彌補大家的創傷,今天分享Redis底層數據結構內容。

 

二:SDS

string作為redis中常用對象之一,普遍用于用戶信息緩存等場景。當string對象中encoding編碼為embstr或raw時都是采用sds作為其底層實現

 

2.1 SDS結構

源碼文件位于redis安裝目錄src下的sds.h,sds聲明了五種頭部類型,分別為sdshdr5、sdshdr8、sdshdr16、sdshdr32、sdshdr64。根據字符串長度創建不同頭部的sds實例

 

struct __attribute__ ((__packed__)) sdshdr8 {

uint8_t len;

uint8_t alloc;

unsigned char flags;

char buf[];

};

 

屬性名稱作用含義

len字符串長度

alloc預分配空間大小

flags低三位用于表示sds類型,可以查看sds.h文件76-82行定義

buf[]存儲字符串用數組

2.2 SDS與C字符串區別

區別描述

長度計算 c中的字符串長度計算需要數組遍歷,但是redis中的sds自身維護了len屬性。所以O(1)時間復雜度即可

緩沖區溢出c中字符串更改如果未提前做好內存分配則會內存溢出,但是sds則會根據alloc與len計算預留內存是否足夠分配重新申請內存

動態擴展 緩沖區溢出已經闡述這個概念,sds的內存空間會在字符串內容變更時自動擴展計算。策略為當字符換小于1M時*2翻倍,大于1M時每次擴容1M

惰性釋放 與空間預分配相似操作的還有內存惰性釋放,即字符串刪除某些內容后所占用的內存空間并不會立即釋放,后續字符串變更擴展就無需再申請內存

二:ZipList

ziplist可以說把redis對于內存的極致操作體現的淋漓盡致,鏈表除了節點值之外還需要維護前后節點兩個指針,并且還會造成內存碎片。壓縮列表緊湊的內存布局,所有節點都維護在整塊內存中處理

 

2.1 ZipList結構

屬性名稱作用含義

zlbytes列表健占用內存的總字節數,在對列表健內存重分配或者是計算zlend的時候使用

zltail 指向壓縮列表起始地址的指針

zllen 壓縮列表的節點數量

entry壓縮列表保存的節點數據

zlend壓縮列表的尾節點

2.2 Entry節點結構

 

屬性名稱作用含義

previous_entry_length 字節為單位記錄上一個節點的長度,如果上一個字節長度小于254占用1字節。大于254占用5字節,第一個字節設置為OxFE(十進制254),后面四個字節儲存長度

encoding 記錄content記錄的數據類型以及長度。長度一、二、五字節,值的最高位為00、01、10表示類型為字節數組,長度使用除去最高位的其它位記錄。11開頭表示儲存整數,除去最高位其他位置表示content數據長度

content 記錄壓縮列表記錄的數據

2.3 連鎖更新

一個壓縮列表節點在保存上一個節點長度使用previous_entry_length屬性,這個屬性可以使用1字節或者是5字節。假設現有一個壓縮列表里面保存的節點長度全部都是250-253,這時候previous_entry_length使用一字節記錄就行。但是這時候添加一個新節點到頭節點的位置,恰好這個節點的大小大于254字節,這時候所有后面字節都需要更新,因為他們的previous_entry_length都會變成5字節

 

三:QuickList

list 鏈表是redis中常用對象之一,之前一些版本中底層編碼數據采用雙向鏈表、壓縮列表的數據結構。但是后續考慮鏈表指針維護開銷以及內存碎片原因,開發新的數據結構quicklist,這是一個雙向鏈表和壓縮列表的混合體

 

3.1 quicklist圖示

 

3.2 結構描述

typedef struct quicklist {

quicklistNode *head;

quicklistNode *tail;

unsigned long count;

unsigned long len;

int fill : 16;

unsigned int compress : 16;

} quicklist;

 

屬性名稱作用含義

head頭部節點

tail 尾部節點

count壓縮列表元素數量總數

len ziplist節點數量

fill 單個ziplist節點的填充因子

compress不壓縮節點的深度

3.3 ziplist節點

quicklist 內部默認單個 ziplist 長度為 8k字節,超出了這個字節數就會新建一個 ziplist。ziplist 的長度由配置參數 list-max-ziplist-size決定

Redis底層數據結構解密

 

3.4 LZF壓縮

快速列表ziplist為了push與pop操作的效率默認首尾節點不進行LZF壓縮,如果需要設置更多節點不進行LZF壓縮可以通過redis.conf配置文件中1099行list-compress-depth 0參數定義

 

四:Dict

redis中的hash、set等對象都有使用到字典這個數據結構,字典底層實現使用哈希表的結構。字典中主要掌握它的漸進式hash,結構源碼位置位于dict.h文件中

 

4.1 字典結構

typedef struct dict {

dictType *type;

void *privdata;

dictht ht[2];

long rehashidx;

} dict;

 

屬性名稱作用含義

type 自定義一些操作的方法,拷貝key、拷貝value、銷毀key、銷毀value等

privdate創建dict時傳入,用于某些特殊操作回傳給調用函數

ht [0]用于數據存儲,[1]用于rehash變更

rehashidx表示rehash進度,-1表示未進行rehash

4.2 哈希表結構

typedef struct dictht {

dictEntry **table;

unsigned long size;

unsigned long sizemask;

unsigned long used;

} dictht;

 

屬性名稱作用含義

tablehash表節點

size hash表大小

sizemark哈希表大小掩碼,計算索引值。大小等于size -1

used哈希表已有的節點數量

4.3 哈希表節點結構

typedef struct dictEntry{

void *key;

union{

void *val;

uint64_tu64;

int64_ts64;

}v;

struct dictEntry *next;

}dictEntry

 

屬性名稱作用含義

key 保存數據的key值

union值對象,可以是一個對象,因為有個對象空指針或者是uint64、int64的整數

next 指向下一個Entry的指針,形成一個鏈表

4.4 漸進式rehash

字典的rehash操作數據量過大時并不是一次完成,而是分批次逐漸進行

rehash過程中新插入字典數據放在[1]哈希表中,并將原[0]中數據重新進行hash計算加入[1]中。讀操作將會讀取[0]、[1]兩個哈希表

rehash過程標志使用dict中屬性rehashidx標識

rehash采用cow寫時復制技術

五:Intset

redis中常用對象set會用到的底層數據結構

 

5.1 整數集合特點

1:內容全是數字

2:內存連續

3:元素有序,不可重復

5.2 Intset結構

typedef struct intset{

uint32_t encoding;

uint32_t length;

int8_t contents[];

}intset;

 

屬性名稱作用含義

encoding整數集合可以有三種編碼方式16、32、64

length整數集合數組中保存的元素個數

contents從小到大保存的整數集合中的元素

六:ZipList

zset中用到的一個數據結構,性能可以和紅黑樹、AVL樹不相上下

Redis底層數據結構解密

 

6.1 跳躍表結構

typedef struct zskiplist{

//表頭結點和尾節點

structz skiplistNode *heade,*tail;

//表中節點數量

unsigned long length;

//表中層數最大的節點的層數

int level;

}zskiplist;

 

屬性名稱作用含義

head跳躍表頭結點

tail 跳躍表尾節點

length跳躍表節點數量,表頭結點不記錄在里面

level 跳躍表最大層數,不記錄表頭節點

6.2 跳躍表節點

typedof struct zskiplistNode{

//層

struct zskiplistNode{

//前進指針

struct zskiplistNode *forward;

//跨度

unsihned int span;

}level[];

//后退指針

struct zskiplistNode *backward;

//分值

double score;

//成員對象

robj *obj;

}zsikplistNode;

 

屬性名稱作用含義

zskiplistNode集合記錄該節點位于的每一層

forward 每一層節點對應的下一個節點

span 距離下一個節點需要跨越的層數

backward 后退指針

score 節點分數值

obj 跳躍表節點保存的對象

分享到:
標簽:Redis
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定