redis筆記:壓縮列表

本人博客同步發(fā)表,排版更佳

概述

  • 壓縮列表是列表、哈希的底層實(shí)現(xiàn)之一
  • 當(dāng)列表只包含少量列表項(xiàng),并且要么是小整數(shù)值、短字符串時(shí),采用壓縮列表
  • 哈希表只包含少量鍵值對(duì),鍵值對(duì)的鍵和值要么都是小整數(shù)、短字符串,采用壓縮列表實(shí)現(xiàn)哈希
<zlbytes> 是一個(gè)無(wú)符號(hào)整數(shù),保存著 ziplist 使用的內(nèi)存數(shù)量。
通過(guò)這個(gè)值,程序可以直接對(duì) ziplist 的內(nèi)存大小進(jìn)行調(diào)整,
而無(wú)須為了計(jì)算 ziplist 的內(nèi)存大小而遍歷整個(gè)列表。

<zltail> is the offset to the last entry in the list. This allows a pop
operation on the far side of the list without the need for full traversal.

<zltail> 保存著到達(dá)列表中最后一個(gè)節(jié)點(diǎn)的偏移量。
這個(gè)偏移量使得對(duì)表尾的 pop 操作可以在無(wú)須遍歷整個(gè)列表的情況下進(jìn)行。

<zllen> is the number of entries.When this value is larger than 2**16-2,
we need to traverse the entire list to know how many items it holds.

<zllen> 保存著列表中的節(jié)點(diǎn)數(shù)量。
當(dāng) zllen 保存的值大于 2**16-2 時(shí),
程序需要遍歷整個(gè)列表才能知道列表實(shí)際包含了多少個(gè)節(jié)點(diǎn)。

<zlend> is a single byte special value, equal to 255, which indicates the
end of the list.

<zlend> 的長(zhǎng)度為 1 字節(jié),值為 255 ,標(biāo)識(shí)列表的末尾。
  • 每個(gè) ziplist 節(jié)點(diǎn)的前面都帶有一個(gè) header ,這個(gè) header 包含兩部分信息:
    • 前置節(jié)點(diǎn)的長(zhǎng)度,在程序從后向前遍歷時(shí)使用。
    • 當(dāng)前節(jié)點(diǎn)所保存的值的類型和長(zhǎng)度。

編碼前置節(jié)點(diǎn)的長(zhǎng)度的方法如下:

  1. 如果前置節(jié)點(diǎn)的長(zhǎng)度小于 254 字節(jié),那么程序?qū)⑹褂?1 個(gè)字節(jié)來(lái)保存這個(gè)長(zhǎng)度值。

  2. 如果前置節(jié)點(diǎn)的長(zhǎng)度大于等于 254 字節(jié),那么程序?qū)⑹褂?5 個(gè)字節(jié)來(lái)保存這個(gè)長(zhǎng)度值:

    • 第 1 個(gè)字節(jié)的值將被設(shè)為 254 ,用于標(biāo)識(shí)這是一個(gè) 5 字節(jié)長(zhǎng)的長(zhǎng)度值。
    • 之后的 4 個(gè)字節(jié)則用于保存前置節(jié)點(diǎn)的實(shí)際長(zhǎng)度。

header 另一部分的內(nèi)容和節(jié)點(diǎn)所保存的值有關(guān)。

  1. 如果節(jié)點(diǎn)保存的是字符串值,
    那么這部分 header 的頭 2 個(gè)位將保存編碼字符串長(zhǎng)度所使用的類型,
    而之后跟著的內(nèi)容則是字符串的實(shí)際長(zhǎng)度。
  • |00pppppp| - 1 byte
    String value with length less than or equal to 63 bytes (6 bits).
    字符串的長(zhǎng)度小于或等于 63 字節(jié)。
  • |01pppppp|qqqqqqqq| - 2 bytes
    String value with length less than or equal to 16383 bytes (14 bits).
    字符串的長(zhǎng)度小于或等于 16383 字節(jié)。
  • |10______|qqqqqqqq|rrrrrrrr|ssssssss|tttttttt| - 5 bytes
    String value with length greater than or equal to 16384 bytes.
    字符串的長(zhǎng)度大于或等于 16384 字節(jié)。
  1. 如果節(jié)點(diǎn)保存的是整數(shù)值,
    那么這部分 header 的頭 2 位都將被設(shè)置為 1 ,
    而之后跟著的 2 位則用于標(biāo)識(shí)節(jié)點(diǎn)所保存的整數(shù)的類型。
  • |11000000| - 1 byte
    Integer encoded as int16_t (2 bytes).
    節(jié)點(diǎn)的值為 int16_t 類型的整數(shù),長(zhǎng)度為 2 字節(jié)。
  • |11010000| - 1 byte
    Integer encoded as int32_t (4 bytes).
    節(jié)點(diǎn)的值為 int32_t 類型的整數(shù),長(zhǎng)度為 4 字節(jié)。
  • |11100000| - 1 byte
    Integer encoded as int64_t (8 bytes).
    節(jié)點(diǎn)的值為 int64_t 類型的整數(shù),長(zhǎng)度為 8 字節(jié)。
  • |11110000| - 1 byte
    Integer encoded as 24 bit signed (3 bytes).
    節(jié)點(diǎn)的值為 24 位(3 字節(jié))長(zhǎng)的整數(shù)。
  • |11111110| - 1 byte
    Integer encoded as 8 bit signed (1 byte).
    節(jié)點(diǎn)的值為 8 位(1 字節(jié))長(zhǎng)的整數(shù)。
  • |1111xxxx| - (with xxxx between 0000 and 1101) immediate 4 bit integer.
    Unsigned integer from 0 to 12. The encoded value is actually from
    1 to 13 because 0000 and 1111 can not be used, so 1 should be
    subtracted from the encoded 4 bit value to obtain the right value.
    節(jié)點(diǎn)的值為介于 0 至 12 之間的無(wú)符號(hào)整數(shù)。
    因?yàn)?0000 和 1111 都不能使用,所以位的實(shí)際值將是 1 至 13 。
    程序在取得這 4 個(gè)位的值之后,還需要減去 1 ,才能計(jì)算出正確的值。
    比如說(shuō),如果位的值為 0001 = 1 ,那么程序返回的值將是 1 - 1 = 0 。
  • |11111111| - End of ziplist.
    ziplist 的結(jié)尾標(biāo)識(shí)

所有整數(shù)都表示為小端字節(jié)序。

ziplist 示例圖

/* 
空白 ziplist 示例圖

area        |<---- ziplist header ---->|<-- end -->|

size          4 bytes   4 bytes 2 bytes  1 byte
            +---------+--------+-------+-----------+
component   | zlbytes | zltail | zllen | zlend     |
            |         |        |       |           |
value       |  1011   |  1010  |   0   | 1111 1111 |
            +---------+--------+-------+-----------+
                                       ^
                                       |
                               ZIPLIST_ENTRY_HEAD
                                       &
address                        ZIPLIST_ENTRY_TAIL
                                       &
                               ZIPLIST_ENTRY_END

非空 ziplist 示例圖

area        |<---- ziplist header ---->|<----------- entries ------------->|<-end->|

size          4 bytes  4 bytes  2 bytes    ?        ?        ?        ?     1 byte
            +---------+--------+-------+--------+--------+--------+--------+-------+
component   | zlbytes | zltail | zllen | entry1 | entry2 |  ...   | entryN | zlend |
            +---------+--------+-------+--------+--------+--------+--------+-------+
                                       ^                          ^        ^
address                                |                          |        |
                                ZIPLIST_ENTRY_HEAD                |   ZIPLIST_ENTRY_END
                                                                  |
                                                        ZIPLIST_ENTRY_TAIL
*/

連鎖更新

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Redis的內(nèi)存優(yōu)化 聲明:本文內(nèi)容來(lái)自《Redis開(kāi)發(fā)與運(yùn)維》一書第八章,如轉(zhuǎn)載請(qǐng)聲明。 Redis所有的數(shù)據(jù)都...
    meng_philip123閱讀 19,075評(píng)論 2 29
  • 參考來(lái)源 Redis的內(nèi)存優(yōu)化 Redis所有的數(shù)據(jù)都在內(nèi)存中,而內(nèi)存又是非常寶貴的資源。對(duì)于如何優(yōu)化內(nèi)存使用一直...
    秦漢郵俠閱讀 1,371評(píng)論 0 2
  • 聲明:本文內(nèi)容來(lái)自《Redis開(kāi)發(fā)與運(yùn)維》一書第八章,如轉(zhuǎn)載請(qǐng)聲明。Redis所有的數(shù)據(jù)都在內(nèi)存中,而內(nèi)存又是非常...
    yoqu閱讀 1,616評(píng)論 0 2
  • 唯有時(shí)刻保持清醒,才能認(rèn)清自己的價(jià)值
    核苷酸的代謝閱讀 126評(píng)論 0 0
  • 昨天我瘋狂的找那張相片,然后又跑回娘家去找,終于找到了,然后又跑到縣城去交,今天我開(kāi)了辦公室的門,卻發(fā)現(xiàn)在地上靜靜...
    馬上做閱讀 231評(píng)論 0 0

友情鏈接更多精彩內(nèi)容