Redis RDB文件保存的是二進制數據,結構包括5部分:
REDIS | db_version | databases | EOF | check_sum
db_version長度爲4個字節,它的值是一個字符串表示的整數,記錄RDB文件的版本號。
databases記錄數據庫實例,和各個數據庫實例的鍵值對數據,如果redis-server中所有db都爲空,那這個值也爲空,長度爲0字節。
EOF常量長度爲1字節,標誌着RDB文件正文內容結束。
check_sum是一個8字節長的無符號整數,保存着一個校驗和,這個校驗和是程序通過對REDIS、db_version、databases、EOF四個部分內容計算而來。Redis在載入RDB文件時,會將載入數據的檢驗和與該值對比,以此來檢查RDB文件是否出錯或損壞。
1.databases
每個非空數據庫在RDB文件中的都保存爲SELECTDB、db_number、key_value_pairs三個部分。
SELECTDB | db_number | key_value_pairs
SELECTDB常量長度爲1字節,標識後面的數據庫號碼。
db_number保存數據庫號碼,根據號碼大小不同,長度爲1字節、2字節或5字節。當程序讀入db_number部分後,服務器啊會調用SELECT命令,根據讀入的數據庫號碼進行數據庫切換。
key_value_pairs保存了數據庫中所有鍵值對數據,如果鍵值對帶有過期時間,那麼過期時間也會和鍵值對保存在一起。
2.key_value_pairs
不帶過期時間的鍵值對結構
TYPE | key | value
帶過期時間的鍵值對結構
EXPIRETIME_MS | ms | TYPE | key | value
其中,TYPE記錄value的類型,是以下常量中任意一個:
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_INSERT
REDIS_RDB_TYPE_ZSET_ZIPLIST
REDIS_RDB_TYPE_HASH_ZIPLIST
key總是一個字符串對象,編碼和REDIS_RDB_TYPE_STRING類型的value一樣。
value根據TYPE類型不同,結構和長度也會不同。
EXPIRETIME_MS常量長度爲1字節,當程序讀入該常量時,會表示下一個讀入的將是一個以毫秒爲單位的過期時間。
ms是一個8字節長的帶符號整數,記錄了一個以毫秒爲單位的unix時間戳,即過期時間。
3.value編碼
a.字符串對象
TYPE是REDIS_RDB_TYPE_STRING,字符串對象編碼可以是REDIS_ENCODING_INT或者REDIS_ENCODING_RAW,對應保存的值類型是整數和字符串。
如果字符串對象編碼爲REDIS_ENCODING_RAW,字符串長度若大於20字節,那麼這個字符串會被壓縮保存,否則原樣保存。
無壓縮字符串結構
len | string
壓縮後結構
REDIS_RDB_ENC_LZF | compressed_len | origin_len | compressed_string
其中REDIS_RDB_ENC_LZF常量標誌字符串已被LZF算法壓縮,程序在讀入過程中,碰到這個常量時,會根據之後的compressed_len和orgin_len和compressed_string 三部分對字符串進行解壓。
b.列表對象
TYPE爲REDIS_RDB_TYPE_LIST,value保存的是一個REDIS_ENCODING_LINKEDLIST編碼的列表對象,結構如下
list_length | item1| item2 | item3 | ... | itemN
list_length記錄了列表的長度,item部分代表列表的項,每項都是字符串對象。
c.集合對象
TYPE爲REDIS_RDB_TYPE_SET,value保存的是一個REDIS_ENCODING_HT編碼的對象集合,結構如下
set_size | elem1 | elem2 | elem3 | ... | elemN
set_size記錄集合大小,elem開頭部分代表元素集合,每個元素都是一個字符串對象。
d.哈希表對象
TYPE爲REDIS_RDB_TYPE_HASH,value保存的是一個REDIS_ENCODING_HT編碼的集合對象,結構如下
hash_size | key_value_pair 1 | key_value_pair 2 | key_value_pair 3 | ... | key_value_pair N
hash_size記錄了哈希表的大小。key_value_pair部分代表鍵值對,結構中的每個鍵值對都以鍵緊挨着值的方式排列。結構如下
key1 | value1 | key2 | value2 | key3 | value3 | ....
e.有序集合對象
TYPE爲REDIS_RDB_TYPE_ZSET,value保存的是一個REDIS_ENCODING_SKIPLIST編碼的有序集合對象。結構如下
sorted_set_size | elem1 | elem2 | elem3 | ... | elemN
sorted_set_size記錄有序集合大小,elem開頭部分代表有序集合中的元素,每個元素又分爲成員 (member)和分值(score)兩部分,成員是一個字符串對象,分值則是一個double類型的浮點數,程序在保存RDB文件時會先將分支轉換成字符串對象,再用保存字符串的方法將分值保存起來。
有序集合中每個元素都是以成員緊挨着分值方式排列,結構如下
sorted_set_size | member1 | score 1 | member2 | score2 | ... | memberN | scoreN
f.INTSET編碼集合
TYPE爲REDIS_RDB_TYPE_SET_INTSET,value保存的是一個整數集合對象,RDB保存這種對象方法是先將整數集合轉換爲字符串對象,再保存到RDB文件中。讀取是相反。
g.ZIPLIST編碼的列表、哈希表或有序集合
TYPE爲REDIS_RDB_TYPE_LIST_ZIPLIST、REDIS_RDB_TYPE_HASH_ZIPLIST或者REDIS_RDB_TYPE_ZSET_ZIPLIST,那麼value保存的是一個壓縮列表對象,RDB文件保存方法是:
1)將壓縮列表轉換成一個字符串對象;
2)將轉換所得的字符串對象保存到RDB文件。
讀取時做對應類型轉換即可。