Redis數據結構之String原理

一、基本原理redis

Redis 的字符串是動態字符串,是能夠修改的字符串,內部結構實現上相似於 Java 的 ArrayList,採用預分配冗餘空間的方式來減小內存的頻繁分配,如圖中所示,內部爲當前字符串實際分配的空間 capacity 通常要高於實際字符串長度 len。當字符串長度小於 1M 時, 擴容都是加倍現有的空間,若是超過 1M,擴容時一次只會多擴 1M 的空間。須要注意的是 字符串最大長度爲 512M。api

二、數據結構安全

struct sdshdr {
    // buf 中已佔用空間的長度
    int len;
    // buf 中剩餘可用空間的長度
    int alloc;
    //前3位爲數據類型,後5位暫時沒有用到 
    unsigned char flags;
    // 數據空間
    char buf[];
};

三、SDS 與C字符串的對比 和優勢數據結構

a  O(1) 獲取字符串長度函數

由於sds已經存了數據的長度,因此獲取字符串長度複雜度爲O(1),而C字符串獲取長度爲O(n)。優化

b  杜絕緩衝區溢出致使的內存問題編碼

假設內存區域有s1:「hi」,s2: 「redis」 兩個字符串,位置緊鄰,以下圖: 緊鄰字符串被覆蓋 此時須要給s1 追加一個「boy」, 若是是C字符串,忘記了在追加以前先給s1 分配空間,此時追加將致使 s2的值被意外的修改。 而使用 sds則不會有這個問題。 由於其封裝好的函數,會在追加數據以前先檢查 空間是否夠用,若是不夠用就擴容。code

c  經過空間預分配和空間惰性釋放圖片

減小內存分配問題 當給sds的值追加一個字符串,而當前的剩餘空間不夠時,就會觸發sds的擴容機制。擴容採用了空間預分配的優化策略,即分配空間的時候:若是sds 值大小< 1M ,則增長一倍; 反之若是>1M , 則當前空間加1M做爲新的空間。 當sds的字符竄縮短了,sds的buf內會多出來一些空間,這個空間並不會立刻被回收,而是暫時留着以防再用的時候進行多餘的內存分配。這個是惰性空間釋放的策略內存

d 二進制安全

c字符串必須符合某種編碼(例如ASCII),且不能包含空字符。 這些限制使得 c字符竄不能保存圖片,音頻等二進制文件。 而sds的api 都是二進制安全的,其全部api 都會以處理二進制的方式來處理buf內的數據,因此不會有任何的限制。

相關文章
相關標籤/搜索