久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

Redis數(shù)據(jù)結(jié)構(gòu)中的String類型有哪些

共計(jì) 2388 個(gè)字符,預(yù)計(jì)需要花費(fèi) 6 分鐘才能閱讀完成。

這篇文章主要介紹“Redis 數(shù)據(jù)結(jié)構(gòu)中的 String 類型有哪些”,在日常操作中,相信很多人在 Redis 數(shù)據(jù)結(jié)構(gòu)中的 String 類型有哪些問(wèn)題上存在疑惑,丸趣 TV 小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”Redis 數(shù)據(jù)結(jié)構(gòu)中的 String 類型有哪些”的疑惑有所幫助!接下來(lái),請(qǐng)跟著丸趣 TV 小編一起來(lái)學(xué)習(xí)吧!

Redis 常用作分布式 KV 緩存,很多人僅僅只會(huì)使用,卻不知道底層卻有著很多不為人知的秘密。

String 類型

String 作為 Redis 支持的最基礎(chǔ)的數(shù)據(jù)類型,首先我們來(lái)看下 String,他的數(shù)據(jù)結(jié)構(gòu)和存儲(chǔ)是怎么樣的。

重新定義 SDS 去存儲(chǔ) String

眾所周知,redis 是用 c 語(yǔ)言進(jìn)行編寫的,而 c 語(yǔ)言是沒(méi)有 String 類型的,只有 char[],并且在初始化的是時(shí)候就必須大小指定類型后就不能改變。為了實(shí)現(xiàn)動(dòng)態(tài)增加和擴(kuò)展等功能,如 incr 命令,append 命令,所以 redis 就自己定義維護(hù)了一個(gè) SDS(Simple Dynamic String)來(lái)實(shí)現(xiàn)這些功能。

我們先來(lái)看一下 redis 源碼中定義的數(shù)據(jù)結(jié)構(gòu), 這里有 5 種類型,目的是為了節(jié)省空間。

1、len: 獲取 char[]的長(zhǎng)度,需要遍歷數(shù)組,len(char[])時(shí)間復(fù)雜度 O(n);
2、alloc:c 語(yǔ)言沒(méi)有 String 類型,只有 char[],且 char[]必須先分配空間長(zhǎng)度,char[]預(yù)先分配了長(zhǎng)度,數(shù)據(jù)增長(zhǎng)后需要擴(kuò)容;

3、falgs:總是占用一個(gè)字節(jié)。其中的最低 3 個(gè) bit 用來(lái)表示 header 的類型。header 的類型共有 5 種,在 sds.h 中有常量定義。
4、buf[]:c 語(yǔ)言的 char 數(shù)組,用 \0 代表結(jié)束,意味著存儲(chǔ)二進(jìn)制數(shù)據(jù)不能包含 \0,圖片音頻等用二進(jìn)制存儲(chǔ)會(huì)有問(wèn)題——這就是為什么 Redis 說(shuō)自己實(shí)現(xiàn)的 SDS 是二進(jìn)制安全的字符串。

SDS 對(duì) c 原始 char 數(shù)組的改進(jìn)

1、Redis 實(shí)現(xiàn)的 SDS 支持?jǐn)U容
2、包含長(zhǎng)度 len,獲取長(zhǎng)度復(fù)雜度 O(1)
3、空間預(yù)分配
4、惰性空間釋放(下面會(huì)講)

SDS 的優(yōu)缺點(diǎn)

優(yōu)點(diǎn)

能夠支持?jǐn)U容

包含長(zhǎng)度 len,獲取長(zhǎng)度復(fù)雜度 O(1)

空間預(yù)分配

缺點(diǎn)

需要分配額外的內(nèi)存

頻繁的分配和回收帶來(lái)的效率問(wèn)題

Redis 使用的內(nèi)存分配庫(kù) jemalloc

jemalloc 在分配內(nèi)存時(shí),會(huì)根據(jù)我們申請(qǐng)的字節(jié)數(shù) N,找一個(gè)比 N 大,但是最接近 N 的 2 的冪次數(shù)作為分配的空間,這樣可以減少頻繁分配的次數(shù)。舉個(gè)例子。如果你申請(qǐng) 6 字節(jié)空間,jemalloc 實(shí)際會(huì)分配 8 字節(jié)空間;如果你申請(qǐng) 24 字節(jié)空間,jemalloc 則會(huì)分配 32 字節(jié)。所以,在我們剛剛說(shuō)的場(chǎng)景里,dictEntry 結(jié)構(gòu)就占用了 32 字節(jié)。

空間預(yù)分配

空間預(yù)分配用于優(yōu)化 SDS 的字符串增長(zhǎng)操作:當(dāng) SDS 的 API 對(duì)一個(gè) SDS 進(jìn)行修改,并且需要對(duì) SDS 進(jìn)行空間擴(kuò)展的時(shí)候,程序不僅會(huì)為 SDS 分配修改所必須要的空間,還會(huì)為 SDS 分配額外的未使用空間。

其中,額外分配的未使用空間數(shù)量由以下公式?jīng)Q定:

如果對(duì) SDS 進(jìn)行修改之后,SDS 的長(zhǎng)度(也即是 len 屬性的值)將小于 1 MB,那么程序分配和 len 屬性同樣大小的未使用空間,這時(shí) SDS len 屬性的值將和 free 屬性的值相同。舉個(gè)例子,如果進(jìn)行修改之后,SDS 的 len 將變成 13 字節(jié),那么程序也會(huì)分配 13 字節(jié)的未使用空間,SDS 的 buf 數(shù)組的實(shí)際長(zhǎng)度將變成 13 + 13 + 1 = 27 字節(jié)(額外的一字節(jié)用于保存空字符)。

如果對(duì) SDS 進(jìn)行修改之后,SDS 的長(zhǎng)度將大于等于 1 MB,那么程序會(huì)分配 1 MB 的未使用空間。舉個(gè)例子,如果進(jìn)行修改之后,SDS 的 len 將變成 30 MB,那么程序會(huì)分配 1 MB 的未使用空間,SDS 的 buf 數(shù)組的實(shí)際長(zhǎng)度將為 30 MB + 1 MB + 1 byte。

通過(guò)空間預(yù)分配策略,Redis 可以減少連續(xù)執(zhí)行字符串增長(zhǎng)操作所需的內(nèi)存重分配次數(shù)。

惰性釋放

惰性空間釋放用于優(yōu)化 SDS 的字符串縮短操作:當(dāng) SDS 的 API 需要縮短 SDS 保存的字符串時(shí),程序并不立即使用內(nèi)存重分配來(lái)回收縮短后多出來(lái)的字節(jié),而是使用 free 屬性將這些字節(jié)的數(shù)量記錄起來(lái),并等待將來(lái)使用。

Redis 的 KV 存儲(chǔ)結(jié)構(gòu)

在 redis 中,所有的存儲(chǔ)都是以 KV 鍵值對(duì)的形式存儲(chǔ)的,K 是字符串類型,就是 SDS;V 可能是字符串、list、hash 等(Redis 支持的數(shù)據(jù)結(jié)構(gòu)),V 并沒(méi)有直接定成具體的類型,而是用 redisObject 封裝了一層;實(shí)際存儲(chǔ)的數(shù)據(jù)結(jié)構(gòu)是由 ptr 指針具體指向。

并且,redis 為了更好的節(jié)省空間,ptr 指針也有不同方式的存儲(chǔ),一方面,當(dāng)保存的是 Long 類型整數(shù)時(shí),RedisObject 中的指針就直接賦值為整數(shù)數(shù)據(jù)了,這樣就不用額外的指針再指向整數(shù)了,節(jié)省了指針的空間開(kāi)銷。另一方面,當(dāng)保存的是字符串?dāng)?shù)據(jù),并且字符串小于等于 44 字節(jié)時(shí),RedisObject 中的元數(shù)據(jù)、指針和 SDS 是一塊連續(xù)的內(nèi)存區(qū)域,這樣就可以避免內(nèi)存碎片。這種布局方式也被稱為 embstr 編碼方式。當(dāng)然,當(dāng)字符串大于 44 字節(jié)時(shí),SDS 的數(shù)據(jù)量就開(kāi)始變多了,Redis 就不再把 SDS 和 RedisObject 布局在一起了,而是會(huì)給 SDS 分配獨(dú)立的空間,并用指針指向 SDS 結(jié)構(gòu)。這種布局方式被稱為 raw 編碼模式。如圖所示

embstr 編碼
存儲(chǔ)簡(jiǎn)短字符串,一次的內(nèi)存分配;
它是只讀的,如果對(duì)內(nèi)容進(jìn)行修改,就會(huì)變成 raw 編碼(即使沒(méi)超過(guò) 44 字節(jié));

raw 編碼
可分配多次內(nèi)存空間,存儲(chǔ)大于 44 個(gè)字節(jié)的長(zhǎng)字符串。

raw 原生 SDS 字符長(zhǎng)度 縮減到小于 44,會(huì)逆向變成 embstr 編碼嗎?
不會(huì);Redis 底層編碼,轉(zhuǎn)變后 不可逆(不會(huì)回退)。

到此,關(guān)于“Redis 數(shù)據(jù)結(jié)構(gòu)中的 String 類型有哪些”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注丸趣 TV 網(wǎng)站,丸趣 TV 小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!

正文完
 
丸趣
版權(quán)聲明:本站原創(chuàng)文章,由 丸趣 2023-07-18發(fā)表,共計(jì)2388字。
轉(zhuǎn)載說(shuō)明:除特殊說(shuō)明外本站除技術(shù)相關(guān)以外文章皆由網(wǎng)絡(luò)搜集發(fā)布,轉(zhuǎn)載請(qǐng)注明出處。
評(píng)論(沒(méi)有評(píng)論)
主站蜘蛛池模板: 缙云县| 新竹县| 浦县| 奉新县| 土默特左旗| 安新县| 重庆市| 垫江县| 宁阳县| 盱眙县| 永济市| 崇文区| 康马县| 松阳县| 东乡族自治县| 漳浦县| 金秀| 巢湖市| 前郭尔| 崇州市| 安多县| 晋城| 凭祥市| 沙田区| 夏津县| 万盛区| 永胜县| 循化| 祁东县| 黄平县| 乐东| 当雄县| 田阳县| 苍溪县| 昌黎县| 海宁市| 盘山县| 奇台县| 丘北县| 桦甸市| 城市|