偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Redis中五大數(shù)據(jù)結(jié)構(gòu)的底層實(shí)現(xiàn)

運(yùn)維 數(shù)據(jù)庫(kù)運(yùn)維 Redis
下面讓我們來(lái)詳細(xì)介紹一下redis中五大數(shù)據(jù)結(jié)構(gòu)的底層實(shí)現(xiàn)。讓我們一起來(lái)看看吧。

一、概述

Redis是一個(gè)開(kāi)源的使用ANSI C語(yǔ)言編寫(xiě)、遵守BSD協(xié)議、支持網(wǎng)絡(luò)、可基于內(nèi)存亦可持久化的日志型、Key-Value數(shù)據(jù)庫(kù),與Memcached類似,卻優(yōu)于Memcached的一個(gè)高性能的key-value數(shù)據(jù)庫(kù)。下面讓我們來(lái)詳細(xì)介紹一下redis中五大數(shù)據(jù)結(jié)構(gòu)的底層實(shí)現(xiàn)。

二、簡(jiǎn)單動(dòng)態(tài)字符串

1、概述

Redis是一個(gè)開(kāi)源的使用ANSI C語(yǔ)言編寫(xiě)的key-value 數(shù)據(jù)庫(kù),我們可能會(huì)較為主觀的認(rèn)為 Redis 中的字符串就是采用了C語(yǔ)言中的傳統(tǒng)字符串表示,但其實(shí)不然,Redis沒(méi)有直接使用C語(yǔ)言傳統(tǒng)的字符串表示,而是自己構(gòu)建了一種名為簡(jiǎn)單動(dòng)態(tài)字符串(simple dynamic string SDS)的抽象類型,并將SDS用作Redis的默認(rèn)字符串表示:redis>SET msg "hello world"

SDS 定義: 

  1. struct sdshdr{  
  2.      //記錄buf數(shù)組中已使用字節(jié)的數(shù)量  
  3.      //等于 SDS 保存字符串的長(zhǎng)度  
  4.      int len;  
  5.      //記錄 buf 數(shù)組中未使用字節(jié)的數(shù)量  
  6.      int free;  
  7.      //字節(jié)數(shù)組,用于保存字符串  
  8.      char buf[];  

圖片來(lái)源:《Redis設(shè)計(jì)與實(shí)現(xiàn)》

我們看上面對(duì)于 SDS 數(shù)據(jù)類型的定義:

  •  len 保存了SDS保存字符串的長(zhǎng)度
  •  buf[] 數(shù)組用來(lái)保存字符串的每個(gè)元素
  •  free j記錄了 buf 數(shù)組中未使用的字節(jié)數(shù)量  

2、與C語(yǔ)言相比較 

一般來(lái)說(shuō),SDS 除了保存數(shù)據(jù)庫(kù)中的字符串值以外,SDS 還可以作為緩沖區(qū)(buffer):包括 AOF 模塊中的AOF緩沖區(qū)以及客戶端狀態(tài)中的輸入緩沖區(qū)。后面在介紹Redis的持久化時(shí)會(huì)進(jìn)行介紹。

三、鏈表

1、概述

鏈表提供了高效的節(jié)點(diǎn)重排能力,以及順序性的節(jié)點(diǎn)訪問(wèn)方式,并且可以通過(guò)增刪節(jié)點(diǎn)來(lái)靈活地調(diào)整鏈表的長(zhǎng)度。

鏈表在Redis 中的應(yīng)用非常廣泛,比如列表鍵的底層實(shí)現(xiàn)之一就是鏈表。當(dāng)一個(gè)列表鍵包含了數(shù)量較多的元素,又或者列表中包含的元素都是比較長(zhǎng)的字符串時(shí),Redis 就會(huì)使用鏈表作為列表鍵的底層實(shí)現(xiàn)。

每個(gè)鏈表節(jié)點(diǎn)使用一個(gè)listNode結(jié)構(gòu)表示(adlist.h/listNode): 

  1. typedef  struct listNode{  
  2.        //前置節(jié)點(diǎn)  
  3.        struct listNode *prev;  
  4.        //后置節(jié)點(diǎn)  
  5.        struct listNode *next;  
  6.        //節(jié)點(diǎn)的值  
  7.        void *value;    
  8. }listNode 

鏈表的數(shù)據(jù)結(jié)構(gòu): 

  1. typedef struct list{  
  2.       //表頭節(jié)點(diǎn)  
  3.      listNode *head;  
  4.      //表尾節(jié)點(diǎn)  
  5.      listNode *tail;  
  6.      //鏈表所包含的節(jié)點(diǎn)數(shù)量  
  7.      unsigned long len;  
  8.      //節(jié)點(diǎn)值復(fù)制函數(shù)  
  9.      void (*free) (void *ptr);  
  10.      //節(jié)點(diǎn)值釋放函數(shù)  
  11.      void (*free) (void *ptr);  
  12.      //節(jié)點(diǎn)值對(duì)比函數(shù)  
  13.      int (*match) (void *ptr,void *key);  
  14. }list; 

組成結(jié)構(gòu)圖

2、Redis鏈表特性

  •  雙端:鏈表具有前置節(jié)點(diǎn)和后置節(jié)點(diǎn)的引用,獲取這兩個(gè)節(jié)點(diǎn)時(shí)間復(fù)雜度都為O(1)。
  •  無(wú)環(huán):表頭節(jié)點(diǎn)的 prev 指針和表尾節(jié)點(diǎn)的 next 指針都指向 NULL,對(duì)鏈表的訪問(wèn)都是以 NULL 結(jié)束?!?/li>
  •  帶鏈表長(zhǎng)度計(jì)數(shù)器:通過(guò) len 屬性獲取鏈表長(zhǎng)度的時(shí)間復(fù)雜度為 O(1)。
  •  多態(tài):鏈表節(jié)點(diǎn)使用 void* 指針來(lái)保存節(jié)點(diǎn)值,可以保存各種不同類型的值。

四、字典

1、概述

字典又稱為符號(hào)表或者關(guān)聯(lián)數(shù)組、或映射(map),是一種用于保存鍵值對(duì)的抽象數(shù)據(jù)結(jié)構(gòu)。字典中的每一個(gè)鍵 key 都是唯一的,通過(guò) key 可以對(duì)值來(lái)進(jìn)行查找或修改。C 語(yǔ)言中沒(méi)有內(nèi)置這種數(shù)據(jù)結(jié)構(gòu)的實(shí)現(xiàn),所以字典依然是 Redis自己構(gòu)建的。

哈希表結(jié)構(gòu)定義: 

  1. typedef struct dictht{  
  2.      //哈希表數(shù)組  
  3.      dictEntry **table;  
  4.      //哈希表大小  
  5.      unsigned long size;  
  6.      //哈希表大小掩碼,用于計(jì)算索引值  
  7.      //總是等于 size-1  
  8.      unsigned long sizemask;  
  9.      //該哈希表已有節(jié)點(diǎn)的數(shù)量  
  10.      unsigned long used;  
  11. }dictht 

哈希表是由數(shù)組 table 組成,table 中每個(gè)元素都是指向 dict.h/dictEntry 結(jié)構(gòu),dictEntry 結(jié)構(gòu)定義如下: 

  1. typedef struct dictEntry{  
  2.      //鍵  
  3.      void *key;  
  4.      //值  
  5.      union{  
  6.           void *val;  
  7.           uint64_tu64;  
  8.           int64_ts64;  
  9.      }v;  
  10.      //指向下一個(gè)哈希表節(jié)點(diǎn),形成鏈表  
  11.      struct dictEntry *next; 
  12. }dictEntry 

key 用來(lái)保存鍵,val 屬性用來(lái)保存值,值可以是一個(gè)指針,也可以是uint64_t整數(shù),也可以是int64_t整數(shù)。

注意這里還有一個(gè)指向下一個(gè)哈希表節(jié)點(diǎn)的指針,我們知道哈希表最大的問(wèn)題是存在哈希沖突,如何解決哈希沖突,有開(kāi)放地址法和鏈地址法。這里采用的便是鏈地址法,通過(guò)next這個(gè)指針可以將多個(gè)哈希值相同的鍵值對(duì)連接在一起,用來(lái)解決哈希沖突。

五、跳躍表

1、概述

跳躍表(skiplist)是一種有序數(shù)據(jù)結(jié)構(gòu),它通過(guò)在每個(gè)節(jié)點(diǎn)中維持多個(gè)指向其他節(jié)點(diǎn)的指針,從而達(dá)到快速訪問(wèn)節(jié)點(diǎn)的目的。跳躍表是一種隨機(jī)化的數(shù)據(jù),跳躍表以有序的方式在層次化的鏈表中保存元素,效率和平衡樹(shù)媲美 ——查找、刪除、添加等操作都可以在對(duì)數(shù)期望時(shí)間下完成,并且比起平衡樹(shù)來(lái)說(shuō),跳躍表的實(shí)現(xiàn)要簡(jiǎn)單直觀得多。

Redis 只在兩個(gè)地方用到了跳躍表,一個(gè)是實(shí)現(xiàn)有序集合鍵,另外一個(gè)是在集群節(jié)點(diǎn)中用作內(nèi)部數(shù)據(jù)結(jié)構(gòu)。

Redis中跳躍表節(jié)點(diǎn)定義如下: 

  1. typedef struct zskiplistNode {  
  2.      //層  
  3.      struct zskiplistLevel{  
  4.            //前進(jìn)指針  
  5.            struct zskiplistNode *forward;  
  6.            //跨度  
  7.            unsigned int span;  
  8.      }level[];  
  9.      //后退指針  
  10.      struct zskiplistNode *backward;  
  11.      //分值  
  12.      double score;  
  13.      //成員對(duì)象  
  14.      robj *obj;  
  15. } zskiplistNode 

多個(gè)跳躍表節(jié)點(diǎn)構(gòu)成一個(gè)跳躍表: 

  1. typedef struct zskiplist{  
  2.      //表頭節(jié)點(diǎn)和表尾節(jié)點(diǎn)  
  3.      structz skiplistNode *header, *tail;  
  4.      //表中節(jié)點(diǎn)的數(shù)量  
  5.      unsigned long length;  
  6.      //表中層數(shù)最大的節(jié)點(diǎn)的層數(shù)  
  7.      int level;  
  8. }zskiplist; 
  •  header和tail指針?lè)謩e指向跳躍表的表頭和表尾節(jié)點(diǎn);
  •  length屬性記錄節(jié)點(diǎn)的數(shù)量;
  •  level屬性記錄層數(shù)最高的幾點(diǎn)的層數(shù)量;
  •  下圖分別展示了完整的跳躍表和單個(gè)節(jié)點(diǎn)的詳細(xì)結(jié)構(gòu)圖:

2、特性

跳表具有如下性質(zhì):

  •  由很多層結(jié)構(gòu)組成
  •  每一層都是一個(gè)有序的鏈表
  •  最底層(Level 1)的鏈表包含所有元素
  •  如果一個(gè)元素出現(xiàn)在 Level i 的鏈表中,則它在 Level i 之下的鏈表也都會(huì)出現(xiàn)。
  •  每個(gè)節(jié)點(diǎn)包含兩個(gè)指針,一個(gè)指向同一鏈表中的下一個(gè)元素,一個(gè)指向下面一層的元素。

六、整數(shù)集合

1、概述

《Redis 設(shè)計(jì)與實(shí)現(xiàn)》 中這樣定義整數(shù)集合:“整數(shù)集合是集合建的底層實(shí)現(xiàn)之一,當(dāng)一個(gè)集合中只包含整數(shù),且這個(gè)集合中的元素?cái)?shù)量不多時(shí),redis就會(huì)使用整數(shù)集合intset作為集合的底層實(shí)現(xiàn)。”

我們可以這樣理解整數(shù)集合,他其實(shí)就是一個(gè)特殊的集合,里面存儲(chǔ)的數(shù)據(jù)只能夠是整數(shù),并且數(shù)據(jù)量不能過(guò)大。 

  1. typedef struct intset{  
  2.      //編碼方式  
  3.      uint32_t encoding;  
  4.      //集合包含的元素?cái)?shù)量  
  5.      uint32_t length;  
  6.      //保存元素的數(shù)組  
  7.      int8_t contents[];  
  8. }intset; 

我們觀察一下一個(gè)完成的整數(shù)集合結(jié)構(gòu)圖:   

  • encoding:用于定義整數(shù)集合的編碼方式
  • length:用于記錄整數(shù)集合中變量的數(shù)量
  • contents:用于保存元素的數(shù)組,雖然我們?cè)跀?shù)據(jù)結(jié)構(gòu)圖中看到,intset將數(shù)組定義為int8_t,但實(shí)際上數(shù)組保存的元素類型取決于encoding

2、特性

  •  整數(shù)集合是集合建的底層實(shí)現(xiàn)之一
  •  整數(shù)集合的底層實(shí)現(xiàn)為數(shù)組,這個(gè)數(shù)組以有序,無(wú)重復(fù)的范式保存集合元素,在有需要時(shí),程序會(huì)根據(jù)新添加的元素類型改變這個(gè)數(shù)組的類型
  •  升級(jí)操作為整數(shù)集合帶來(lái)了操作上的靈活性,并且盡可能地節(jié)約了內(nèi)存2

    整數(shù)集合只支持升級(jí)操作,不支持降級(jí)操作

七、壓縮列表

1、概述

壓縮列表是列表鍵和哈希鍵的底層實(shí)現(xiàn)之一。當(dāng)一個(gè)列表鍵只包含少量列表項(xiàng),并且每個(gè)列表項(xiàng)要么就是小整數(shù),要么就是長(zhǎng)度比較短的字符串,那么Redis 就會(huì)使用壓縮列表來(lái)做列表鍵的底層實(shí)現(xiàn)。

一個(gè)壓縮列表的組成如下:  

  •  zlbytes:用于記錄整個(gè)壓縮列表占用的內(nèi)存字節(jié)數(shù)
  •  zltail:記錄要列表尾節(jié)點(diǎn)距離壓縮列表的起始地址有多少字節(jié)
  •  zllen:記錄了壓縮列表包含的節(jié)點(diǎn)數(shù)量
  •  entryX:要說(shuō)列表包含的各個(gè)節(jié)點(diǎn)
  •  zlend:用于標(biāo)記壓縮列表的末端

2、特性

  •  壓縮列表是一種為了節(jié)約內(nèi)存而開(kāi)發(fā)的順序型數(shù)據(jù)結(jié)構(gòu)
  •  壓縮列表被用作列表鍵和哈希鍵的底層實(shí)現(xiàn)之一
  •  壓縮列表可以包含多個(gè)節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)可以保存一個(gè)字節(jié)數(shù)組或者整數(shù)值
  •  添加新節(jié)點(diǎn)到壓縮列表,可能會(huì)引發(fā)連鎖更新操作。 

 

責(zé)任編輯:龐桂玉 來(lái)源: DBAplus社群
相關(guān)推薦

2023-10-18 15:17:24

Redis數(shù)據(jù)結(jié)構(gòu)Java

2017-01-15 10:56:57

大數(shù)據(jù)非結(jié)構(gòu)化過(guò)期

2019-06-21 15:20:05

Redis數(shù)據(jù)結(jié)構(gòu)數(shù)據(jù)庫(kù)

2012-08-13 14:27:31

大數(shù)據(jù)

2013-01-10 10:30:32

大數(shù)據(jù)預(yù)測(cè)Hadoop

2019-10-29 08:59:16

Redis底層數(shù)據(jù)

2021-09-08 17:17:43

大數(shù)據(jù)智慧城市大數(shù)據(jù)應(yīng)用

2022-03-14 09:46:10

Hadoop大數(shù)據(jù)

2020-11-04 07:34:02

Redis數(shù)據(jù)類型

2025-01-14 08:00:00

RedisList數(shù)據(jù)結(jié)構(gòu)

2025-01-15 12:20:41

2015-10-20 09:42:36

醫(yī)療大數(shù)據(jù)應(yīng)用

2019-06-12 22:51:57

Redis軟件開(kāi)發(fā)

2019-04-17 15:35:37

Redis數(shù)據(jù)庫(kù)數(shù)據(jù)結(jié)構(gòu)

2022-08-08 10:20:19

數(shù)據(jù)安全首席信息安全官

2019-05-27 23:21:47

大數(shù)據(jù)云遷移企業(yè)

2015-08-26 10:46:16

大數(shù)據(jù)

2019-09-27 08:53:47

Redis數(shù)據(jù)C語(yǔ)言

2024-05-28 11:44:54

Redis數(shù)據(jù)結(jié)構(gòu)數(shù)據(jù)庫(kù)

2012-02-15 09:29:58

大數(shù)據(jù)IT
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)