不瘦原來對redis也是有個大概的瞭解(就你知道的多), 但是最近和大神聊天的過程中才明白自己知道的簡直就是雞毛蒜皮(讓你得瑟),所以不瘦打算從頭在捋一遍,順便把過程也記錄下來,如果能給大家在學習redis的道路上提供一條清晰的線索,不瘦胖也瞑目了. 我們知道redis沒有直接使用C語言中的字元串, ...
不瘦原來對redis也是有個大概的瞭解(就你知道的多), 但是最近和大神聊天的過程中才明白自己知道的簡直就是雞毛蒜皮(讓你得瑟),所以不瘦打算從頭在捋一遍,順便把過程也記錄下來,如果能給大家在學習redis的道路上提供一條清晰的線索,不瘦胖也瞑目了.
我們知道redis沒有直接使用C語言中的字元串,而是定義了簡單動態字元串(simple dynamic string,SDS)的抽象類型, 並將 SDS 用作 Redis 的預設字元串表示。其中SDS數據結構如下:
struct sdshdr { int len; // len表示buf中存儲的字元串的長度 int free; // free表示buf中空閑空間的長度 char buf[]; // buf用於存儲字元串內容
};
可以看到,就是將一個字元數組和兩個整型變數封裝在結構體中,但是這一封裝加上一些看似簡單的方法(大道至簡)就為SDS增加了很多特性:
- 二進位安全
和C語言字元串只能某種編碼(如ASCII),並且出結尾不能有'\0'字元相比,SDS也可以存儲像圖片,音頻,視頻這樣的二進位數據
- 字元串長度計算,時間複雜度為O(1)
因為在SDS結構體中存儲了len,計算長度時直接返回即可(以空間換時間),而C語言要計算字元串長度時間複雜度為O(n)
- 杜絕緩衝區溢出
我們知道在C語言拼接字元串時,如果超出原字元串申請的記憶體大小就會導致緩衝區溢出,而SDS的空間分配策略直接避免了溢出的可能性:當對SDS修改時,會先檢查剩餘空間是否 滿足(free變數的作用),如果不滿足,則進行自動擴容.
- 減少修改帶來記憶體分配次數
redis作為資料庫經常被用於速度要求嚴苛、數據被頻繁修改的場合, 如果每次修改長度都需要執行一次記憶體重分配的話, 那麼光是執行記憶體重分配的時間就會占去修改所用時間的 一大部分, 如果這種修改頻繁地發生的話, 可能還會對性能造成影響。
為了應對這種應用場景,redis採取了兩種策略: 增加長度時空間預分配(每次多申請點),減少長度時空間惰性釋放(只改free的大小,不實際釋放空間)
註意事項:
- SDS作為key時長度不能超過512MB
參考:
《Redis設計與實現》
這裡是老瘦家的兒子,如需轉載請聲明,我替老瘦感謝你。