最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Redis?ziplist?壓縮列表的源碼解析

 更新時間:2022年06月30日 15:36:22   作者:一七令  
ziplist 是一個經(jīng)過特殊編碼的雙向鏈表,旨在提高內(nèi)存效率,它存儲字符串和整數(shù)值,其中整數(shù)被編碼為實際整數(shù)而不是一系列字符,這篇文章主要介紹了Redis?ziplist?壓縮列表的源碼解析,需要的朋友可以參考下

前言

相信對使用過 Redis 的人來說,數(shù)據(jù)類型 List 是不會陌生的吧。大多數(shù)人需要實現(xiàn)一個隊列時候,首選的就是 List 了。但是其實 Redis 的 List 類型有多種實現(xiàn)方式。這篇文章就是介紹其中一種實現(xiàn) ziplist - 壓縮列表。

源碼解讀

一如既往,關(guān)于 ziplist 的定義和實現(xiàn)還是放在一對文件中,分別是 ziplist.h 和 ziplist.c。在 ziplist.c 文件的頭部有著這么一段注釋介紹什么是 ziplist。

ziplist 是一個經(jīng)過特殊編碼的雙向鏈表,旨在提高內(nèi)存效率。 它存儲字符串和整數(shù)值,其中整數(shù)被編碼為實際整數(shù)而不是一系列字符。 它允許在 O(1) 時間內(nèi)在列表的任一側(cè)進行推送和彈出操作。 但是,由于每個操作都需要重新分配 ziplist 使用的內(nèi)存,因此實際復(fù)雜性與 ziplist 使用的內(nèi)存量有關(guān)。

從這段話得到:對于不同的數(shù)據(jù)類型有著不同的編碼方式,理解為會對數(shù)據(jù)進行壓縮,從而達到減少內(nèi)存使用的目的。但是隨著存儲的 value 數(shù)據(jù)級增加,使用 ziplist 所付出的代價也隨之增加。

ziplist 布局

ziplist 是一個特殊雙向鏈表,不像普通的鏈表使用前后指針關(guān)聯(lián)在一起,它是存儲在連續(xù)內(nèi)存上的。整體的結(jié)構(gòu)布局如下圖:

  • zlbytes: 32 位無符號整型,記錄 ziplist 整個結(jié)構(gòu)體的占用空間大小。當然了也包括 zlbytes 本身。這個結(jié)構(gòu)有個很大的用處,就是當需要修改 ziplist 時候不需要遍歷即可知道其本身的大小。 這個 SDS 中記錄字符串的長度有相似之處,這些好的設(shè)計往往在平時的開發(fā)中可以采納一下。
  • zltail: 32 位無符號整型, 記錄整個 ziplist 中最后一個 entry 的偏移量。所以在尾部進行 POP 操作時候不需要先遍歷一次。
  • zllen: 16 位無符號整型, 記錄 entry 的數(shù)量, 所以只能表示 2^16。但是 Redis 作了特殊的處理:當實體數(shù)超過 2^16 ,該值被固定為 2^16 - 1。 所以這種時候要知道所有實體的數(shù)量就必須要遍歷整個結(jié)構(gòu)了。
  • entry: 真正存數(shù)據(jù)的結(jié)構(gòu)。
  • zlend: 8 位無符號整型, 固定為 255 。為 ziplist 的結(jié)束標識。

entry 節(jié)點

每個 entry 都包含兩條信息的元數(shù)據(jù)為前綴。 第一元數(shù)據(jù)用來存儲前一個 entry 的長度,以便能夠從后向前遍歷列表。 第二元數(shù)據(jù)是表示 entry 的編碼形式。 用來表示 entry 類型,整數(shù)或字符串,在字符串的情況下,它還表示字符串有效的長度。

所以一個完整的 ziplist 是這樣存儲的:

prelen

記錄前一個 entry 的長度。若前一個 entry 的長度小于 254 , 則使用 1 個字節(jié)的 8 位無符號整數(shù)來表示。

若前一個 entry 長度大于等于 254,則使用 5 個字節(jié)來表示。第 1 個字節(jié)固定為 254 (FE) 作為標識,剩余 4 字節(jié)則用來表示前一個 entry 的實際大小。

所以兩種情況下的 entry 結(jié)構(gòu)如下所示:

1. 前一個 entry 大小不超過 253。
<prevlen from 0 to 253> <encoding> <entry>
2. 前一個 entry 大小超過 253。
0xFE <4 bytes unsigned little endian prevlen> <encoding> <entry>

encoding 編碼

entry 的編碼字段取決于具體值的內(nèi)容,分為字符串、數(shù)字兩種類型單獨處理。

一、當 entry 是字符串時,有 3 種編碼方式。編碼第 1 個字節(jié)的前 2 位將保存用于存儲字符串長度的編碼類型,后面是字符串的實際長度。

1. 長度小于或等于 63 字節(jié)(6 位)的字符串值。 “pppppp”表示無符號的 6 位數(shù)據(jù)長度。
|00pppppp| - 1 byte
2. 長度小于或等于 16383 字節(jié)(14 位)的字符串值。14 位的數(shù)據(jù)采用  big endian 存儲。
big endian 是一種字節(jié)序方式,有Little-Endian、Big-Endian兩種。
|01pppppp|qqqqqqqq| - 2 bytes
3. 長度大于或等于 16384 字節(jié)的字符串值。
采用 big endian 存儲且可表示的字符串長度最大2^32-1,所以第一個字節(jié)沒有用到,所以低6位沒有用,所以都是0。
|10000000|qqqqqqqq|rrrrrrrr|ssssssss|tttttttt| - 5 bytes 

二、當 entry 是整數(shù)時,有 6 種編碼方式。前 2 位都固定為 1,接下來的 2 位用于指定將在此標頭后存儲哪種類型的整數(shù)。

與 ziplist 標頭一樣,所有整數(shù)都以 Little-Endian 序表示,即使此代碼是在 Big-Endian 系統(tǒng)中編譯的。

1. 整數(shù)編碼為 int16_t(2 字節(jié))。
|11000000| - 3 bytes
2. 整數(shù)編碼為int32_t(4個字節(jié))。
|11010000| - 5 bytes
3. 整數(shù)編碼為 int64_t(8 字節(jié))。
|11100000| - 9 bytes
4. 整數(shù)編碼為24位帶符號(3個字節(jié))。
|11110000| - 4 bytes
5. 整數(shù)編碼為 8 位有符號(1 字節(jié))。
|11111110| - 2 bytes
6. 0到12的無符號整數(shù)。編碼后的值實際上是1到13,因為0000和1111不能用,所以要從編碼后的4位值中減去1才能得到正確的值。
|1111xxxx| - (with xxxx between 0001 and 1101) immediate 4 bit integer

三、結(jié)尾編碼標識

1. 表示 ziplist 結(jié)尾的標識。
|11111111|

總結(jié)

  • ziplist 為了節(jié)省內(nèi)存,采用了緊湊的連續(xù)存儲。所以在修改操作下并不能像一般的鏈表那么容易,需要從新分配新的內(nèi)存,然后復(fù)制到新的空間。
  • ziplist 是一個雙向鏈表,可以在時間復(fù)雜度為O(1)從下頭部、尾部進行pop或push。
  • 可能會出現(xiàn)連鎖更新現(xiàn)象。

其實使用中并沒有直接操作這種數(shù)據(jù)結(jié)構(gòu),但是可以設(shè)置何種情況下使用它??梢栽?Redis 的配置文件中進行設(shè)置。

如有以下可選設(shè)置項:

  • hash-max-ziplist-entries:hash 類型元素數(shù)量超過指定數(shù)據(jù)后時候。使用 hash 存儲, 否則使用壓縮表。
  • hash-max-ziplist-value: hash 類型元素長度超過指定數(shù)據(jù)后時候。 使用 hash 存儲,否則使用壓縮鏈表。
  • zset-max-ziplist-entries:zset 類型 壓縮列表 ziplist 最大限制元素數(shù)。超過指定值將會使用跳表 skiplist + dict 來存儲。
  • zset-max-ziplist-value:set 類型 壓縮列表 ziplist 最大限制大小。超過指定將會使用跳表 skiplist+dict 來存儲。

到此這篇關(guān)于Redis ziplist 壓縮列表的源碼解析的文章就介紹到這了,更多相關(guān)Redis ziplist 壓縮列表內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Redis安裝與使用方法小結(jié)

    Redis安裝與使用方法小結(jié)

    這篇文章主要介紹了Redis安裝與使用方法,結(jié)合實例形式分析了Redis數(shù)據(jù)庫的下載、安裝、啟動、設(shè)置及相關(guān)使用操作注意事項,需要的朋友可以參考下
    2018-04-04
  • Redis數(shù)據(jù)庫的安裝和配置教程詳解

    Redis數(shù)據(jù)庫的安裝和配置教程詳解

    這篇文章主要介紹了Redis數(shù)據(jù)庫的安裝和配置?,主要包括Linux環(huán)境安裝Redis和windows環(huán)境安裝Redis,redis客戶端安裝方法,本文通過圖文并茂的形式給大家介紹的非常詳細,需要的朋友可以參考下
    2022-05-05
  • Redis緩存常用4種策略原理詳解

    Redis緩存常用4種策略原理詳解

    這篇文章主要介紹了Redis緩存常用4種策略原理詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-08-08
  • 利用yum安裝Redis的方法詳解

    利用yum安裝Redis的方法詳解

    Redis是一個開源的使用ANSI C語言編寫、支持網(wǎng)絡(luò)、可基于內(nèi)存亦可持久化的日志型、Key-Value數(shù)據(jù)庫,并提供多種語言的API。從2010年3月15日起,Redis的開發(fā)工作由VMware主持。這篇文章主要介紹的是利用yum安裝Redis的方法,有需要的朋友們可以參考借鑒,下面來一起看看吧
    2016-11-11
  • RabbitMQ+redis+Redisson分布式鎖+seata實現(xiàn)訂單服務(wù)的流程分析

    RabbitMQ+redis+Redisson分布式鎖+seata實現(xiàn)訂單服務(wù)的流程分析

    訂單服務(wù)涉及許多方面,分布式事務(wù),分布式鎖,例如訂單超時未支付要取消訂單,訂單如何防止重復(fù)提交,如何防止超賣、這里都會使用到,這篇文章主要介紹了RabbitMQ+redis+Redisson分布式鎖+seata實現(xiàn)訂單服務(wù)的流程分析,需要的朋友可以參考下
    2024-07-07
  • Redis分片集群存儲的搭建到使用

    Redis分片集群存儲的搭建到使用

    這篇文章主要介紹了Redis分片集群存儲的搭建到使用,分片集群顧名思義,將數(shù)據(jù)分開存儲到Redis集群中,這樣能夠存儲更多的數(shù)據(jù),避免浪費資源,需要的朋友可以參考下
    2022-06-06
  • 詳解Redis SCAN命令實現(xiàn)有限保證的原理

    詳解Redis SCAN命令實現(xiàn)有限保證的原理

    這篇文章主要介紹了Redis SCAN命令實現(xiàn)有限保證的原理,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值 ,需要的朋友可以參考下
    2019-07-07
  • Redis如何實現(xiàn)刷票過濾

    Redis如何實現(xiàn)刷票過濾

    這篇文章主要介紹了Redis如何實現(xiàn)刷票過濾問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-03-03
  • Redis Redisson lock和tryLock的原理分析

    Redis Redisson lock和tryLock的原理分析

    這篇文章主要介紹了Redis Redisson lock和tryLock的原理分析,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-04-04
  • Redis主從復(fù)制分步講解使用

    Redis主從復(fù)制分步講解使用

    Redis因為其高性能和易用性在我們后端的服務(wù)中發(fā)揮了巨大的作用,并且很多重要功能的實現(xiàn)都會依賴redis,本篇我們來了解Redis高可用主從復(fù)制,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2022-09-09

最新評論

陕西省| 遂宁市| 云浮市| 大化| 遵义县| 东乡族自治县| 东光县| 顺昌县| 岳西县| 河北区| 加查县| 邻水| 浏阳市| 宜君县| 无棣县| 安陆市| 丰镇市| 北辰区| 桂东县| 酉阳| 团风县| 建瓯市| 措勤县| 望奎县| 呈贡县| 台安县| 高密市| 银川市| 浠水县| 阳春市| 栖霞市| 聂荣县| 墨江| 卓资县| 扎赉特旗| 深圳市| 碌曲县| 南木林县| 体育| 富裕县| 乌拉特中旗|