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

Redis壓縮列表的示例分析

131次閱讀
沒有評論

共計 4564 個字符,預(yù)計需要花費(fèi) 12 分鐘才能閱讀完成。

自動寫代碼機(jī)器人,免費(fèi)開通

這篇文章主要介紹了 Redis 壓縮列表的示例分析,具有一定借鑒價值,需要的朋友可以參考下。希望大家閱讀完這篇文章后大有收獲。下面讓丸趣 TV 小編帶著大家一起了解一下。

此篇文章是主要介紹 Redis 在數(shù)據(jù)存儲方面的其中一種方式,壓縮列表。

本文會介紹

1、壓縮列表(ziplist)的使用場景

2. 如何達(dá)到節(jié)約內(nèi)存的效果?

3. 壓縮列表的存儲格式

4. 連鎖更新的問題  

5. conf 文件配置。

在實(shí)踐上的操作主要是對 conf 配置文件進(jìn)行配置,具體上沒有確切的一個值,更多是經(jīng)驗值。也有的項目會直接使用原本的默認(rèn)值。此篇對于更好地理解一個數(shù)據(jù)庫底層的存儲邏輯會有一點(diǎn)幫助。修學(xué)儲能,既要博,也要淵。希望這篇文章對同樣也是在學(xué)習(xí) Redis 的各位同伴有點(diǎn)用。(推薦教程:Redis 教程)

一、壓縮列表(ziplist)的使用場景:

Redis 為了優(yōu)化數(shù)據(jù)存儲,節(jié)約內(nèi)存,在列表、字典(哈希鍵)和有序集合的底層實(shí)現(xiàn)了使用壓縮列表這一優(yōu)化方案。

例如,假如一個哈希鍵里面存儲的字符串比較短,那么 Redis 就會將它用壓縮列表的格式去存儲,即轉(zhuǎn)換為字節(jié)數(shù)組存儲。而一個哈希鍵內(nèi)部存儲的整數(shù)值比較小,同樣也會把它存儲為壓縮列表的一個節(jié)點(diǎn)。同理,列表鍵的對小數(shù)據(jù)的存儲跟哈希鍵的操作類似。

如此說來,壓縮列表并不是開發(fā)者可以直接調(diào)用的 Redis 中的一種存儲數(shù)據(jù)結(jié)構(gòu),而是 Redis 中為優(yōu)化數(shù)據(jù)存儲而在底層做的一項努力。理解好這點(diǎn)還是比較重要的。

二、如何達(dá)到節(jié)約內(nèi)存的效果?

壓縮列表是一種序列化的數(shù)據(jù)結(jié)構(gòu),這種數(shù)據(jù)結(jié)構(gòu)的功能是將一系列數(shù)據(jù)與其編碼信息存儲在一塊連續(xù)的內(nèi)存區(qū)域,這塊內(nèi)存物理上是連續(xù)的。但邏輯上被分為多個組成部分,即節(jié)點(diǎn)。目的是為了在一定可控的時間復(fù)雜度條件下盡可能的減少不必要的內(nèi)存開銷,從而達(dá)到節(jié)省內(nèi)存的效果。需要理解是怎么達(dá)到節(jié)約內(nèi)存作用的,還需要去了解壓縮列表的存儲格式。

三、壓縮列表的存儲格式:

壓縮列表(ziplist)是 Redis 列表鍵、哈希鍵和有序集合鍵的底層實(shí)現(xiàn)之一,其實(shí)質(zhì)是一種序列化的數(shù)據(jù)存儲結(jié)構(gòu)。有別于普通情況下,Redis 用雙端鏈表表示列表,使用散列表表示哈希鍵,用散列表 + 跳躍表表示有序集合。當(dāng)一個列表或者哈希字典 / 有序集合只包含很少內(nèi)容,并且每一個列表項或者哈希項 / 有序集合項如果是小整數(shù),或者比較短的字符串。那么 Redis 就會用壓縮列表來做底層的實(shí)現(xiàn)。

壓縮列表由一系列經(jīng) Redis 特殊編碼的連續(xù)內(nèi)存塊組成,每一個內(nèi)存塊稱為一個節(jié)點(diǎn)(entry),而一個壓縮列表可以包含很多個節(jié)點(diǎn)。每個節(jié)點(diǎn)存儲的數(shù)據(jù)格式可以是字節(jié)數(shù)組(中文字符串等都會轉(zhuǎn)換為字節(jié)數(shù)組)或者整數(shù)值。

字節(jié)數(shù)組的長度可以是以下的其中一種:

1. 長度小于等于 63 字節(jié)(2 的 6 次方)

2. 長度小于等于 16383 字節(jié)(2 的 14 次方)

3. 長度小于等于 4294967295 字節(jié)(2 的 32 次方)

整數(shù)值可能是以下六種中的其中一種:

1. 4 位長,介于 0 -12 之間的無符號整數(shù)

2. 1 字節(jié)長的有符號整數(shù)

3. 3 字節(jié)長的有符號整數(shù)

4. int16_t 類型整數(shù)

5. int32_類型整數(shù)

6. int64_t 類型整數(shù)

普通存儲格式下和壓縮列表存儲格式下的不同點(diǎn):

列表存儲結(jié)構(gòu)典型的為雙端鏈表,每一個值都是用一個節(jié)點(diǎn)來表示,每個節(jié)點(diǎn)都會有指向前一個節(jié)點(diǎn)和后一個節(jié)點(diǎn)的指針,以及指向節(jié)點(diǎn)包含的字符串值的指針。而字符串值又分為 3 個部分存儲,第一部分存儲字符串長度,第二部分存儲字符串值中剩余可用的字節(jié)量,第三部分存儲的則是字符串?dāng)?shù)據(jù)本身。所以一個節(jié)點(diǎn)往往都需要存儲 3 個指針、2 個記錄字符串信息的整數(shù)、字符串本省和一個額外的字節(jié)。總體上額外的開銷是很大的(21 字節(jié))。

壓縮列表節(jié)點(diǎn)的格式:

Redis 壓縮列表的示例分析

每一個節(jié)點(diǎn)都有 previous_entry_length,encoding,content 三個部分組成,在遍歷壓縮列表的時候是從后往前遍歷的。

1. previous_entry_length 記錄了前一個節(jié)點(diǎn)的長度,只要用當(dāng)前指針減去這個值就可以達(dá)到前一個節(jié)點(diǎn)的起始地址。

2. encoding 記錄了節(jié)點(diǎn) content 屬性所保存數(shù)據(jù)的類型和長度

Redis 壓縮列表的示例分析

3. content 記錄了一個節(jié)點(diǎn)的值

顯然壓縮列表這種方式節(jié)約了不少存儲空間。但同時也會引發(fā)下面的問題。

四、連鎖更新的問題:

一般而言如果前一個節(jié)點(diǎn)的整體長度小于 254 字節(jié),previous_entry_length 屬性只需要 1 個字節(jié)的空間來保存這個長度值。而當(dāng)前一個節(jié)點(diǎn)大于 254 字節(jié)的時候,previous_entry_length 屬性要用 5 個字節(jié)長的空間來記錄長度值。

當(dāng)長度為 254 字節(jié)左右的節(jié)點(diǎn)前插入一個新的節(jié)點(diǎn)的時候,需要增加 previous_entry_length 來記錄這個節(jié)點(diǎn)到新節(jié)點(diǎn)的偏移量。這個時候,這個節(jié)點(diǎn)的長度肯定就大于 254 字節(jié)了。所以這個節(jié)點(diǎn)的后一個節(jié)點(diǎn)就不能只用一個字節(jié)的 previous_entry_length 來記錄這個節(jié)點(diǎn)的信息了,而是需要 5 個字節(jié)來記錄。如果連續(xù)多個節(jié)點(diǎn)的長度都為 254 字節(jié)左右,在其中的某一個節(jié)點(diǎn)前 / 后發(fā)生節(jié)點(diǎn)的插入和刪除(刪除的推理與插入相反,原本用 5 字節(jié)記錄前一節(jié)點(diǎn)的可能變?yōu)?1 字節(jié)),都可能引發(fā)連鎖的更新,顯然,這樣對系統(tǒng)地運(yùn)行效率是很不利的。不過,在實(shí)際應(yīng)用中這種情況還是比較少發(fā)生的。

而雙端鏈表在節(jié)點(diǎn)的更新、增加和刪除上顯得就會“輕松”很多了。因為每一個節(jié)點(diǎn)存儲的信息都是相對獨(dú)立的。

實(shí)踐意義:

要預(yù)估一個節(jié)點(diǎn)大概占據(jù)多少字節(jié)的存儲空間,適當(dāng)?shù)卣{(diào)整字段的存儲格式而不要使存儲的字段值占據(jù)存儲空間落在 254 字節(jié)(除去 encoding 屬性和 previous_entry_length 屬性)左右。

Redis 中查看字符串和哈希鍵值的長度相關(guān)命令:

1. 查詢字符串鍵對應(yīng)的值長度

命令:

Strlen

例如:

127.0.0.1:6379 strlen m_name

(integer) 8

2. 查詢哈希鍵某一個域長度

命令:

Hstrlen

例如:

127.0.0.1:6379 hstrlen good_list good_list1

(integer) 226

五、Conf 文件配置:

通過修改配置文件,可以控制是否使用壓縮列表存儲相關(guān)鍵的最大元素個數(shù)和最大元素的大小

Conf 文件中的配置:
1.

[] -max-ziplist-entries:表示對于鍵的最大元素個數(shù),即一個鍵中在該指定值下的數(shù)量的節(jié)點(diǎn)個數(shù)都會用壓縮列表來儲存

[] -max-ziplist-value:表示壓縮列表中每個節(jié)點(diǎn)的最大體積是多少字節(jié)

實(shí)際使用中,一個列表鍵 / 哈希鍵的某一個元素往往存儲著比較大的信息量,會大于 64 字節(jié),所以配置時很有可能會比 64 大,同時考慮到實(shí)際存儲數(shù)據(jù)的容量大小以及上面談到的 previous_entry_length 的大小問題,對 [] -max-ziplist-value 進(jìn)行合理的配置。

配置文件內(nèi)容:

############## ADVANCED CONFIG ##########################
# Hashes are encoded using a memory efficient data structure when they have a
# small number of entries, and the biggest entry does not exceed a given
# threshold. These thresholds can be configured using the following directives.
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
有序集合鍵
# Similarly to hashes and lists, sorted sets are also specially encoded in
# order to save a lot of space. This encoding is only used when the length and
# elements of a sorted set are below the following limits:
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
列表鍵,比較特殊,直接使用制定大小 kb 字節(jié)數(shù)表示(有些 conf 文件的列表鍵與 hash 鍵的表達(dá)式?jīng)]太大區(qū)別)# Lists are also encoded in a special way to save a lot of space.
# The number of entries allowed per internal list node can be specified
# as a fixed maximum size or a maximum number of elements.
# For a fixed maximum size, use -5 through -1, meaning:
# -5: max size: 64 Kb -- not recommended for normal workloads
# -4: max size: 32 Kb -- not recommended
# -3: max size: 16 Kb -- probably not recommended
# -2: max size: 8 Kb -- good
# -1: max size: 4 Kb -- good
# Positive numbers mean store up to _exactly_ that number of elements
# per list node.
# The highest performing option is usually -2 (8 Kb size) or -1 (4 Kb size),
# but if your use case is unique, adjust the settings as necessary.
list-max-ziplist-size -2

案例:

修改配置前使用默認(rèn)配置:

hash-max-ziplist-entries 512

hash-max-ziplist-value 64

127.0.0.1:6379 hstrlen good_list good_list1

(integer) 226

127.0.0.1:6379 object encoding good_list

hashtable

修改配置:

hash-max-ziplist-entries 512

hash-max-ziplist-value 254

注意:修改配置后需要重啟服務(wù)器

127.0.0.1:6379 hstrlen good_list good_list1

(integer) 226

127.0.0.1:6379 object encoding good_list

ziplist

可以看到存儲方式已將變?yōu)?ziplist

較官方的壓力測試和指導(dǎo)建議:

當(dāng)一個壓縮列表的元素數(shù)量上升到幾千(實(shí)際使用可能遠(yuǎn)小于這個值)的時候,壓縮列表的性能可能會下降,因為 Redis 在操作這種結(jié)構(gòu)的時候,編解碼會出現(xiàn)一定的壓力。

壓縮列表的長度限制在 500-2000 之內(nèi),每個元素體積限制在 128 字節(jié)或以下,壓縮列表的的性能都會處于合理范圍之內(nèi)。

感謝你能夠認(rèn)真閱讀完這篇文章,希望丸趣 TV 小編分享 Redis 壓縮列表的示例分析內(nèi)容對大家有幫助,同時也希望大家多多支持丸趣 TV,關(guān)注丸趣 TV 行業(yè)資訊頻道,遇到問題就找丸趣 TV,詳細(xì)的解決方法等著你來學(xué)習(xí)!

向 AI 問一下細(xì)節(jié)

丸趣 TV 網(wǎng) – 提供最優(yōu)質(zhì)的資源集合!

正文完
 
丸趣
版權(quán)聲明:本站原創(chuàng)文章,由 丸趣 2023-12-18發(fā)表,共計4564字。
轉(zhuǎn)載說明:除特殊說明外本站除技術(shù)相關(guān)以外文章皆由網(wǎng)絡(luò)搜集發(fā)布,轉(zhuǎn)載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 汉寿县| 板桥市| 新巴尔虎左旗| 聂荣县| 新平| 万荣县| 天镇县| 邢台市| 略阳县| 特克斯县| 黑水县| 满洲里市| 田东县| 林口县| 东方市| 东乌珠穆沁旗| 科尔| 亳州市| 高州市| 武宁县| 鲁甸县| 南通市| 钦州市| 台江县| 湘西| 曲麻莱县| 土默特左旗| 佳木斯市| 册亨县| 宣威市| 邻水| 宁津县| 济源市| 建德市| 廊坊市| 贵定县| 孝感市| 凌源市| 嘉鱼县| 藁城市| 平果县|