Redis採用一種名爲簡單動態字符串(simple dynamic string,SDS)的數據結構作爲默認字符串的表示。數組
而且在Redis中,只有常量採用默認C語言字符串表示,若是一個字符串是可變的就會採用SDS。 那麼,首先讓咱們看下SDS數據結構(摘自Redis設計與實現一書)安全
struct sdshdr { // 記錄buf數組中已使用字節的數量 // 等於SDS所保存字符串的長度 int len; // 記錄buf數組中未使用字節的數量 int free; // 字節數組,用於保存字符串 char buf[]; };
如上圖,能夠看到這個數據結構包含三部分:用於保存數據的字節
數組,已使用子節的長度和未使用的字節的長度,經過這個設計相信有經驗的工程師
已經明白了設計者的思路或用意,正是經過未使用空間,SDS實現了空間預分配和惰性空間釋放兩種優化策略
.數據結構
說說這兩種優化策略的大概思想:函數
當一個SDS最初被建立的時候,free=len,也就是建立的長度等於目標字符串長度;如上圖,SDS起初長度爲5(Redis),若是須要將這個字符串拼接上Cluster,SDS會預分配內存到(5+7)*2的長度,也就是總長度爲拼接後的字符串長度乘以2,此時free=len,這就是SDS預分配時,針對修改後的字符串長度小於1MB時採用的策略;假如修改後的長度大於1MB,SDS會預分配1MB的未使用空間優化
在SDS中,若是字符串在修改後長度變小,SDS並不會當即釋放暫時不用的內存空間,而僅僅是修改len和free的值,等待未來使用,舉個例子,假如第一次修改操做爲縮短8個字節,此後一次修改操做爲長度增長7字節,那麼SDS就能夠重複利用這8字節,經過惰性空間釋放策略,SDS避免了縮短字符串時所需的內存重分配操做,併爲未來可能有的增加操做提供了優化。 與此同時,SDS也提供了相應的API,讓咱們能夠在有須要時,真正地釋放SDS的未使用空間,因此不用擔憂惰性空間釋放策略會形成內存浪費。設計
*** 二進制安全 ***code
SDS採用字節數組保存原始數據,採用C末位一個字節爲\0的表示方法實現與C函數的兼容,正由於採用的是字節數組才達到了二進制安全的效果,並不是關鍵內存
綜上,SDS同C的默認字符串實現相比,主要起到了以上兩部分優化效果字符串