Redis RDB文件結(jié)構(gòu)

2018-08-02 14:51 更新

在本章之前的內(nèi)容中, 我們介紹了 Redis 服務(wù)器保存和載入 RDB 文件的方法, 在這一節(jié), 我們將對(duì) RDB 文件本身進(jìn)行介紹, 并詳細(xì)說(shuō)明文件各個(gè)部分的結(jié)構(gòu)和意義。

圖 IMAGE_RDB_STRUCT_OVERVIEW 展示了一個(gè)完整 RDB 文件所包含的各個(gè)部分。

注意

為了方便區(qū)分變量、數(shù)據(jù)、常量, 圖 IMAGE_RDB_STRUCT_OVERVIEW 中用全大寫單詞標(biāo)示常量, 用全小寫單詞標(biāo)示變量和數(shù)據(jù)。

本章展示的所有 RDB 文件結(jié)構(gòu)圖都遵循這一規(guī)則。

RDB 文件的最開(kāi)頭是 REDIS 部分, 這個(gè)部分的長(zhǎng)度為 5 字節(jié), 保存著 "REDIS" 五個(gè)字符。 通過(guò)這五個(gè)字符, 程序可以在載入文件時(shí), 快速檢查所載入的文件是否 RDB 文件。

注意

因?yàn)?RDB 文件保存的是二進(jìn)制數(shù)據(jù), 而不是 C 字符串, 為了簡(jiǎn)便起見(jiàn), 我們用 "REDIS" 符號(hào)代表 'R' 、 'E' 、 'D' 、 'I' 、 'S'五個(gè)字符, 而不是帶 '\0' 結(jié)尾符號(hào)的 C 字符串 'R' 、 'E' 、 'D' 、 'I' 、 'S' 、 '\0' 。

本章介紹的所有內(nèi)容,以及展示的所有 RDB 文件結(jié)構(gòu)圖都遵循這一規(guī)則。

db_version 長(zhǎng)度為 4 字節(jié), 它的值是一個(gè)字符串表示的整數(shù), 這個(gè)整數(shù)記錄了 RDB 文件的版本號(hào), 比如 "0006" 就代表 RDB 文件的版本為第六版。 本章只介紹第六版 RDB 文件的結(jié)構(gòu)。

databases 部分包含著零個(gè)或任意多個(gè)數(shù)據(jù)庫(kù), 以及各個(gè)數(shù)據(jù)庫(kù)中的鍵值對(duì)數(shù)據(jù):

  • 如果服務(wù)器的數(shù)據(jù)庫(kù)狀態(tài)為空(所有數(shù)據(jù)庫(kù)都是空的), 那么這個(gè)部分也為空, 長(zhǎng)度為 0 字節(jié)。
  • 如果服務(wù)器的數(shù)據(jù)庫(kù)狀態(tài)為非空(有至少一個(gè)數(shù)據(jù)庫(kù)非空), 那么這個(gè)部分也為非空, 根據(jù)數(shù)據(jù)庫(kù)所保存鍵值對(duì)的數(shù)量、類型和內(nèi)容不同, 這個(gè)部分的長(zhǎng)度也會(huì)有所不同。

EOF 常量的長(zhǎng)度為 1 字節(jié), 這個(gè)常量標(biāo)志著 RDB 文件正文內(nèi)容的結(jié)束, 當(dāng)讀入程序遇到這個(gè)值的時(shí)候, 它知道所有數(shù)據(jù)庫(kù)的所有鍵值對(duì)都已經(jīng)載入完畢了。

check_sum 是一個(gè) 8 字節(jié)長(zhǎng)的無(wú)符號(hào)整數(shù), 保存著一個(gè)校驗(yàn)和, 這個(gè)校驗(yàn)和是程序通過(guò)對(duì) REDIS 、 db_version 、 databases 、 EOF 四個(gè)部分的內(nèi)容進(jìn)行計(jì)算得出的。 服務(wù)器在載入 RDB 文件時(shí), 會(huì)將載入數(shù)據(jù)所計(jì)算出的校驗(yàn)和與 check_sum 所記錄的校驗(yàn)和進(jìn)行對(duì)比, 以此來(lái)檢查 RDB 文件是否有出錯(cuò)或者損壞的情況出現(xiàn)。

作為例子, 圖 IMAGE_RDB_WITH_EMPTY_DATABASE 展示了一個(gè) databases 部分為空的 RDB 文件: 文件開(kāi)頭的 "REDIS" 表示這是一個(gè) RDB 文件, 之后的 "0006" 表示這是第六版的 RDB 文件, 因?yàn)?nbsp;databases 為空, 所以版本號(hào)之后直接跟著 EOF 常量, 最后的 6265312314761917404是文件的校驗(yàn)和。

databases 部分

一個(gè) RDB 文件的 databases 部分可以保存任意多個(gè)非空數(shù)據(jù)庫(kù)。

比如說(shuō), 如果服務(wù)器的 0 號(hào)數(shù)據(jù)庫(kù)和 3 號(hào)數(shù)據(jù)庫(kù)非空, 那么服務(wù)器將創(chuàng)建一個(gè)如圖 IMAGE_RDB_WITH_TWO_DB 所示的 RDB 文件, 圖中的database 0 代表 0 號(hào)數(shù)據(jù)庫(kù)中的所有鍵值對(duì)數(shù)據(jù), 而 database 3 則代表 3 號(hào)數(shù)據(jù)庫(kù)中的所有鍵值對(duì)數(shù)據(jù)。

每個(gè)非空數(shù)據(jù)庫(kù)在 RDB 文件中都可以保存為 SELECTDB 、 db_number 、 key_value_pairs 三個(gè)部分, 如圖 IMAGE_DATABASE_STRUCT_OF_RDB 所示。

SELECTDB 常量的長(zhǎng)度為 1 字節(jié), 當(dāng)讀入程序遇到這個(gè)值的時(shí)候, 它知道接下來(lái)要讀入的將是一個(gè)數(shù)據(jù)庫(kù)號(hào)碼。

db_number 保存著一個(gè)數(shù)據(jù)庫(kù)號(hào)碼, 根據(jù)號(hào)碼的大小不同, 這個(gè)部分的長(zhǎng)度可以是 1 字節(jié)、 2 字節(jié)或者 5 字節(jié)。 當(dāng)程序讀入 db_number 部分之后, 服務(wù)器會(huì)調(diào)用 SELECT 命令, 根據(jù)讀入的數(shù)據(jù)庫(kù)號(hào)碼進(jìn)行數(shù)據(jù)庫(kù)切換, 使得之后讀入的鍵值對(duì)可以載入到正確的數(shù)據(jù)庫(kù)中。

key_value_pairs 部分保存了數(shù)據(jù)庫(kù)中的所有鍵值對(duì)數(shù)據(jù), 如果鍵值對(duì)帶有過(guò)期時(shí)間, 那么過(guò)期時(shí)間也會(huì)和鍵值對(duì)保存在一起。 根據(jù)鍵值對(duì)的數(shù)量、類型、內(nèi)容、以及是否有過(guò)期時(shí)間等條件的不同, key_value_pairs 部分的長(zhǎng)度也會(huì)有所不同。

作為例子, 圖 IMAGE_EXAMPLE_OF_DB 展示了 RDB 文件中, 0 號(hào)數(shù)據(jù)庫(kù)的結(jié)構(gòu)。

另外, 圖 IMAGE_RDB_WITH_DB_0_AND_DB_3 則展示了一個(gè)完整的 RDB 文件, 文件中包含了 0 號(hào)數(shù)據(jù)庫(kù)和 3 號(hào)數(shù)據(jù)庫(kù)。

key_value_pairs 部分

RDB 文件中的每個(gè) key_value_pairs 部分都保存了一個(gè)或以上數(shù)量的鍵值對(duì), 如果鍵值對(duì)帶有過(guò)期時(shí)間的話, 那么鍵值對(duì)的過(guò)期時(shí)間也會(huì)被保存在內(nèi)。

不帶過(guò)期時(shí)間的鍵值對(duì)在 RDB 文件中對(duì)由 TYPE 、 key 、 value 三部分組成, 如圖 IMAGE_KEY_WITHOUT_EXPIRE_TIME 所示。

TYPE 記錄了 value 的類型, 長(zhǎng)度為 1 字節(jié), 值可以是以下常量的其中一個(gè):

  • REDIS_RDB_TYPE_STRING
  • REDIS_RDB_TYPE_LIST
  • REDIS_RDB_TYPE_SET
  • REDIS_RDB_TYPE_ZSET
  • REDIS_RDB_TYPE_HASH
  • REDIS_RDB_TYPE_LIST_ZIPLIST
  • REDIS_RDB_TYPE_SET_INTSET
  • REDIS_RDB_TYPE_ZSET_ZIPLIST
  • REDIS_RDB_TYPE_HASH_ZIPLIST

以上列出的每個(gè) TYPE 常量都代表了一種對(duì)象類型或者底層編碼, 當(dāng)服務(wù)器讀入 RDB 文件中的鍵值對(duì)數(shù)據(jù)時(shí), 程序會(huì)根據(jù) TYPE 的值來(lái)決定如何讀入和解釋 value 的數(shù)據(jù)。

key 和 value 分別保存了鍵值對(duì)的鍵對(duì)象和值對(duì)象:

  • 其中 key 總是一個(gè)字符串對(duì)象, 它的編碼方式和 REDIS_RDB_TYPE_STRING 類型的 value 一樣。 根據(jù)內(nèi)容長(zhǎng)度的不同, key 的長(zhǎng)度也會(huì)有所不同。
  • 根據(jù) TYPE 類型的不同, 以及保存內(nèi)容長(zhǎng)度的不同, 保存 value 的結(jié)構(gòu)和長(zhǎng)度也會(huì)有所不同, 本節(jié)稍后會(huì)詳細(xì)說(shuō)明每種 TYPE 類型的value 結(jié)構(gòu)保存方式。

帶有過(guò)期時(shí)間的鍵值對(duì)在 RDB 文件中的結(jié)構(gòu)如圖 IMAGE_KEY_WITH_EXPIRE_TIME 所示。

帶有過(guò)期時(shí)間的鍵值對(duì)中的 TYPE 、 key 、 value 三個(gè)部分的意義, 和前面介紹的不帶過(guò)期時(shí)間的鍵值對(duì)的 TYPE 、 key 、 value 三個(gè)部分的意義完全相同, 至于新增的 EXPIRETIME_MS 和 ms , 它們的意義如下:

  • EXPIRETIME_MS 常量的長(zhǎng)度為 1 字節(jié), 它告知讀入程序, 接下來(lái)要讀入的將是一個(gè)以毫秒為單位的過(guò)期時(shí)間。
  • ms 是一個(gè) 8 字節(jié)長(zhǎng)的帶符號(hào)整數(shù), 記錄著一個(gè)以毫秒為單位的 UNIX 時(shí)間戳, 這個(gè)時(shí)間戳就是鍵值對(duì)的過(guò)期時(shí)間。

作為例子, 圖 IMAGE_EXAMPLE_OF_KEY_WITHOUT_EXPIRE_TIME 展示了一個(gè)沒(méi)有過(guò)期時(shí)間的字符串鍵值對(duì)。

圖 IMAGE_EXAMPLE_OF_KEY_WITH_EXPIRE_TIME 展示了一個(gè)帶有過(guò)期時(shí)間的集合鍵值對(duì), 其中鍵的過(guò)期時(shí)間為 1388556000000 (2014 年 1 月 1 日零時(shí))。

value 的編碼

RDB 文件中的每個(gè) value 部分都保存了一個(gè)值對(duì)象, 每個(gè)值對(duì)象的類型都由與之對(duì)應(yīng)的 TYPE 記錄, 根據(jù)類型的不同, value 部分的結(jié)構(gòu)、長(zhǎng)度也會(huì)有所不同。

在接下來(lái)的各個(gè)小節(jié)中, 我們將分別介紹各種不同類型的值對(duì)象在 RDB 文件中的保存結(jié)構(gòu)。

注意

本節(jié)接下來(lái)說(shuō)到的各種 REDIS_ENCODING_* 編碼曾經(jīng)在《對(duì)象》一章中介紹過(guò), 如果忘記了可以去回顧一下。

字符串對(duì)象

如果 TYPE 的值為 REDIS_RDB_TYPE_STRING , 那么 value 保存的就是一個(gè)字符串對(duì)象, 字符串對(duì)象的編碼可以是 REDIS_ENCODING_INT 或者REDIS_ENCODING_RAW 。

如果字符串對(duì)象的編碼為 REDIS_ENCODING_INT , 那么說(shuō)明對(duì)象中保存的是長(zhǎng)度不超過(guò) 32 位的整數(shù), 這種編碼的對(duì)象將以圖 IMAGE_INT_ENCODING_STRING 所示的結(jié)構(gòu)保存。

其中, ENCODING 的值可以是 REDIS_RDB_ENC_INT8 、 REDIS_RDB_ENC_INT16 或者 REDIS_RDB_ENC_INT32 三個(gè)常量的其中一個(gè), 它們分別代表 RDB 文件使用 8 位(bit)、 16 位或者 32 位來(lái)保存整數(shù)值 integer 。

舉個(gè)例子, 如果字符串對(duì)象中保存的是可以用 8 位來(lái)保存的整數(shù) 123 , 那么這個(gè)對(duì)象在 RDB 文件中保存的結(jié)構(gòu)將如圖 IMAGE_EXAMPLE_OF_INT_ENCODING_STRING 所示。

如果字符串對(duì)象的編碼為 REDIS_ENCODING_RAW , 那么說(shuō)明對(duì)象所保存的是一個(gè)字符串值, 根據(jù)字符串長(zhǎng)度的不同, 有壓縮和不壓縮兩種方法來(lái)保存這個(gè)字符串:

  • 如果字符串的長(zhǎng)度小于等于 20 字節(jié), 那么這個(gè)字符串會(huì)直接被原樣保存。
  • 如果字符串的長(zhǎng)度大于 20 字節(jié), 那么這個(gè)字符串會(huì)被壓縮之后再保存。

注意

以上兩個(gè)條件是在假設(shè)服務(wù)器打開(kāi)了 RDB 文件壓縮功能的情況下進(jìn)行的, 如果服務(wù)器關(guān)閉了 RDB 文件壓縮功能, 那么 RDB 程序總以無(wú)壓縮的方式保存字符串值。

具體信息可以參考 redis.conf 文件中關(guān)于 rdbcompression 選項(xiàng)的說(shuō)明。

對(duì)于沒(méi)有被壓縮的字符串, RDB 程序會(huì)以圖 IMAGE_NON_COMPRESS_STRING 所示的結(jié)構(gòu)來(lái)保存該字符串。

其中, string 部分保存了字符串值本身,而 len 保存了字符串值的長(zhǎng)度。

對(duì)于壓縮后的字符串, RDB 程序會(huì)以圖 IMAGE_COMPRESSED_STRING 所示的結(jié)構(gòu)來(lái)保存該字符串。

其中, REDIS_RDB_ENC_LZF 常量標(biāo)志著字符串已經(jīng)被 LZF 算法(http://liblzf.plan9.de)壓縮過(guò)了, 讀入程序在碰到這個(gè)常量時(shí), 會(huì)根據(jù)之后的 compressed_len 、 origin_len 和 compressed_string 三部分, 對(duì)字符串進(jìn)行解壓縮: 其中 compressed_len 記錄的是字符串被壓縮之后的長(zhǎng)度, 而 origin_len 記錄的是字符串原來(lái)的長(zhǎng)度, compressed_string 記錄的則是被壓縮之后的字符串。

圖 IMAGE_EXAMPLE_OF_NON_COMPRESS_STRING 展示了一個(gè)保存無(wú)壓縮字符串的例子, 其中字符串的長(zhǎng)度為 5 , 字符串的值為 "hello" 。

圖 IMAGE_EXAMPLE_OF_COMPRESS_STRING 展示了一個(gè)壓縮后的字符串示例, 從圖中可以看出, 字符串原本的長(zhǎng)度為 21 , 壓縮之后的長(zhǎng)度為6 , 壓縮之后的字符串內(nèi)容為 "?aa???" , 其中 ? 代表的是無(wú)法用字符串形式打印出來(lái)的字節(jié)。

列表對(duì)象

如果 TYPE 的值為 REDIS_RDB_TYPE_LIST , 那么 value 保存的就是一個(gè) REDIS_ENCODING_LINKEDLIST 編碼的列表對(duì)象, RDB 文件保存這種對(duì)象的結(jié)構(gòu)如圖 IMAGE_LINKEDLIST_ENCODING_LIST 所示。

list_length 記錄了列表的長(zhǎng)度, 它記錄列表保存了多少個(gè)項(xiàng)(item), 讀入程序可以通過(guò)這個(gè)長(zhǎng)度知道自己應(yīng)該讀入多少個(gè)列表項(xiàng)。

圖中以 item 開(kāi)頭的部分代表列表的項(xiàng), 因?yàn)槊總€(gè)列表項(xiàng)都是一個(gè)字符串對(duì)象, 所以程序會(huì)以處理字符串對(duì)象的方式來(lái)保存和讀入列表項(xiàng)。

作為示例, 圖 IMAGE_EXAMPLE_OF_LINKEDLIST_ENCODING_LIST 展示了一個(gè)包含三個(gè)元素的列表。

結(jié)構(gòu)中的第一個(gè)數(shù)字 3 是列表的長(zhǎng)度, 之后跟著的分別是第一個(gè)列表項(xiàng)、第二個(gè)列表項(xiàng)和第三個(gè)列表項(xiàng), 其中:

  • 第一個(gè)列表項(xiàng)的長(zhǎng)度為 5 , 內(nèi)容為字符串 "hello" 。
  • 第二個(gè)列表項(xiàng)的長(zhǎng)度也為 5 , 內(nèi)容為字符串 "world" 。
  • 第三個(gè)列表項(xiàng)的長(zhǎng)度為 1 , 內(nèi)容為字符串 "!" 。

集合對(duì)象

如果 TYPE 的值為 REDIS_RDB_TYPE_SET , 那么 value 保存的就是一個(gè) REDIS_ENCODING_HT 編碼的集合對(duì)象, RDB 文件保存這種對(duì)象的結(jié)構(gòu)如圖 IMAGE_HT_ENCODING_SET 所示。

其中, set_size 是集合的大小, 它記錄集合保存了多少個(gè)元素, 讀入程序可以通過(guò)這個(gè)大小知道自己應(yīng)該讀入多少個(gè)集合元素。

圖中以 elem 開(kāi)頭的部分代表集合的元素, 因?yàn)槊總€(gè)集合元素都是一個(gè)字符串對(duì)象, 所以程序會(huì)以處理字符串對(duì)象的方式來(lái)保存和讀入集合元素。

作為示例, 圖 IMAGE_EXAMPLE_OF_HT_SET 展示了一個(gè)包含四個(gè)元素的集合。

結(jié)構(gòu)中的第一個(gè)數(shù)字 4 記錄了集合的大小, 之后跟著的是集合的四個(gè)元素:

  • 第一個(gè)元素的長(zhǎng)度為 5 ,值為 "apple" 。
  • 第二個(gè)元素的長(zhǎng)度為 6 ,值為 "banana" 。
  • 第三個(gè)元素的長(zhǎng)度為 3 ,值為 "cat" 。
  • 第四個(gè)元素的長(zhǎng)度為 3 ,值為 "dog" 。

哈希表對(duì)象

如果 TYPE 的值為 REDIS_RDB_TYPE_HASH , 那么 value 保存的就是一個(gè) REDIS_ENCODING_HT 編碼的集合對(duì)象, RDB 文件保存這種對(duì)象的結(jié)構(gòu)如圖 IMAGE_HT_HASH 所示:

  • hash_size 記錄了哈希表的大小, 也即是這個(gè)哈希表保存了多少鍵值對(duì), 讀入程序可以通過(guò)這個(gè)大小知道自己應(yīng)該讀入多少個(gè)鍵值對(duì)。
  • 以 key_value_pair 開(kāi)頭的部分代表哈希表中的鍵值對(duì), 鍵值對(duì)的鍵和值都是字符串對(duì)象, 所以程序會(huì)以處理字符串對(duì)象的方式來(lái)保存和讀入鍵值對(duì)。

結(jié)構(gòu)中的每個(gè)鍵值對(duì)都以鍵緊挨著值的方式排列在一起, 如圖 IMAGE_KEY_VALUE_PAIR_OF_HT_HASH 所示。

因此, 從更詳細(xì)的角度看, 圖 IMAGE_HT_HASH 所展示的結(jié)構(gòu)可以進(jìn)一步修改為圖 IMAGE_DETIAL_HT_HASH 。

作為示例, 圖 IMAGE_EXAMPLE_OF_HT_HASH 展示了一個(gè)包含兩個(gè)鍵值對(duì)的哈希表。

在這個(gè)示例結(jié)構(gòu)中, 第一個(gè)數(shù)字 2 記錄了哈希表的鍵值對(duì)數(shù)量, 之后跟著的是兩個(gè)鍵值對(duì):

  • 第一個(gè)鍵值對(duì)的鍵是長(zhǎng)度為 1 的字符串 "a" , 值是長(zhǎng)度為 5 的字符串 "apple" 。
  • 第二個(gè)鍵值對(duì)的鍵是長(zhǎng)度為 1 的字符串 "b" , 值是長(zhǎng)度為 6 的字符串 "banana" 。

有序集合對(duì)象

如果 TYPE 的值為 REDIS_RDB_TYPE_ZSET , 那么 value 保存的就是一個(gè) REDIS_ENCODING_SKIPLIST 編碼的有序集合對(duì)象, RDB 文件保存這種對(duì)象的結(jié)構(gòu)如圖 IMAGE_SKIPLIST_ZSET 所示。

sorted_set_size 記錄了有序集合的大小, 也即是這個(gè)有序集合保存了多少元素, 讀入程序需要根據(jù)這個(gè)值來(lái)決定應(yīng)該讀入多少有序集合元素。

以 element 開(kāi)頭的部分代表有序集合中的元素, 每個(gè)元素又分為成員(member)和分值(score)兩部分, 成員是一個(gè)字符串對(duì)象, 分值則是一個(gè) double 類型的浮點(diǎn)數(shù), 程序在保存 RDB 文件時(shí)會(huì)先將分值轉(zhuǎn)換成字符串對(duì)象, 然后再用保存字符串對(duì)象的方法將分值保存起來(lái)。

有序集合中的每個(gè)元素都以成員緊挨著分值的方式排列, 如圖 IMAGE_MEMBER_AND_SCORE_OF_ZSET 所示。

因此, 從更詳細(xì)的角度看, 圖 IMAGE_SKIPLIST_ZSET 所展示的結(jié)構(gòu)可以進(jìn)一步修改為圖 IMAGE_DETIAL_SKIPLIST_ZSET 。

作為示例, 圖 IMAGE_EXAMPLE_OF_SKIPLIST_ZSET 展示了一個(gè)帶有兩個(gè)元素的有序集合。

在這個(gè)示例結(jié)構(gòu)中, 第一個(gè)數(shù)字 2 記錄了有序集合的元素?cái)?shù)量, 之后跟著的是兩個(gè)有序集合元素:

  • 第一個(gè)元素的成員是長(zhǎng)度為 2 的字符串 "pi" , 分值被轉(zhuǎn)換成字符串之后變成了長(zhǎng)度為 4 的字符串 "3.14" 。
  • 第二個(gè)元素的成員是長(zhǎng)度為 1 的字符串 "e" , 分值被轉(zhuǎn)換成字符串之后變成了長(zhǎng)度為 3 的字符串 "2.7" 。

INTSET 編碼的集合

如果 TYPE 的值為 REDIS_RDB_TYPE_SET_INTSET , 那么 value 保存的就是一個(gè)整數(shù)集合對(duì)象, RDB 文件保存這種對(duì)象的方法是, 先將整數(shù)集合轉(zhuǎn)換為字符串對(duì)象, 然后將這個(gè)字符串對(duì)象保存到 RDB 文件里面。

如果程序在讀入 RDB 文件的過(guò)程中, 碰到由整數(shù)集合對(duì)象轉(zhuǎn)換成的字符串對(duì)象, 那么程序會(huì)根據(jù) TYPE 值的指示, 先讀入字符串對(duì)象, 再將這個(gè)字符串對(duì)象轉(zhuǎn)換成原來(lái)的整數(shù)集合對(duì)象。

ZIPLIST 編碼的列表、哈希表或者有序集合

如果 TYPE 的值為 REDIS_RDB_TYPE_LIST_ZIPLIST 、 REDIS_RDB_TYPE_HASH_ZIPLIST 或者 REDIS_RDB_TYPE_ZSET_ZIPLIST , 那么 value 保存的就是一個(gè)壓縮列表對(duì)象, RDB 文件保存這種對(duì)象的方法是:

  1. 將壓縮列表轉(zhuǎn)換成一個(gè)字符串對(duì)象。
  2. 將轉(zhuǎn)換所得的字符串對(duì)象保存到 RDB 文件。

如果程序在讀入 RDB 文件的過(guò)程中, 碰到由壓縮列表對(duì)象轉(zhuǎn)換成的字符串對(duì)象, 那么程序會(huì)根據(jù) TYPE 值的指示, 執(zhí)行以下操作:

  1. 讀入字符串對(duì)象,并將它轉(zhuǎn)換成原來(lái)的壓縮列表對(duì)象。
  2. 根據(jù) TYPE 的值,設(shè)置壓縮列表對(duì)象的類型: 如果 TYPE 的值為 REDIS_RDB_TYPE_LIST_ZIPLIST , 那么壓縮列表對(duì)象的類型為列表; 如果TYPE 的值為 REDIS_RDB_TYPE_HASH_ZIPLIST , 那么壓縮列表對(duì)象的類型為哈希表; 如果 TYPE 的值為 REDIS_RDB_TYPE_ZSET_ZIPLIST , 那么壓縮列表對(duì)象的類型為有序集合。

從步驟 2 可以看出, 由于 TYPE 的存在, 即使列表、哈希表和有序集合三種類型都使用壓縮列表來(lái)保存, RDB 讀入程序也總可以將讀入并轉(zhuǎn)換之后得出的壓縮列表設(shè)置成原來(lái)的類型。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)