《Redis設計與實現》讀書筆記一

《Redis設計與實現》讀書筆記一

Redis是什麼

Redis(全稱:Remote Dictionary Server 遠程字典服務)是一個開源的使用ANSI C語言編寫、支持網絡、可基於內存亦可持久化的日誌型、Key-Value數據庫,並提供多種語言的API。 ——百度百科

Redis的常見應用場景

1.做緩存

Redis讀寫性能優異,且支持事務,在使用時能保證數據的一致性。

2.應對海量數據和高併發

3.消息隊列

消息隊列,顧名思義,就是用來存放消息的容器,多用於分佈式系統,生產者產生消息,消費者消費消息。使用消息隊列可以通過異步處理緩衝高併發事件,比如大量數據庫寫入事件,可以先存入消息隊列中,而後由數據庫異步執行。

第二章 簡單動態字符串

雖然Redis是用C語言編寫,但它並沒有直接使用C語言傳統的字符串表示,而是自己構建了一種叫做簡單動態字符串(SDS)的抽象類型作爲Redis的默認字符串表示。Redis只在使用靜態字符串時才使用C語言的字符串。

來看實現:

struct sdshdr{
    //記錄buf數組中已使用字節的數量(不算最後的'\0')
    int len;
    //記錄buf數組中未使用字節的數量
    int free;
    //字節數組,用於保存字符串
    char buf[]
}

在這裏插入圖片描述

圖中,free爲0,len爲5.

底層採用C字符串的好處是可以直接使用一部分C語言字符串函數庫的函數,而無須爲SDS編寫專門的打印函數。

SDS比C字符串更加安全:

1.空間預分配

當SDS的API對一個SDS進行修改,並且需要對SDS進行空間擴展時,程序不僅會爲SDS分配修改所需的空間,還會爲SDS分配額外的未使用的空間。

預分配公式:(1)若修改後SDS的長度小於1MB,那麼程序將分配和len屬性同樣大小的未使用空間。(2)若修改後的SDS長度大於1MB,那麼程序將分配1MB的未使用空間。

2.惰性空間釋放

當SDS的API需要縮短SDS保存的字符串時,程序並不立即使用內存重分配來回收字節,而是使用free屬性將這些字節記錄起來,並等待使用。

思考:如果有很多很長的SDS,在假性釋放後,會不會造成浪費?

答:SDS也提供了相應的API,可以真正的釋放SDS未使用的空間。

二進制安全

二進制安全是指對所有二進制文件一視同仁,不對其中某些01序列賦予特殊意義,防止損壞二進制文件。

SDS是二進制安全的,而C字符串不是。例如“Redis Cluster”,C字符串所用的函數只會識別到Redis。

總結

比起C字符串,SDS具有以下優點:

1.常數複雜度獲取字符串長度。

2.杜絕緩衝區溢出。

3.減少修改字符串長度時所需的內存重分配次數。

4.二進制安全。

5.兼容部分C字符串函數。

在這裏插入圖片描述

第三章 鏈表

Redis中,鏈表健、發佈與訂閱、慢查詢、監視器等功能也用到了鏈表。

來看實現:

typedef struct listNode{
    //前置節點
    struct listNode *prev;
    //後置節點
    struct listNode *next;
    //節點的值
    void *value;
}listNode

Redis實現了list結構來儲存鏈表,使得一些常用操作的時間複雜度控制在O(1).

typedef struct list{
    //表頭節點
    listNode *head;
    //表尾節點
    listNode *tail;
    //節點數量
    unsigned long len;
    //節點值複製函數
    void *(*dup)(void *ptr);
    //節點釋放函數
    void (*free)(void *ptr);
    //節點比較函數
    int (*match)(void *ptr,void *key);
}

Redis鏈表特點

1.是無環鏈表。

2.Redis的鏈表可以用於保存各種不同類型的值。

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