redis的字串資料結構SDS(Simple Dynamic String), 其意指簡單的動態字串,字面上的意思就是smiple 代指簡單,操作簡單,使用者能夠快點理解上手,無需關心redis內部實作;Dynamic 指動態擴展,表是能夠自動的對記憶體空間進行動態分配;String 表示字串,不難理解。
redis3.2之前資料結構如下;
struct sdshdr { unsigned int len; unsigned int free; char buf[]; };
len 表示buf (緩衝區)中已使用的空間長度;
free 表示buf中未使用的長度;
buf[] 表示緩衝區數組,儲存字元;
更的形象的一個儲存影像如下buf 中的實際大小為11(len free 1),其中已經使用空間len = 5 , 未使用空間free=5; 保留位空字元\0 佔一位;當我們在redis儲存進一個字串zxzxz
的時候就已經給我們分配好了內存空間,以及後面能用使用的記憶體空間;如果是c 語言那麼要得到一個zxzxz 字元長度就需要遍歷整個字元數組遇到\0 (C語言以\0區分記憶體空間中的字串)後結束,才計算出一個字串的長度,然而redis只需要一個sdslen
(非c語言讀者不必糾結此類API) 就可以計算得出字符串長度; 從演算法角度來看redis 的一次獲取字符字串長度為O(1), c 語言為O(N), 所以redis 快很多;
其次透過上圖可以發現儲存一個字串zxzxz
, 其所佔長度為5 , 為使用空間為5,\0 佔1 ;原因是redis字串儲存大小小於1MB 的時候, 儲存任意的字串, 其free大小永遠與自身的大小相同;當字串大小大於1MB時,其就分配free大小固定為1MB, 此稱為空間預分配策略
; 如果是c語言則需要計算當前字串在buf中的長度,再計算即將追加的字串長度,然後分配空間大小;故redis 的速度是相當快,相較於c 操作記憶體空間;
c 語言在操作記憶體空間的時候要不斷的計算大小,在追加字串的時候分配空間大小,如果未進行分配,那麼追加的字串有可能覆蓋已經儲存到記憶體空間的字串; 例如記憶體空間儲存zzz \ 0kkk\0
; 儲存zzz 的時候所佔用3 個位,加一個未分配空間1位,如果向zzz字串進行追加一個ggg, 那麼在未進行計算分配空間的情況下原有的數據會變成zzzggg\0k\0
, 很直覺的發現記憶體溢出, 第一個字串就覆蓋至第二個字串的部分內容;
所以redis 的操作內容空間是杜絕內存溢出,並且能夠儲存圖片,視頻等二進制數據,如果是c語言操作儲存,二進位文件中一個\0就可能導致內存洩漏,緩衝區溢出等,故c語言一般只操作文本文件;
以上是redis SDS的資料結構是怎麼樣的的詳細內容。更多資訊請關注PHP中文網其他相關文章!