1. 程式人生 > 實用技巧 >Redis 閱讀筆記-動態字串

Redis 閱讀筆記-動態字串

簡單動態字串(simple dynamic string)抽象模型, 簡稱SDS

SDS在Redis的應用場景

1、用來儲存資料的字串值
2、被用做緩衝區,如AOF模組的AOF緩衝區,客戶端輸入的緩衝區

SDS的定義

// sds.h/sdshdr結構表示的SDS值:
struct sdshdr {
    //所儲存的字串長度
    int len;
    //陣列中未使用位元組的長度
    int free;
    //位元組陣列,用於儲存字串
    char buf[];
}

SDS示例如下圖:

SDS相比與C字串的區別

1、獲取C字串長度,程式需遍歷整個字串,操作複雜度為O(N), 而SDS的在len屬性中記錄SDS本身的長度,獲取SDS字串的長度複雜度僅為O(1)。
2、SDS字串可以杜絕緩衝區溢位。這是因為SDS API對SDS進行修改時,API會先簡稱SDS的空間是否滿足所需修改的要求,若不滿足,會自動將SDS擴充套件所需的大小,然後再執行修改操作。
3、減少字串修改帶來的記憶體重分配次數。SDS通過未使用空間解除了字串長度和底層陣列長度的關聯:在SDS中,buf陣列長度不一定是字串加一, 數組裡面可以包含未使用的位元組,而這些位元組的數量有SDS的free屬性記錄。
通過未使用空間,SDS實現了空間預分配和惰性空間釋放兩種優化策略。
1)空間預分配
SDS對空間進行擴充套件時,程式不僅為SDS分配修改,還會為SDS分配額外未使用的空間。分配未使用空間數量的公式如下:

若SDS的長度(len屬性的值)小於1M,程式分配和len屬性同樣大小的未使用空間,此時len的值和free屬性的值相同。
若SDS修改後,SDS的長度大於1M,那麼程式將會分配1M未使用空間
在擴充套件SDS空間之前,SDS API會先檢查未使用空間是否足夠,如果足夠,API會直接使用未使用空間,而無需執行記憶體重分配。通過這種預分配策略,SDS將連續增長N次字串所需的記憶體分配次數從必定N次降低為最多N次。

2)惰性空間釋放
惰性空間釋放用於優化SDS字串縮短操作。當SDS API需要縮短SDS儲存的字串,程式並不使用記憶體重分配來回收縮短後多出來的位元組,而是使用free屬性,將這些位元組記錄下來,方便將來在用。

4、二進位制安全的
C字串必須符合某中編碼,並且除了字串末尾外,字串不能包含空字元,最先讀入的空字元被誤認為字串的結尾,這使C字串只能儲存文字資料,不能儲存圖片,音訊,視訊,壓縮檔案這類的二進位制資料。
SDS的API都是二進位制安全的,所有的SDS API都會處理二進位制方式來處理SDS存放在buf數組裡的資料,程式不會對資料做任何限制,過濾或假設。
5、SDS相容部分C字串函式。