目錄
1 Redis基礎數據結構
鍵對應的數據類型只有一種:
- 字符串
鍵對應的值包含五種數據類型:
- 字符串
- 列表
- 哈希表
- 集合
- 有序集合
2 底層數據結構詳解
主要介紹以上五種數據類型底層的數據結構
2.1 簡單動態字符串(SDS)
全稱是Simple Dynamic String,對C語言中的字符數組做了封裝,使用len字段標誌buf數組中的已用空間,使用free字段標誌buf中的未使用空間。
struct sdshdr {
// 記錄 buf 數組中已使用字節的數量
// 等於 SDS 所保存字符串的長度
int len;
// 記錄 buf 數組中未使用字節的數量
int free;
// 字節數組,用於保存字符串
// buf數組的真實長度是len+free
char buf[];
};
2.1.1 SDS空間預分配策略
SDS內存空間管理策略不同於C語言的字符數組。修改字符串時,系統不僅爲SDS的buf申請相應空間存儲字符串,還會額外申請未使用的空間用於未來使用。
- 目標字符串小於1MB(即len),申請的內存空間buf是目標字符串的空間,額外加上相同的未使用空間。即buf長度是目標字符串的兩倍,這時buf等於len
- 目標字符串大於1MB,則申請的內存空間buf是目標字符串的大小,額外加上1MB空間。即free大小是1MB。
2.1.2 SDS空間釋放策略
SDS內存空間惰性釋放,不是直接釋放buf,而是修len以及free,標誌buf中的已用空間以及可用空間。這樣方便未來使用。
2.1.3 SDS與字符數組區別
SDS | 字符數組 | |
---|---|---|
獲取字符串長度的時間複雜度 | O(1) | O(n) |
修改字符串時,緩衝區溢出風險 | SDS自動檢查空間是否足夠,不夠就自動分配 | 手動檢查/分配空間 |
修改字符串時,內存分配次數 | 預分配空間,最多分配n次 | 每次修改字符串,都要分配空間 |
修改字符串時,內存釋放 | 不釋放空間,只更free以及len,方便未來使用 | 釋放空間 |
2.2 鏈表
Redis種涉及到的鏈表都是雙向鏈表,Redis設計的初衷是首先考慮訪問速度,雙向鏈表會佔用較多的空間(相比較於單向鏈表)
2.2 哈希表
2.3 跳錶
跳錶融合了數組以及鏈表的優點,方便增刪改,也可以在log(n)
的平均時間複雜度內查找數據/區間查找
3 數據結構組合
3.1 字符串
Redis中的字符串使用SDS作爲字符串的實現,沒使用C語言自己的字符數組。