Redis5.0 RDB文件超詳細解析

Redis RDB介紹

RDB 是 Redis 將 server 端的內存中的 k/v 對以二進制的方式,持久化存儲的一種文件形式。 文件中,通常會以 對象的長度+對象 的格式來存儲,只要根據這個格式,就能漸進的遍歷整個文件。 Redis 還支持開啓 LZF 的壓縮算法,能夠犧牲CPU時間,來減小 RDB 文件的大小;若是開啓LZF而且超過20個bytes時, 會將壓縮後的字符寫入文件。redis

RDB文件格式

➜  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 文件算法

魔數 Magic Number

文件前 9 個字節是一個 魔數,5 個字節REDIS 和 4 個字節的版本號 009數據庫

輔助字段 Aux Fields

通用字符串字段,用於向RDB添加狀態,Version 7 加入的,向後兼容。AUX字段由兩個字符串組成:鍵和值。 整理了下,除了 lua,有這些字段:bash

  • redis-ver:版本號
  • redis-bits:OS Arch
  • ctime:RDB文件建立時間
  • used-mem:使用內存大小
  • repl-stream-db:在server.master客戶端中選擇的數據庫
  • repl-id:當前實例 replication ID
  • repl-offset:當前實例複製的偏移量

數據庫索引

fe(0xfe),fb(0xfb)是 10 進制的 254 和 251,在 RDB 分別對應着, SELECT_DBRESIZE_DB。 每個 SELECTDB後都會緊跟着 RESIZEDB,後者表示的是當前數據庫 hashtable鍵大小的提示,每次切換數據庫時提早讀到,避免沒必要要的 rehash

數據庫鍵值對

接下來,讀到的就是Redis中全部存儲着的K/V對: ui

類型對照表

LFU/LRU Idle

後面f9(0xf9)是 10 進制的 249,是表示 key 對象的lfu_idle,這個字段是隻有開啓maxmemory-policy而且設置爲volatile-lfuallkeys-lfu纔會寫入文件。 LRU的同理,不過前綴是 f8(0xf8),maxmemory-policy要設置爲:allkeys-lruvolatile-lrulua

String結構

00(0x00)是 10 進制的 0,表示string類型的對象,01 指key是一個字節長度:「s」, value 也是一個字節長度:「a」,spa

List結構

0e(0x0e)是 10 進制的 14,表示list類型的對象(在3.2版本以前,是由ziplistlinkedlist結構保存,以後存儲是quicklist);2個字節長度的key:"li", 下來分別是一個長度的items:"a" 和 "b"設計

Set結構

2,表示Set類型對象,3個長度 "set",兩個members:"a" 和 "b"3d

Stream結構

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:29name:Jack,age:26name:Tom,age:30;下來是消費組 Group,名爲: group 的消費組,由於沒有任何消費,因此偏移量 pending entry list都是 0

ZSet結構

0c 是 10 進制的 12,以ziplist結構存儲的Sortedset類型,4個長度的key:"zset",接下來的 4 表示:4個元素,zset會將memberscore一塊兒保存,因此,就是2組members;分別是:{memeber:"a",score:1}{member:"b",score:2}

Hash結構

0d(13) 是RDB_TYPE_HASH_ZIPLIST,表示是ziplist存儲的hash類型數據,1 個長度的key:」h」。 key後面的2,存着hash結構的fieldvalue;在 field 和 value 前面的 1,分別是指各自的長度,都是 「a」

文件EOF

ff(255) EOF,在全部數據寫完結束後,會以一個EOF結尾

CheckSum

Version 5 開始,若是在配置文件中開啓rdbchecksum yes,會在RDB文件的結尾處,用 8 個字節記錄,經過CRC64算法計算的整個文件內容的校驗和。

相關文章
相關標籤/搜索