Redis 並未直接使用 C 語言傳統的以空字元結尾的字串,而是自行實現了一套名為簡單動態字符串(Simple Dynamic String,SDS)的結構。這種設計不僅提升了效能,更解決了 C 字串的諸多缺陷。
struct sdshdr {
int len; // 已使用長度
int free; // 剩餘可用空間
char buf[]; // 實際資料緩衝區
};
len 欄位直接讀取,無需遍歷計算。buf 儲存字節陣列,配合 len 判斷結尾,可儲存包含空字元的任意二進制資料。為減少記憶體重分配次數,Redis 採用「空間預分配」:
2 × 新長度 + 1 位元組(含結尾符)。新長度 + 1 MB 位元組。範例演示:
狀態 0:len=5, free=4, buf="hello\0xxxx"
執行 sdscat(s, "redis") 後 → 狀態 1:len=10, free=10, buf="helloredis\0..."(發生一次擴容)
再次執行 sdscat(s, "redis") → 狀態 2:len=15, free=5, buf="helloredisredis\0..."(利用預留空間,無需擴容)
縮短字串時(如 sdstrim(s, "re")),Redis 僅更新 len 和 free,不實際歸還記憶體(狀態 3:len=11, free=9)。這避免了縮容時的重分配開銷,並為未來擴充預留空間。若需真正釋放,可呼叫 sdsfree。
C 字串以 \0 判斷結尾,遇嵌入空字元會被截斷。SDS 使用 len 記錄長度,buf 純粹作為字節容器,完美支援圖片、序列化物件等二進制資料。