RDB
是 Redis 將 server 端的內存中的 k/v 對以二進制的方式,持久化存儲的一種文件形式。 文件中,通常會以 對象的長度+對象 的格式來存儲,只要根據這個格式,就能漸進的遍歷整個文件。 Redis
還支持開啓 LZF
的壓縮算法,能夠犧牲CPU時間,來減小 RDB
文件的大小;若是開啓LZF
而且超過20
個bytes時, 會將壓縮後的字符寫入文件。redis
➜ go-redis-parser od -A x -t x1c -v ./teststub/dumpV9.rdb
000000 52 45 44 49 53 30 30 30 39 fa 09 72 65 64 69 73
R E D I S 0 0 0 9 372 \t r e d i s
000010 2d 76 65 72 05 35 2e 30 2e 35 fa 0a 72 65 64 69
- v e r 005 5 . 0 . 5 372 \n r e d i
000020 73 2d 62 69 74 73 c0 40 fa 05 63 74 69 6d 65 c2
s - b i t s 300 @ 372 005 c t i m e 302
000030 71 8a 8d 5d fa 08 75 73 65 64 2d 6d 65 6d c2 30
q 212 215 ] 372 \b u s e d - m e m 302 0
000040 e0 0f 00 fa 0c 61 6f 66 2d 70 72 65 61 6d 62 6c
340 017 \0 372 \f a o f - p r e a m b l
000050 65 c0 00 fe 00 fb 06 00 f9 00 00 01 73 01 61 f9
e 300 \0 376 \0 373 006 \0 371 \0 \0 001 s 001 a 371
000060 03 0e 02 6c 69 01 11 11 00 00 00 0d 00 00 00 02
003 016 002 l i 001 021 021 \0 \0 \0 \r \0 \0 \0 002
000070 00 00 01 61 03 01 62 ff f9 00 02 03 73 65 74 02
\0 \0 001 a 003 001 b 377 371 \0 002 003 s e t 002
000080 01 62 01 61 f9 00 0f 06 73 74 72 65 61 6d 01 10
001 b 001 a 371 \0 017 006 s t r e a m 001 020
000090 00 00 01 6d 70 b5 4a 7e 00 00 00 00 00 00 00 00
\0 \0 001 m p 265 J ~ \0 \0 \0 \0 \0 \0 \0 \0
0000a0 40 52 52 00 00 00 18 00 03 01 00 01 02 01 84 6e
@ R R \0 \0 \0 030 \0 003 001 \0 001 002 001 204 n
0000b0 61 6d 65 05 83 61 67 65 04 00 01 02 01 00 01 00
a m e 005 203 a g e 004 \0 001 002 001 \0 001 \0
0000c0 01 87 4c 61 6d 62 65 72 74 08 1d 01 05 01 02 01
001 207 L a m b e r t \b 035 001 005 001 002 001
0000d0 f2 33 8c 00 04 00 01 84 4a 61 63 6b 05 1a 01 05
362 3 214 \0 004 \0 001 204 J a c k 005 032 001 005
0000e0 01 02 01 f2 9c ad 00 04 00 01 83 54 6f 6d 04 1e
001 002 001 362 234 255 \0 004 \0 001 203 T o m 004 036
0000f0 01 05 01 ff 03 81 00 00 01 6d 70 b5 f8 1a 00 01
001 005 001 377 003 201 \0 \0 001 m p 265 370 032 \0 001
000100 05 67 72 6f 75 70 00 00 00 00 f9 00 0c 04 7a 73
005 g r o u p \0 \0 \0 \0 371 \0 \f 004 z s
000110 65 74 15 15 00 00 00 12 00 00 00 04 00 00 01 61
e t 025 025 \0 \0 \0 022 \0 \0 \0 004 \0 \0 001 a
000120 03 f2 02 01 62 03 f3 ff f9 03 0d 01 68 11 11 00
003 362 002 001 b 003 363 377 371 003 \r 001 h 021 021 \0
000130 00 00 0d 00 00 00 02 00 00 01 61 03 01 61 ff ff
\0 \0 \r \0 \0 \0 002 \0 \0 001 a 003 001 a 377 377
000140 0e e0 f7 31 2f 37 16 df
016 340 367 1 / 7 026 337
000148
複製代碼
這是一個 version 9
的 RDB 文件算法
文件前 9 個字節是一個 魔數
,5 個字節REDIS
和 4 個字節的版本號 009
。數據庫
通用字符串字段,用於向RDB添加狀態,Version 7
加入的,向後兼容。AUX字段由兩個字符串組成:鍵和值
。 整理了下,除了 lua
,有這些字段:bash
SELECT_DB
和
RESIZE_DB
。 每個
SELECTDB
後都會緊跟着
RESIZEDB
,後者表示的是當前數據庫
hashtable
鍵大小的提示,每次切換數據庫時提早讀到,避免沒必要要的
rehash
。
接下來,讀到的就是Redis
中全部存儲着的K/V
對: ui
後面f9(0xf9)是 10 進制的 249,是表示 key 對象的lfu_idle
,這個字段是隻有開啓maxmemory-policy
而且設置爲volatile-lfu
或allkeys-lfu
纔會寫入文件。 LRU
的同理,不過前綴是 f8(0xf8),maxmemory-policy
要設置爲:allkeys-lru
和volatile-lru
。lua
00(0x00)是 10 進制的 0,表示string
類型的對象,01 指key
是一個字節長度:「s」, value
也是一個字節長度:「a」,spa
0e(0x0e)是 10 進制的 14,表示list
類型的對象(在3.2版本以前,是由ziplist
和linkedlist
結構保存,以後存儲是quicklist
);2個字節長度的key
:"li", 下來分別是一個長度的items
:"a" 和 "b"設計
2,表示Set
類型對象,3個長度 "set",兩個members
:"a" 和 "b"3d
繼 module
以後,redis 在 5.0 增長了新的數據類型 Stream
,不瞭解的同窗能夠Google下,不少介紹的文章。根據做者本身說,它也是充分借鑑了 kafka
的設計思想,在已有 list
的基礎上增長了另外一種流式類型。 基本。
0f(0x0f)是 10 進制的 15,是Stream
類型的對象,5個長度的key
:"stream"。而後是 StreamId
結構體, 6d 70 b5 4a 7e
分別是 10 進制的(109 112 181 74 126),二進制 01101101 01110000 10110101 01001010 01111110
,由於毫秒是uint
,加上符號位即:1 01101101 01110000 10110101 01001010 01111110
對應如圖所示: code
first-entry
剛好是建立
stream
的毫秒數,後面跟着8位的隨機數
0
;而後是
entry
結構,每一個
entry
結構前面,也會有和
streamId
相同的
messageId
,這裏就不具體逐位分析了。長度是 3,第一個字段:"name"; 第二個字段:"age",3個
entry
分別是
name:Lambert,age:29
、
name:Jack,age:26
、
name:Tom,age:30
;下來是消費組
Group
,名爲:
group
的消費組,由於沒有任何消費,因此偏移量
pending entry list
都是
0
。
0c 是 10 進制的 12,以ziplist
結構存儲的Sortedset
類型,4個長度的key
:"zset",接下來的 4 表示:4個元素,zset
會將member
和score
一塊兒保存,因此,就是2組members
;分別是:{memeber:"a",score:1}
、{member:"b",score:2}
。
0d(13) 是RDB_TYPE_HASH_ZIPLIST
,表示是ziplist
存儲的hash
類型數據,1 個長度的key:」h」。 key
後面的2,存着hash
結構的field
和value
;在 field 和 value 前面的 1,分別是指各自的長度,都是 「a」
ff(255) EOF,在全部數據寫完結束後,會以一個EOF結尾
從Version 5
開始,若是在配置文件中開啓rdbchecksum yes
,會在RDB
文件的結尾處,用 8 個字節記錄,經過CRC64
算法計算的整個文件內容的校驗和。