亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Redis系列之底層數(shù)據(jù)結(jié)構(gòu)SDS詳解

 更新時(shí)間:2024年11月07日 09:02:32   作者:smileNicky  
SDS(簡(jiǎn)單動(dòng)態(tài)字符串)是Redis使用的核心數(shù)據(jù)結(jié)構(gòu),用于替代C語(yǔ)言的字符串,以解決長(zhǎng)度獲取慢、內(nèi)存溢出等問(wèn)題,SDS通過(guò)預(yù)分配與惰性釋放策略優(yōu)化內(nèi)存使用,增強(qiáng)安全性,且能存儲(chǔ)文本與二進(jìn)制數(shù)據(jù),可查看源碼src/sds.h和src/sds.c了解更多

實(shí)驗(yàn)的環(huán)境

  • Redis 6.0
  • VSCode 1.88.1

什么是SDS?

SDS:Simple Dynamic String,翻譯為簡(jiǎn)單動(dòng)態(tài)字符串。

SDS是一種用于存儲(chǔ)二進(jìn)制數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu),具有動(dòng)態(tài)擴(kuò)容的特點(diǎn),代碼位于src/sds.hsrc/sds.c

SDS的總體數(shù)據(jù)結(jié)構(gòu)大致如圖:在源碼里sds包括幾個(gè)部分,len、allocflags、buf,其中 sdshdr是頭部,buf是真實(shí)存儲(chǔ)數(shù)據(jù)的地方,在存儲(chǔ)的數(shù)據(jù)后面會(huì)跟一個(gè)\0,所以數(shù)據(jù)加上\0就是所謂的buf

  • len:保存了SDS字符串的長(zhǎng)度
  • buf[]:保存數(shù)據(jù)的地方
  • alloc:分別以u(píng)int8, uint16, uint32, uint64表示整個(gè)SDS
  • flags:始終為一字節(jié), 以低三位標(biāo)示著頭部的類(lèi)型, 高5位未使用

查看源碼sds.h,可以看到SDS里面有幾種不同的頭部,其中sdshdr5實(shí)際并未使用到,所以實(shí)際上有四種不同的頭部

/* Note: sdshdr5 is never used, we just access the flags byte directly.
 * However is here to document the layout of type 5 SDS strings. */
struct __attribute__ ((__packed__)) sdshdr5 {
    unsigned char flags; /* 3 lsb of type, and 5 msb of string length */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr8 {
    uint8_t len; /* used */
    uint8_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr16 {
    uint16_t len; /* used */
    uint16_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr32 {
    uint32_t len; /* used */
    uint32_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr64 {
    uint64_t len; /* used */
    uint64_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};

為什么要使用SDS?

Redis是用C語(yǔ)言寫(xiě)的,為什么不直接就用C語(yǔ)言里的char來(lái)定義字符串?

獲取字符串長(zhǎng)度

由于有len屬性,所以獲取SDS字符串的長(zhǎng)度只需要讀取len屬性,所以時(shí)間復(fù)雜度為O(1)。

如果直接使用C語(yǔ)言中的字符串來(lái)實(shí)現(xiàn),獲取字符串的長(zhǎng)度需要遍歷計(jì)數(shù),時(shí)間復(fù)雜度為O(n)

避免緩存區(qū)溢出

C語(yǔ)言中,如果使用strcat函數(shù)來(lái)進(jìn)行兩個(gè)字符串的拼接,如果沒(méi)有分配足夠長(zhǎng)度的內(nèi)存空間,就會(huì)造成緩存區(qū)溢出。

而對(duì)于SDS數(shù)據(jù)類(lèi)型,在進(jìn)行字符串修改的時(shí)候,會(huì)根據(jù)記錄的len屬性檢查內(nèi)存空間是否滿足需求,如果不滿足,會(huì)進(jìn)行相應(yīng)空間的擴(kuò)展,所以不會(huì)出現(xiàn)緩存區(qū)溢出

減少字符串內(nèi)存重新分配次數(shù)

C語(yǔ)言中字符串,是不會(huì)記錄字符串的長(zhǎng)度的,所以一旦修改了字符串,就需要重新分配內(nèi)存,因?yàn)槿绻麤](méi)有重新分配,字符串長(zhǎng)度增大時(shí)會(huì)造成內(nèi)存溢出區(qū)溢出,長(zhǎng)度減小時(shí)會(huì)造成內(nèi)存泄漏。

而對(duì)于SDS來(lái)說(shuō),因?yàn)橛虚L(zhǎng)度熟悉lenalloc屬性的存在,SDS實(shí)現(xiàn)了空間預(yù)分配惰性空間釋放兩種策略來(lái)減少重新分配內(nèi)存

  1. 空間預(yù)分配:SDS對(duì)空間進(jìn)行擴(kuò)展的時(shí)候,擴(kuò)展的內(nèi)存比實(shí)際需要的多,這樣可以減少字符串增長(zhǎng)操作所需的內(nèi)存重新分配次數(shù)
  2. 惰性空間釋放:SDS對(duì)字符串進(jìn)行縮短操作時(shí),不會(huì)立即進(jìn)行內(nèi)存重新分配,來(lái)回收縮短后多余的內(nèi)存空間,而是使用alloc將這些字節(jié)數(shù)量記錄下來(lái),等待后續(xù)使用

二進(jìn)制安全

C語(yǔ)言中,是以空字符串作為字符串結(jié)束的標(biāo)識(shí),但是一些特殊的字符串,可能就包括空字符串的,所以容易丟失數(shù)據(jù),不能正確存取。

而SDS是根據(jù)len屬性,以處理二進(jìn)制的方式來(lái)處理buf里的數(shù)據(jù),所以保存數(shù)據(jù)更加安全

兼容部分C字符串函數(shù)

SDS可以重用C語(yǔ)言庫(kù)<string.h>中的一部分函數(shù)

C字符串和SDS對(duì)比

C字符串SDS
獲取字符串長(zhǎng)度時(shí)間復(fù)雜度為O(n)獲取字符串的長(zhǎng)度時(shí)間復(fù)雜度為O(1)
不安全,可能會(huì)造成緩沖區(qū)溢出安全,不會(huì)造成緩沖區(qū)溢出
修改字符串n次就需要進(jìn)行n次內(nèi)存分配修改字符串長(zhǎng)度n次,最多需要n次內(nèi)存分配
只能保存文本數(shù)據(jù)可以保存文本數(shù)據(jù)或者二進(jìn)制數(shù)據(jù)
可以使用所有<string.h>庫(kù)中的函數(shù)可以使用一部分<string.h>庫(kù)中的函數(shù)

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Redisson之lock()和tryLock()的區(qū)別及說(shuō)明

    Redisson之lock()和tryLock()的區(qū)別及說(shuō)明

    這篇文章主要介紹了Redisson之lock()和tryLock()的區(qū)別及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • redis的hash類(lèi)型操作方法

    redis的hash類(lèi)型操作方法

    Hash 是一個(gè) String 類(lèi)型的 field(字段) 和 value(值) 的映射表,hash 特別適合用于存儲(chǔ)對(duì)象,這篇文章主要介紹了redis的hash類(lèi)型的詳解,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-06-06
  • 分布式利器redis及redisson的延遲隊(duì)列實(shí)踐

    分布式利器redis及redisson的延遲隊(duì)列實(shí)踐

    這篇文章為大家主要介紹了分布式利器redis及redisson的延遲隊(duì)列實(shí)踐,搜遍全網(wǎng)好像還沒(méi)有使用redisson的延遲隊(duì)列的,redisson作為一個(gè)分布式利器,這么好用的工具沒(méi)人用有點(diǎn)可惜
    2022-03-03
  • Redis的setNX分布式鎖超時(shí)時(shí)間失效 -1問(wèn)題及解決

    Redis的setNX分布式鎖超時(shí)時(shí)間失效 -1問(wèn)題及解決

    這篇文章主要介紹了Redis的setNX分布式鎖超時(shí)時(shí)間失效 -1問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • NoSQL和Redis簡(jiǎn)介及Redis在Windows下的安裝和使用教程

    NoSQL和Redis簡(jiǎn)介及Redis在Windows下的安裝和使用教程

    這篇文章主要介紹了NoSQL和Redis簡(jiǎn)介及Redis在Windows下的安裝和使用教程,本文同時(shí)講解了python操作redis,并給出了操作實(shí)例,需要的朋友可以參考下
    2015-01-01
  • Redis實(shí)現(xiàn)消息的發(fā)布訂閱原理分析

    Redis實(shí)現(xiàn)消息的發(fā)布訂閱原理分析

    本文主要介紹了Redis實(shí)現(xiàn)消息的發(fā)布訂閱原理分析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • redis初學(xué)者常見(jiàn)字符亂碼問(wèn)題及解決方案

    redis初學(xué)者常見(jiàn)字符亂碼問(wèn)題及解決方案

    這篇文章主要介紹了redis初學(xué)者常見(jiàn)字符亂碼問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • Redis高并發(fā)緩存設(shè)計(jì)問(wèn)題與性能優(yōu)化

    Redis高并發(fā)緩存設(shè)計(jì)問(wèn)題與性能優(yōu)化

    本文詳細(xì)介紹了Redis緩存設(shè)計(jì)中常見(jiàn)的問(wèn)題及解決方案,包括緩存穿透、緩存失效(擊穿)、緩存雪崩、熱點(diǎn)緩存key重建優(yōu)化、緩存與數(shù)據(jù)庫(kù)雙寫(xiě)不一致以及開(kāi)發(fā)規(guī)范與性能優(yōu)化,感興趣的可以了解一下
    2024-11-11
  • Redis與MySQL數(shù)據(jù)一致性問(wèn)題的策略模式及解決方案

    Redis與MySQL數(shù)據(jù)一致性問(wèn)題的策略模式及解決方案

    開(kāi)發(fā)中,一般會(huì)使用Redis緩存一些常用的熱點(diǎn)數(shù)據(jù)用來(lái)減少數(shù)據(jù)庫(kù)IO,提高系統(tǒng)的吞吐量,本文將給大家介紹了Redis與MySQL數(shù)據(jù)一致性問(wèn)題的策略模式及解決方案,文中通過(guò)代碼示例介紹的非常詳細(xì),需要的朋友可以參考下
    2024-07-07
  • 詳解Redis緩存穿透/擊穿/雪崩原理及其解決方案

    詳解Redis緩存穿透/擊穿/雪崩原理及其解決方案

    緩存可以比喻為防彈衣,但如果沒(méi)有使用好這個(gè)防彈衣效果就會(huì)適得其反,所以要更好的使用緩存才能發(fā)揮出它的作用。本文詳細(xì)講解了緩存穿透/擊穿/雪崩以及其解決方法,感興趣的小伙伴可以學(xué)習(xí)一下這篇文章
    2021-09-09

最新評(píng)論