參考書本 《Redis設計與實現》
SDS的概念
Redis沒有直接使用c語言中的字符串,而是自己定義了一種簡單動態字符串(SDS)的抽象類型,SDS作爲redis的默認字符串表示
SDS的結構
SDS的由三部分組成,分別爲:保存字符串長度的int len,保存未使用字節數量的int free,存儲字符串的字節數組。如下:
struct sdshdr{
int len; //buf中已經使用的字節長度,即字符串長度
int free; //buf中的未使用的字節長度
char buf[]; //存儲字符串的字節數組
}
SDS與 c字符串比較
SDS中的buf[]也是使用‘\0’表示字符串結尾的,這樣可以部分重用c語言的字符串操作函數
SDS中記錄了字符串長度,所以獲取字符串長度的時間負載度爲o(1)
c中的字符串不記錄自身長度帶來的問題是“緩衝區溢出”,因爲需要手動分配足夠多的空間,sds可以通過載入之前額檢查(free是不是足夠大),確定如何調節緩衝區大小
sds是二進制安全的,雖然數據庫大多數時候適用於存儲文本的,但是存儲二進制數據的時候也不少,redis所有關於sds的函數,都是以二進制方式處理buf[]中的數據,所以我們稱之爲字節數組;而c的字符串中只能保存文本數據(因爲用‘\0’標誌結尾)。
針對c字符串的操作一定注意是否需要重新分配空間,比如拼接可能會造成“緩衝區溢出”,截斷可能會造成“內存泄漏”;SDS針對上述問題的解決方法是“空間預分配”“惰性空間釋放”。(注:redis經常用於數據頻繁修改的場合,因此每次內存重分配,損耗太大)。
1、空間預分配
當sds的緩衝區空間不足,需要擴展的時候,除了分配必須的部分,還會多分配一些,規則如下:
len<1MB,free = len
len>=1MB,free = 1MB
2、惰性空間釋放
sds中的字符串縮短的時候,並不立即重新分配空間,以回收縮短部分,而是把縮短部分歸入free中。
sds提供真正釋放sds的未使用空間的API