Redis數據結構ZipList,QuickList,SkipList

目錄

1.ZipList

1.2.解析Entry:

1.3Encoding編碼

1.4.ZipList連鎖更新問題

2.QuickList

SkipList跳表

RedisObject

五種數據類型


1.ZipList

redis中的ZipList是一種緊湊的內存儲存結構,主要可以節省內存空間儲存小規模數據。是一種特殊的雙端鏈表,有一系列連續的內存組成,可以在任意一端進行壓入/彈出操作,而且操作的時間復雜度為O(1)

常見方法:

LPUSH mylist "value1" "value2"    //左邊插入
RPUSH mylist "value3" "value4"    //右邊插入LPOP mylist    //從鏈表最左端彈出數據
RPOP mylist    //從鏈表最右端彈出數據LRANGE mylist 0 2    //獲取左邊指定范圍的數據
LINDEX mylist 0    //獲取指定下標數據LLEN mylist    //獲取列表長度
zlbyteszltailzllenentry

...

entryentryzlend
屬性類型長度用途
zlbytesuint32_t4字節記錄整個壓縮鏈表占用的內存字節數
zltailuint32_t4字節這個是偏移量,記錄壓縮列表尾節點到列表起始地址有多少字節,通過這個偏移量,可以確定尾節點地址
zllenuint16_t2字節記錄列表包含的節點數量。最大65534,如果超出也只是65535
entry列表節點不定各個節點的長度由節點保存的內容確定
zlenduint8_t1字節特殊值0xFF(255),用于標記壓縮例表的末端
1.2.解析Entry:

ZipList的Entry不像普通鏈表那樣記錄前后節點的指針,因為記錄前后節點指針需要16字節,大大浪費了內存。所以采用下面的結構來保存。

previous_entry_lengthencoding

content

1.previous_entry_length:前一節點的長度,占1字節 或 5字節

當前一節點長度 < 254字節,采用 1字節保存這個長度值

當前一節點的長度 > 254字節,采用5字節保存這個長度值

2.encoding:編碼屬性,記錄content的數據類型(數字/字符串)及長度,占用1,2,5字節。

3.contents:負責保存具體的內容,可以是數字可以是字符串

注意:ZipList中所有儲存長度的數值均采用小端字節序儲存,低位在前,高位字節在后。

列如:0x1234,采用小端字節序后就是 0x3412

1.3Encoding編碼

encoding編碼分為兩種:字符串和數字

字符串:encoding以00,01,10開頭標識儲存的是字符串。

下面長度不同的字符串對應encoding編碼格式

舉例:儲存字符串ab,bc

1.4.ZipList連鎖更新問題

ZipList的每個Entry都包含previous_entry_length來記錄上一節點大小,長度為1個或5字節。

>>如果前一節點長度 < 254,那么采用1字節保存這個長度值。

>>如果前一節點 >= 254,則采用5字節保存這個長度值。

如果有N個連續的長度為250~253之間的entry,如果不巧有一個擴展那么又可能發生連鎖反應,又可能所有都發生連鎖更新,新增,刪除都可能導致連鎖更新發生

總結:

1.壓縮列表可以看作連續內存空間的“雙向鏈表“

2.列表的節點之間不是通過指針鏈接,而是上一節點和本節點長度來尋址,大大節省內存

3.如果數據過多,鏈表過長,可能影響查詢性能

4.增加刪除都可能發生連續更新問題


2.QuickList

ZIpList雖然節省內存,但是申請內存必須是連續空間,如果內存占用過多那么申請效率變低

數據量過大超出上限采用分片儲存數據,那么這些ZipList如何聯系?

Redis3.2版本引入QuickList,是一個雙端鏈表,只不過每個節點都是ZipList

Redis提供配置:list-max-ziplist-size?

如果值是正:代表ZipList允許的最大entry數。

如果值是負:代表每個ZipList的最大內存大小。

-1-2-3-4-5
4kb8kb16kb32kb64kb

QuickList可以控制首尾是否進行壓縮,通過配置項list-compress-depth來控制,這個參數是控制首尾不壓縮的節點個數。

012
代表首尾節點不壓縮首尾各有一個1個不壓縮,中間全壓縮首尾各有2節點不壓縮,中間全壓縮

QuickList 和 Quick List Node的結構源碼:

QuickList結構圖:

QuickList特性:

1.每個節點都是ZipList的雙端鏈表

2.節點采用ZipList,解決傳統鏈表的內存占用

3.控制ZipList大小,解決傳統連續內存空間申請問題

4.中間節點可壓縮,節省內存


SkipList跳表

是個鏈表,但不是普通鏈表,不同節點之間跨度不一樣。

1.元素按照升序排列儲存

2.節點可能包含多個指針,指針跨度不同

為了更快的找到所需要的元素,SkipList采用這種結構類似于二分查找。

以下是結構源碼:

// t_zset.c
typedef struct zskiplist {// 頭尾節點指針struct zskiplistNode* header, * tail;// 節點數量unsigned long length;// 最大的索引層級,默認是1int level;
} zskiplist;// t_zset.c
typedef struct zskiplistNode {sds ele; // 節點存儲的值double score;// 節點分數,排序、查找用struct zskiplistNode* backward; // 前一個節點指針struct zskiplistLevel {struct zskiplistNode* forward; // 下一個節點指針unsigned long span; // 索引跨度} level[]; // 多級索引數組
} zskiplistNode;

特性:

1.跳表是一個雙向鏈表,每個節點包含存儲的值和排序用的socre,用來保存別的節點的ele數組

2.節點按照score值排序,score值一樣按照ele字典排序

3.每層指針到下一節點跨度不同,層級越高跨度越大

4.增刪改查的效率與紅黑樹基本一致


RedisObject

在Redis中任意數據類型的鍵和值都會被封裝在一個RedisObject中,也叫做Redis對象。

Redis會根據儲存不同的數據類型選擇不同的編碼格式,共包含11種不同類型。

編號編碼方式說明
0OBJ_ENCODING_RAW動態字符串(動態長度,非預分配)
1OBJ_ENCODING_INT長整型(用?long?類型存儲)
2OBJ_ENCODING_HT哈希表(字典,基于?dict?實現)
3OBJ_ENCODING_ZIPMAP已廢棄的哈希壓縮結構
4OBJ_ENCODING_LINKEDLIST雙端鏈表(舊版 List 實現)
5OBJ_ENCODING_ZIPLIST壓縮列表(緊湊的二進制結構)
6OBJ_ENCODING_INTSET整數集合(僅存儲整數的有序集合)
7OBJ_ENCODING_SKIPLIST跳表(有序集合的底層實現之一)
8OBJ_ENCODING_EMBSTR短字符串(固定長度,預分配內存)
9OBJ_ENCODING_QUICKLIST快速列表(雙向鏈表 + 壓縮列表)
10OBJ_ENCODING_STREAMStream 流(消息隊列結構)

五種數據類型

String基于簡單動態字符串SDS實現,存儲上限為512mb,基本編碼方式是RAM

List可以從首尾操作列表中的元素,3.2版本后統一采用QuickList來實現List

Set:

1.為了查詢效率和唯一性,采用Dict編碼,key為存儲元素,value統一為null

2.所有數據都是整數,且元素數量不超過set-max-intset-entries,Set會采用IntSet編碼

ZSet:

ZSet就是SortedSet,其中每個元素都需指定一個score 和 member值

可以根據score排序,且member必須唯一,可以根據member查詢分數

當元素數數量小時,采用ZipList來節省內存,但是需要滿足兩個條件:

1.元素數量小于 zset_max_ziplist_entries (128)

2.每個元素都小于zset_max_ziplist_value(64)

當數據量大時采用SkipList和HT結構

Hash:

hash底層的編碼和ZSet基本一致,只需要把排序有關的SkipList去掉就行。

1.數據量小時,采用ZipList編碼節省內存,ZipList中相鄰的兩個entry保存field和value

2.數據量大時,采用HT編碼,就是Dict,觸發條件是:元素數量超過512,每個entry超過64字節

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/81937.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/81937.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/81937.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

laravel 12 監聽syslog消息,并將消息格式化后存入mongodb

在Laravel 12中實現監聽Syslog消息并格式化存儲到MongoDB&#xff0c;需結合日志通道配置、Syslog解析和MongoDB存儲操作。以下是具體實現方案&#xff1a; 一、環境配置 安裝MongoDB擴展包 執行以下命令安裝必要的依賴&#xff1a; composer require jenssegers/mongodb ^4.0確…

【STM32項目實戰】一文了解單片機的SPI驅動外設功能

前言&#xff1a;在前面我有文章介紹了關于單片機的SPI外設CUBEMX配置&#xff0c;但是要想使用好SPI這個外設我們還必須對其原理性的時序有一個詳細的了解&#xff0c;所以這篇文章就補充一下SPI比較偏向底層的時序性的邏輯。 1&#xff0c;SPI簡介 SPI是MCU最常見的對外通信…

【挖洞利器】GobyAwvs解放雙手

【滲透測試工具】解放雙手&Goby配合Awvs滲透測試利器\x0a通過Goby和Awvs 解放雙手https://mp.weixin.qq.com/s/SquRK8C5cRpWmfGbIOqxoQ

LangChain4j(15)——RAG高級之跳過檢索

之前的文章中&#xff0c;我們介紹了RAG的使用&#xff0c;但是&#xff0c;每次提問時&#xff0c;都會通過RAG進行檢索。有時&#xff0c;檢索是不必要執行的&#xff0c;比如&#xff0c;當用戶只是說“你好”時。于是&#xff0c;我們需要有條件的跳過檢索過程。 跳過決策…

【SDRS】面向多模態情感分析的情感感知解糾纏表征轉移

abstract 多模態情感分析(MSA)旨在利用多模態的互補信息對用戶生成的視頻進行情感理解。現有的方法主要集中在設計復雜的特征融合策略來整合單獨提取的多模態表示,忽略了與情感無關的信息的干擾。在本文中,我們提出將單模表征分解為情感特定特征和情感獨立特征,并將前者融…

Sui 上線兩周年,掀起增長「海嘯」

兩年前的 5 月 3 日&#xff0c;Sui 的主網正式發布&#xff0c;將在開發網和測試網上驗證過的下一代技術承諾變為現實。這一新興網絡旨在優化現有區塊鏈技術&#xff0c;結合高性能計算環境與安全性、可驗證性及韌性。 隨著 Sui 迎來兩周年&#xff0c;這股浪潮已成長為「海嘯…

深入理解 mapper-locations

mybatis-plus.mapper-locations: classpath*:/mapper/**/*.xml 是 MyBatis/MyBatis-Plus 在 Spring Boot 配置文件&#xff08;如 application.yml 或 application.properties&#xff09;中的一項關鍵配置&#xff0c;用于指定 MyBatis Mapper XML 文件的存放路徑。以下是詳細…

電容的作用

使用多個電容是從電容的實際等效模型去考慮的(也就是從SI&#xff0c;信號完整性方面&#xff09;。只考慮一個實際電容時&#xff0c;它的阻抗曲線是一個類似于倒三角形的形狀&#xff0c;只在諧振頻率點(與等效串聯電感形成)處的阻抗最小。因此相當于只在這一個頻率點處及附近…

移植的本質是什么

有斷時間我就在想&#xff0c;為什么freertos&#xff0c;lvgl等等的移植都是把庫文件放進來&#xff0c;直接點擊編譯&#xff0c;然后把bug都處理完成就移植成功了&#xff0c;為什么呢&#xff1f; 明明我一個函數都沒調用&#xff0c;為什么會有一堆錯誤&#xff0c;莫名其…

廣告場景下的檢索平臺技術

檢索方向概述 數據檢索領域技術選型大體分為SQL事務數據庫、NoSQL數據庫、分析型數據庫三個類型。 SQL數據庫的設計思路是采用關系模型組織數據&#xff0c;注重讀寫操作的一致性&#xff0c;注重數據的絕對安全。為了實現這一思路&#xff0c;SQL數據庫往往會犧牲部分性能&…

高頻PCB設計如何選擇PCB層數?

以四層板為例&#xff0c;可以第一層和第二層畫信號&#xff0c;作為信號層。 第三層可以走電源&#xff0c;然后第四層走GND 但是更可以第一層和第三層畫信號。第二層可以走電源&#xff0c;然后第四層走GND 用中間的電源層以及地層可以起到屏蔽的作用&#xff0c;有效降低寄…

[Linux_69] 數據鏈路層 | Mac幀格式 | 局域網轉發 | MTU MSS

目錄 0.引入 1.以太網幀格式 2.重談局域網轉發的原理(基于協議) 小結 3.認識MTU 3.1MTU對IP協議的影響 3.2MTU對UDP協議的影響 3.3MTU對于TCP協議的影響 0.引入 在去年的這篇文章中&#xff0c;我們有對網絡進行過一個概述[Linux#47][網絡] 網絡協議 | TCP/IP模型 | 以…

vue2 provide 后 inject 數據不是響應式的,不實時更新

今天用 provide 后&#xff0c;inject 獲取數據時不是實時更新的&#xff0c;獲取的不是更新后的值 祖父組件 <div style"text-align: left !important;"><button click"change">更改</button> </div>data() {return {name: ini…

洛谷---P1629 郵遞員送信

題目描述 有一個郵遞員要送東西&#xff0c;郵局在節點 1。他總共要送 n?1 樣東西&#xff0c;其目的地分別是節點 2 到節點 n。由于這個城市的交通比較繁忙&#xff0c;因此所有的道路都是單行的&#xff0c;共有 m 條道路。這個郵遞員每次只能帶一樣東西&#xff0c;并且運…

2025年LangChain(V0.3)開發與綜合案例

LangChain是什么&#xff1f; 在實際企業開發中&#xff0c;大模型應用往往比簡單的問答要復雜得多。如果只是簡單地向大模型提問并獲取回答&#xff0c;那么大模型的許多強大功能都沒有被充分利用。 要開始使用LangChain&#xff0c;首先需要安裝相關的庫&#xff1a; pip …

十分鐘了解 @MapperScan

MapperScan 是 MyBatis 和 MyBatis-Plus 提供的一個 Spring Boot 注解&#xff0c;用于自動掃描并注冊 Mapper 接口&#xff0c;使其能夠被 Spring 容器管理&#xff0c;并與對應的 XML 或注解 SQL 綁定。它的核心作用是簡化 MyBatis Mapper 接口的配置&#xff0c;避免手動逐個…

深度解析 MindTorch:無縫遷移 PyTorch 到 MindSpore 的高效工具

在深度學習領域&#xff0c;框架的選擇往往取決于開發者的習慣、硬件支持以及項目需求。PyTorch 作為當前最受歡迎的深度學習框架之一&#xff0c;以其動態圖機制和簡潔的 API 設計深受開發者喜愛。然而&#xff0c;隨著昇騰硬件的崛起&#xff0c;如何高效地利用昇騰的強大計算…

[250506] Auto-cpufreq 2.6 版本發布:帶來增強的 TUI 監控及多項改進

目錄 Auto-cpufreq 2.6 版本發布&#xff1a;帶來增強的 TUI 監控及多項改進 Auto-cpufreq 2.6 版本發布&#xff1a;帶來增強的 TUI 監控及多項改進 Auto-cpufreq&#xff0c;一款適用于 Linux 的免費開源自動 CPU 速度與功耗優化器&#xff0c;已發布其最新版本 2.6。該工具…

Linux 更改內存交換 swap 為 zram 壓縮,減小磁盤寫入

1、查看當前 swap 的方式 swapon --show 我這里是默認的 swap 文件&#xff0c;大小為 2G。 2、安裝 zram Ubuntu 下&#xff1a; sudo apt install zram-tools安裝后默認會啟動&#xff1a; 3、關閉默認的 swap 文件 sudo swapoff /swapfile 其次是關閉 /etc/fstab 中的 …

ORCAD打印pdf

1 筆記本電腦綁定了打印機&#xff0c;要改成這個