高級程序員知識學習(Redis相關知識)

Redis基本五大數據結構,

它可以支持五種基本數據類型,分別是字符串(string),列表(list),集合(set),有序集合(zset)以及哈希(hash)

Redis爲什麼這麼快的原因是:

讀寫性能優異, Redis能讀的速度是110000次/s,寫的速度是81000次/s。

支持數據持久化,支持AOF和RDB兩種持久化方式。

支持事務,Redis的所有操作都是原子性的,Redis還支持對幾個操作合併後的原子性執行。

數據結構豐富,除了支持string類型的value外還支持hash、set、zset、list等數據結構。

支持主從複製,主機會自動將數據同步到從機,可以進行讀寫分離。

那你能說說 Redis 是單線程的,爲什麼還能這麼快嗎?

Redis 完全基於內存,絕大部分請求是純粹的內存操作,非常迅速,數據存在內存中,類似於 HashMap,HashMap 的優勢就是查找和操作的時間複雜度是 O(1)。

數據結構簡單,對數據操作也簡單。

採用單線程,避免了不必要的上下文切換和競爭條件,不存在多線程導致的 CPU 切換不用去考慮各種鎖的問題,不存在加鎖釋放鎖操作,沒有死鎖問題導致的性能消耗。

使用多路複用 IO 模型,非阻塞 IO。

 

  1. Redis數據結構底層實現

String類型:SDS的結構體

簡單動態字符串(SDS):字符串作爲redis中最常見的數據結構,所有鍵值對的鍵,字符串對象的值底層都是由簡單動態字符串實現的。在redis中,它並未使用C語言中的字符串,而是自己實現了一種叫做SDS的數據結構,它的結構表示如下:

struct sdshdr{

//記錄buf數組中已使用字節的長度

int len;

//記錄buf數組中剩餘空間的長度

int free;

//字節數組,用於存儲字符串

char buf[];

};

 

List類型:雙頭鏈表

鏈表提供了節點重排以及節點順序訪問的能力,redis中的列表對象主要是由壓縮列表和雙端鏈表實現。

type struct list{

//表頭節點

listNode *head;

//表尾節點

listNode *tail;

//包含的節點總數

unsigned long len;

//一些操作函數 dup free match...

};

 其中每個節點都有一個prev指針和一個next指針,而節點中的value則是列表對象具體的值。

type struct ziplist{

//整個壓縮列表的字節數

uint32_t zlbytes;

//記錄壓縮列表尾節點到頭結點的字節數,直接可以求節點的地址

uint32_t zltail_offset;

//記錄了節點數,有多種類型,默認如下

uint16_t zllength;

//節點

列表節點 entryX;

 Set類型

集合對象的編碼可以是整數集合(intset)或者字典(hashtable)。整數集合結構如下:

typedef struct intset{
//編碼方式
uint32_t encoding;
//元素數量
uint32_t length;
//存儲元素的數組
int8_t contents[];
}

字典的結構如下:

typedef struct dict{
//類型特定函數
dictType *type;
//哈希表 兩個,一個用於實時存儲,一個用於rehash
dictht ht[2];
//rehash索引 數據遷移時使用
unsigned rehashidx;
}

而哈希表的結構如下

typedef struct dictht{
//哈希表數組
dictEntry **table;
//哈希表大小
unsigned long size;
//哈希表掩碼,總是等於size-1,存儲時計算索引值
unsigned long sizemask;
//已有元素數量
unsigned long used;
}

 

有序集合的編碼可以是壓縮列表(ziplist)或者跳躍表(skiplist)

跳躍表的結構如下:

typedef struct zskiplist{
//跳躍表的頭結點
zskiplistNode header;
//尾節點
zskiplistNode tail;
//跳躍表中層數最大的節點的層數(不包括頭結點)
unsigned long level;
//跳躍表長度(不包括頭節點)
unsigned int length;

哈希對象的編碼可以是壓縮列表(ziplist)或者字典(hashtable),當哈希對象保存的所有鍵值對的鍵和值得長度都小於64字節並且元素數量小於512個時使用ziplist,否則使用hashtable。使用ziplist時,是依次將鍵和值壓入鏈表之中,兩者相鄰。使用hashtable是是將鍵值對存於dictEntry之中 。

Redis的淘汰機制:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章