Redis RDB文件格式全解析
RDB文件是Redis持久化的一種方式,Redis通過制定好的策略,按期將內存中的數據以鏡像的形式轉存到RDB文件中。那么RDB文件內部格式是什么樣的呢,Redis又做了哪些工作讓RDB能夠更快的dump和加載呢,下面我們深入RDB文件,來看一看其內部結構。
首先我們來看一個RDB文件的概況圖:
----------------------------# RDB文件是二進制的,所以并不存在回車換行來分隔一行一行. 52 45 44 49 53 # 以字符串 "REDIS" 開頭 30 30 30 33 # RDB 的版本號,大端存儲,比如左邊這個表示版本號為0003 ---------------------------- FE 00 # FE = FE表示數據庫編號,Redis支持多個庫,以數字編號,這里00表示第0個數據庫 ----------------------------# Key-Value 對存儲開始了 FD $length-encoding # FD 表示過期時間,過期時間是用 length encoding 編碼存儲的,后面會講到 $value-type # 1 個字節用于表示value的類型,比如set,hash,list,zset等 $string-encoded-key # Key 值,通過string encoding 編碼,同樣后面會講到 $encoded-value # Value值,根據不同的Value類型采用不同的編碼方式 ---------------------------- FC $length-encoding # FC 表示毫秒級的過期時間,后面的具體時間用length encoding編碼存儲 $value-type # 同上,也是一個字節的value類型 $string-encoded-key # 同樣是以 string encoding 編碼的 Key值 $encoded-value # 同樣是以對應的數據類型編碼的 Value 值 ---------------------------- $value-type # 下面是沒有過期時間設置的 Key-Value對,為防止沖突,數據類型不會以 FD, FC, FE, FF 開頭 $string-encoded-key $encoded-value ---------------------------- FE $length-encoding # 下一個庫開始,庫的編號用 length encoding 編碼 ---------------------------- ... # 繼續存儲這個數據庫的 Key-Value 對 FF ## FF:RDB文件結束的標志下面我們對上面的內容進行詳細講解
Magic Number
第一行就不用講了,REDIS字符串用于標識是Redis的RDB文件
版本號
用了4個字節存儲版本號,以大端(big endian)方式存儲和讀取
數據庫編號
以一個字節的0xFE開頭,后面存儲數據庫的具體編號,數據庫的編號是一個數字,通過 “Length Encoding” 方式編碼存儲,“Length Encoding” 我們后面會講到。
Key-Value值對
值對包括下面四個部分
Key過期時間
過期時間由?0xFD 或 0xFC開頭用于標識,分別表示秒級的過期時間和毫秒級的過期時間,后面的具體時間是一個UNIX時間戳,秒級或毫秒級的。具體時間戳的值通過“Redis Length Encoding” 編碼存儲。在導入RDB文件的過程中,會通過過期時間判斷是否已過期并需要忽略。
Value類型
Value類型用一個字節進行存儲,目前包括以下一些值:
- 0 = “String Encoding”
- 1 = “List Encoding”
- 2 = “Set Encoding”
- 3 = “Sorted Set Encoding”
- 4 = “Hash Encoding”
- 9 = “Zipmap Encoding”
- 10 = “Ziplist Encoding”
- 11 = “Intset Encoding”
- 12 = “Sorted Set in Ziplist Encoding”
Key
Key值就是簡單的 “String Encoding” 編碼,具體可以看后面的描述
Value
上面列舉了Value的9種類型,實際上可以分為三大類
- type = 0, 簡單字符串
- type 為 ?9, 10, 11 或 12, value字符串在讀取出來后需要先解壓
- type 為 1, 2, 3 或 4, value是字符串序列,這一系列的字符串用于構建list,set,hash 和 zset 結構
Length Encoding
上面說了很多 Length Encoding ,現在就為大家講解。可能你會說,長度用一個int存儲不就行了嗎?但是,通常我們使用到的長度可能都并不大,一個int 4個字節是否有點浪費呢。所以Redis采用了變長編碼的方法,將不同大小的數字編碼成不同的長度。
這樣做有什么好處呢,實際就是節約空間:
String Encoding
Redis的 String Encoding 是二進制安全的,也就是說他沒有任何特殊分隔符用于分隔各個值,你可以在里面存儲任何東西。它就是一串字節碼。
下面是 String Encoding 的三種類型
長度編碼字符串
長度編碼字符串是最簡單的一種類型,它由兩部分組成,一部分是用 “Length Encoding” 編碼的字符串長度,第二部分是具體的字節碼。
數字替代字符串
上面說到過 Length Encoding 的特殊編碼,就在這里用上了。所以數字替代字符串是以 1 1 開頭的,然后讀取這個字節剩下的6 位,根據不同的值標識不同的數字類型:
- 0 表示下面是一個8 位的數字
- 1 表示下面是一個16 位的數字
- 2 表示下面是一個32 位的數字
LZF壓縮字符串
和數據替代字符串一樣,它也是以1 1 開頭的,然后剩下的6 位如果值為4,那么就表示它是一個壓縮字符串。壓縮字符串解析規則如下:
List Encoding
Redis List 結構在RDB文件中的存儲,是依次存儲List中的各個元素的。其結構如下:
Set Encoding
Set結構和List結構一樣,也是依次存儲各個元素的
Sorted Set Encoding
todo
Hash Encoding
Zipmap Encoding
參見本站之前的文章:Redis zipmap內存布局分析
待續&歡迎投稿
Ziplist Encoding
Intset Encoding
Sorted Set as Ziplist Encoding
來源:RDB_File_Format.textile
from:?http://blog.nosqlfan.com/html/3734.html
總結
以上是生活随笔為你收集整理的Redis RDB文件格式全解析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 深入剖析Redis RDB持久化机制
- 下一篇: Redis集群教程