欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Redis中SDS簡單動態(tài)字符串詳解

 更新時間:2023年04月12日 08:28:56   作者:邴越  
Redis中的SDS(Simple?Dynamic?String)是一種自動擴容的字符串實現(xiàn)方式,它可以提供高效的字符串操作,并且支持二進制安全。SDS的設計使得它可以在O(1)時間內實現(xiàn)字符串長度的獲取和修改,同時也可以在O(N)的時間內進行字符串的拼接和截取。

Redis 是內存數據庫,高效使用內存對 Redis 的實現(xiàn)來說非常重要。

看一下,Redis 中針對字符串結構針對內存使用效率做的設計優(yōu)化。

一、SDS的結構 

c語言沒有string類型,本質是char[]數組;而且c語言數組創(chuàng)建時必須初始化大小,指定類型后就不能改變,并且字符數組的最后一個元素總是空字符 '\0' 。

以下展示了一個值為 "Redis" 的 C 字符串:

Redis沒有直接使用C語言的字符串方式,而是構建了一種簡單動態(tài)字符串(Simple dynamic string, SDS)的類型,Redis中的字符串底層都是使用SDS結構進行存儲,比如包含字符串的鍵值對底層都是使用SDS結構實現(xiàn)的。

SDS結構定義在sds.h中

struct sdshdr{


    int len;//SDS保存的字符串長度


    int free;//buf數組中未使用字節(jié)數量


    char buf[];//字符數組,保存字符串


}

最后一個字節(jié)保存了空字符'\0',保留了C字符串的規(guī)范,使得SDS結構的字符串,可以重用一部分C函數庫的函數。

二、為什么不使用C字符串

主要是因為C字符串有以下缺點:

獲取字符串長度時間復雜度為O(N):C字符串獲取長度需遍歷整個字符串,遇到'\0'空字符為止。 緩沖區(qū)溢出:比如在進行字符串追加操作時,如果沒有分配足夠的內存,就會造成內存溢出。 內存重分配:每次增長或者截短字符串,程序都要對保存C字符串的數組進行內存重分配操作,而內存重分配涉及復雜的算法,并可能需要執(zhí)行系統(tǒng)調用,所以它通常比較耗時。 空字符問題:C字符串中間不能保存空格,否則程序遍歷是會誤認為是字符串的末尾。這一限制導致C字符串只能存儲文本數據,不能保存像圖片、音視頻、壓縮文件等二進制數據。

三、怎樣解決C字符串問題 

 

1、SDS通過len屬性記錄了SDS長度,所以獲取長度的時間復雜度為O(1),即strlen命令的時間復雜度是O(1)。

2、SDS空間分配策略避免了緩沖區(qū)溢出:當對SDS進行修改時,會先檢查SDS空間是否滿足修改,不滿足會自動擴展到所需大小,然后才執(zhí)行修改。

3、較少修改字符串時內存重分配次數:SDS中的free記錄buf字節(jié)數組中未使用的字節(jié)。

redis通過free屬性實現(xiàn)空間預分配、惰性空間釋放兩種優(yōu)化策略。

空間預分配:當對SDS進行增長操作時,程序不僅會分配修改所必須得空間,還會為SDS分配額外的未使用空間。通過預分配策略,減少了連續(xù)執(zhí)行字符串增長操作時內存重分配次數。 惰性空間釋放:當對SDS進行截短操作時,程序并不會立即回收縮短后多出來的字節(jié)所占用的內存,而是使用free屬性記錄多出來的字節(jié)數,以供將來使用。如果將來要對這個SDS進行增長操作,未使用空間可能就派上用場,并且增長操作也不一定會執(zhí)行內存重分配。

SDS結構中的buf字節(jié)數組,是二進制安全的,不僅可以保存字符,也可以保存二進制數據。

SDS保留了C字符串的慣例,將數據的末尾設置為空字符'\0',SDS中之所以保留這一規(guī)范是可以重用C字符串函數庫的一部分函數,例如追加字符串。

四、對字符串的進一步優(yōu)化

Redis string的三種編碼:

int 存儲8個字節(jié)的長整型(long,2^63-1 ) embstr, embstr格式的SDS (Simple Dynamic String) raw, raw格式的SDS,存儲大于44個字節(jié)的長字符串

int類型就是指的是數字,那么raw、embstr都代表的是字符串有什么異同嗎,下面我們分析下。

圖中展示了兩者的區(qū)別,可以看到embstr將redisObject和SDS保存在連續(xù)的64字節(jié)空間內,這樣可以只需要一次內存分配,而對于raw來說,SDS和redisObject分離,需要兩次內存分配,而且占用更多的內存空間。

可以看到embstr在3.2+中使用了叫sdshdr8的結構,在該結構下,元數據只需要3個字節(jié),而Redis需要8個字節(jié),所以總共64個字節(jié),減去redisObject(16字節(jié)),再減去SDS的原信息,最后的實際內容就變成了44字節(jié)和39字節(jié)。

當字符串小于等于 44 字節(jié)時,Redis 就使用了嵌入式字符串的創(chuàng)建方法,以此減少內存分配和內存碎片。

下面這張圖展示了 createEmbeddedStringObject 創(chuàng)建嵌入式字符串的過程:

 

總之,只要記住,Redis 會通過設計實現(xiàn)一塊連續(xù)的內存空間,把 redisObject 結構體和 SDS 結構體緊湊地放置在一起。

這樣一來,對于不超過 44 字節(jié)的字符串來說,就可以避免內存碎片和兩次內存分配的開銷了。

SDS是Redis中一種高效的字符串實現(xiàn)方式,它具有自動擴容、二進制安全、O(1)長度獲取和修改等優(yōu)點。在實際的應用中,SDS可以幫助我們實現(xiàn)高效的字符串操作,同時也可以避免一些常見的字符串操作問題,比如緩沖區(qū)溢出等。通過深入了解SDS的內部結構和實現(xiàn)原理,我們可以更好地理解Redis的底層機制,進一步提升我們的Redis應用能力。

到此這篇關于Redis中SDS簡單動態(tài)字符串詳解的文章就介紹到這了,更多相關Redis中SDS簡單動態(tài)字符串內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • SpringBoot讀寫Redis客戶端并實現(xiàn)Jedis技術切換功能

    SpringBoot讀寫Redis客戶端并實現(xiàn)Jedis技術切換功能

    這篇文章主要介紹了SpringBoot讀寫Redis客戶端并實現(xiàn)技術切換功能,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-01-01
  • Redis命令使用技巧之Keys的相關操作

    Redis命令使用技巧之Keys的相關操作

    Redis KEYS命令用于搜索具有匹配模式的鍵。下面這篇文章主要給大家介紹了關于Redis命令使用技巧之Keys的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考借鑒,下面隨著小編來一起學習學習吧
    2018-10-10
  • 詳解redis集群的三種方式

    詳解redis集群的三種方式

    Redis三種集群方式分別是主從復制,哨兵模式,Cluster集群,這篇文章主要介紹了redis集群的三種方式,本文給大家介紹的非常詳細,需要的朋友可以參考下
    2022-07-07
  • Redis生成分布式系統(tǒng)全局唯一ID的實現(xiàn)

    Redis生成分布式系統(tǒng)全局唯一ID的實現(xiàn)

    在互聯(lián)網系統(tǒng)中,并發(fā)越大的系統(tǒng),數據就越大,數據越大就越需要分布式,本文主要介紹了Redis生成分布式系統(tǒng)全局唯一ID的實現(xiàn),感興趣的可以了解一下
    2021-10-10
  • Redis過期Key刪除策略和內存淘汰策略的實現(xiàn)

    Redis過期Key刪除策略和內存淘汰策略的實現(xiàn)

    當內存使用達到上限,就無法存儲更多數據了,為了解決這個問題,Redis內部會有兩套內存回收的策略,過期Key刪除策略和內存淘汰策略,本文就來詳細的介紹一下這兩種方法,感興趣的可以了解一下
    2024-02-02
  • 為什么RedisCluster設計成16384個槽

    為什么RedisCluster設計成16384個槽

    本文主要介紹了為什么RedisCluster設計成16384個槽,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • 基于Redis的限流器的實現(xiàn)(示例講解)

    基于Redis的限流器的實現(xiàn)(示例講解)

    下面小編就為大家分享一篇基于Redis的限流器的實現(xiàn)(示例講解),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2017-12-12
  • Redis之SDS數據結構的使用

    Redis之SDS數據結構的使用

    本文主要介紹了Redis之SDS數據結構的使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-08-08
  • Redis設置密碼的實現(xiàn)步驟

    Redis設置密碼的實現(xiàn)步驟

    本文主要介紹了Redis設置密碼的實現(xiàn)步驟,主要包括兩種方法:臨時密碼和持久密碼,具有一定的參考價值,感興趣的可以了解一下
    2023-08-08
  • redis執(zhí)行redis命令的方法教程

    redis執(zhí)行redis命令的方法教程

    這篇文章主要給大家介紹了在redis中執(zhí)行redis命令的方法教程,文中詳細介紹了關于Redis 命令及在遠程服務上執(zhí)行命令的方法,介紹的非常詳細,對大家具有一定的參考學習價值,需要的朋友們下面來一起看看吧。
    2017-06-06

最新評論