redis我與SDS的初見

一 前言

本篇文章是初步認識redis的字符串數據結構SDS(Simple Dynamic String), 其意指簡單的動態字符串,字面上的含義就是smiple 代指簡單,操做簡單,使用者可以快點理解上手,無需關心redis內部實現;Dynamic 指動態擴展,表是可以自動的對內存空間進行動態分配;String 表示字符串,不難理解;git

公衆號:知識追尋者github

知識追尋者(Inheriting the spirit of open source, Spreading technology knowledge;)redis

二 SDS結構

2.1 redis SDS數據結構

redis3.2以前數據結構以下;算法

struct sdshdr {
    unsigned int len;   
    unsigned int free;  
    char buf[];         
};
  • len 表示 buf(緩衝區)中已經使用的空間長度;
  • free 表示 buf中未使用的長度;
  • buf[] 表示緩衝區數組,存儲字符;

2.12 redis 緩衝區結構

更加的形象的一個存儲圖像以下 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 快不少;數組

2.2 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, 很直觀的發現 內存溢出, 第一個字符串就覆蓋至第二個字符串的部份內容;post

因此 redis 的操做內容空間是杜絕內存溢出,而且可以儲存圖片,視頻等二進制數據,若是是c語言操做儲存,二進制文件中一個\0就可能致使內存泄漏,緩衝區溢出等,故c語言通常只操做文本文件;spa

三 相關連接

若是想要深刻redis之SDS源碼,能夠參考以下連接;.net

http://www.javashuo.com/article/p-gnnttsnb-bz.htmlcode

https://juejin.im/post/5cdbafedf265da037c7d090f

https://blog.csdn.net/qq193423571/article/details/81637075

https://lynnapan.github.io/2017/07/14/redis_sds/

相關文章
相關標籤/搜索