如何解析 redis 的 rdb 文件

安裝工具

pip install rdbtools python-lzf

或者

git clone //github.com/sripathikrishnan/redis-rdb-tools
cd redis-rdb-tools
sudo python setup.py install

解析 redis 的 rdb 文件

命令行工具使用,先看 --help

usage: usage: rdb [options] /path/to/dump.rdb

Example : rdb --command json -k "user.*" /var/redis/6379/dump.rdb

positional arguments:
  dump_file             RDB Dump file to process

optional arguments:
  -h, --help            show this help message and exit
  -c CMD, --command CMD     
                        Command to execute. Valid commands are json, diff,
                        justkeys, justkeyvals, memory and protocol
  -f FILE, --file FILE  Output file
  -n DBS, --db DBS      Database Number. Multiple databases can be provided.
                        If not specified, all databases will be included.
  -k KEYS, --key KEYS   Keys to export. This can be a regular expression
  -o NOT_KEYS, --not-key NOT_KEYS
                        Keys Not to export. This can be a regular expression
  -t TYPES, --type TYPES
                        Data types to include. Possible values are string,
                        hash, set, sortedset, list. Multiple typees can be
                        provided. If not specified, all data types will be
                        returned
  -b BYTES, --bytes BYTES
                        Limit memory output to keys greater to or equal to
                        this value (in bytes)
  -l LARGEST, --largest LARGEST
                        Limit memory output to only the top N keys (by size)
  -e {raw,print,utf8,base64}, --escape {raw,print,utf8,base64}
                        Escape strings to encoding: raw (default), print,
                        utf8, or base64.
  -x, --no-expire       With protocol command, remove expiry from all keys
  -a N, --amend-expire N
                        With protocol command, add N seconds to key expiry
                        time

參數解析

  1. -c 執行命令 輸出不同格式的數據
    1. json; 輸出 json 格式的字符串 如: [{"int":"1"}]
    2. diff; 導出可供 diff 、kdiff 、 vimdiff 比較的數據
    3. justkeys; 只輸出 key
    4. justkeyvals; 只輸出鍵值對,以空格分隔
    5. memory; 輸出內存分佈狀態
    6. protocol; 輸出原始的 RESP 協議
  2. -f 指定輸出到文件
  3. -n 指定輸出的 db
  4. -k 指定輸出哪些 key; 可以使用正則表達式, 如: '^users_\d+$'
  5. -o 排除哪些 key; 可以使用正則表達式
  6. -t 指定輸出 value 的類型
  7. -b 指定大於此位元組數的 key 輸出
  8. -l 輸出最大的多少個 key
  9. -e 轉義字符串到其他格式
    1. raw 原始字符串
    2. print
    3. utf8 輸出原始 utf8 格式字符串
    4. base64 對於二進制數據來說,可以先 base64 存儲到文件,然後在程序中 decode 出來
  10. -x 在導出 RESP 協議內容時,去掉過期時間
  11. -a 導出 RESP 協議內容時,給有過期時間的 key 加上幾秒鐘過期時間

下面看一下一些常見用法:

生成內存報告

rdb --command memory dump.rdb > memory.csv

生成 CSV 格式的內存報告。包含的列有:
數據庫 ID,數據類型,key,內存使用量(byte),編碼。內存使用量包含 key、value 和其他值,結果:

database,type,key,size_in_bytes,encoding,num_elements,len_largest_element,expiry
0,set,fruit,252,hashtable,2,6,
0,hash,webset,81,ziplist,1,13,
0,string,baiduyun,64,string,5,5,
0,list,languages,161,quicklist,2,6,
0,sortedset,page_rank,80,ziplist,1,9

使用參數過濾想要的數據

# 使用這個命令會將存儲的 int 值顯示為 json 的字符串
> rdb -c json --db 2 --type hash --key "a.*" /var/redis/6379/dump.rdb

[{},{
"aroma":{"pungent":"vinegar","putrid":"rotten eggs","floral":"roses"}}]

比較兩個 rdb 文件

> rdb --command diff /var/redis/6379/dump1.rdb | sort > dump1.txt
> rdb --command diff /var/redis/6379/dump2.rdb | sort > dump2.txt

# 使用 diff 軟件查看 diff
> kdiff3 dump1.txt dump2.txt

查看一個 key 的內存使用情況

> redis-memory-for-key person:1

> redis-memory-for-key -s localhost -p 6379 -a mypassword person:1

Key 			person:1
Bytes				111
Type				hash
Encoding			ziplist
Number of Elements		2
Length of Largest Element	8          # hash 中佔用內存最大的那個 value 的佔用位元組數

常見問題 FAQ

  • 內存報告的精確度如何?

    答:最多有 10% 的誤差

  • 存儲了一個二進制 binary 數據,但是輸出的時候是亂碼,不可讀,怎麼處理?

    答:可以使用 -e 命令先輸出 base64 編碼的字符串,然後程序中解碼之後使用

  • 這個工具能解析哪個版本的 rdb 文件?

    答:2~6 版本

  • 我不想用 python,有其他的解析方案嗎?

    答:

    1. redis-rdb is written in Ruby
    2. rdbhs is written in Haskell
    3. rdb-parser is written in Node.js
    4. rdb is written in Go
    5. rdb-rs is written in Rust
    6. 參閱 rdb 文件格式 自己寫一個解析

參考

//github.com/sripathikrishnan/redis-rdb-tools