標籤:redis-rdb-tools
解析Redis dump.rdb檔案,分析記憶體並將資料匯出到JSON
Rdbtools是Redis的dump.rdb檔案的解析器。解析器產生類似於xml sax解析器的事件,並且非常有效記憶體明智。
此外,rdbtools還提供公用程式:
在所有資料庫和密鑰中產生資料的記憶體報告
將轉儲檔案轉換為JSON
使用標準差異工具比較兩個轉儲檔案
Rdbtools是用Python編寫的,雖然有其他語言的類似項目。請參見常見問題以擷取更多資訊。
安裝rdbtools
前提條件:
redis-py是可選的,只需要運行測試案例。
要從PyPI安裝(推薦):
pip install rdbtools
從源安裝:
git clone https://github.com/sripathikrishnan/redis-rdb-toolscd redis-rdb-toolssudo python setup.py install
命令列用法樣本
RDB工具的每一次運行都需要指定一個命令來指示解析的RDB資料應該做什麼。有效命令是:json,diff,justkeys,justkeyvals和protocol。
從兩個資料庫轉儲的JSON:
> rdb --command json /var/redis/6379/dump.rdb[{"user003":{"fname":"Ron","sname":"Bumquist"},"lizards":["Bush anole","Jackson‘s chameleon","Komodo dragon","Ground agama","Bearded dragon"],"user001":{"fname":"Raoul","sname":"Duke"},"user002":{"fname":"Gonzo","sname":"Dr"},"user_list":["user003","user002","user001"]},{"baloon":{"helium":"birthdays","medical":"angioplasty","weather":"meteorology"},"armadillo":["chacoan naked-tailed","giant","Andean hairy","nine-banded","pink fairy"],"aroma":{"pungent":"vinegar","putrid":"rotten eggs","floral":"roses"}}]過濾解析輸出
只有與Regex匹配的進程密鑰,只列印鍵和值:
> rdb --command justkeyvals --key "user.*" /var/redis/6379/dump.rdbuser003 fname Ron,sname Bumquist,user001 fname Raoul,sname Duke,user002 fname Gonzo,sname Dr,user_list user003,user002,user001
在資料庫2中只有以“a”開頭的進程散列:
> rdb -c json --db 2 --type hash --key "a.*" /var/redis/6379/dump.rdb[{},{"aroma":{"pungent":"vinegar","putrid":"rotten eggs","floral":"roses"}}]
將轉儲檔案轉換為JSON
的json命令輸出是UTF-8編碼的JSON。預設情況下,回調嘗試使用UTF-8解析RDB資料,並以\U符號或非UTF-8可解析位元組轉義非ASCII碼可列印字元\x。嘗試解碼RDB資料可能會導致位元據轉換,這可以通過使用該--escape raw選項來避免。另一個選擇是-e base64用於Base64編碼的位元據。
解析轉儲檔案並在標準輸出上列印JSON:
> rdb -c json /var/redis/6379/dump.rdb[{"Citat":["B\u00e4ttre sent \u00e4n aldrig","Bra karl reder sig sj\u00e4lv","Man ska inte k\u00f6pa grisen i s\u00e4cken"],"bin_data":"\\xFE\u0000\u00e2\\xF2"}]
將轉儲檔案解析為原始位元組,並在標準輸出上列印JSON:
> rdb -c json /var/redis/6379/dump.rdb --escape raw[{"Citat":["B\u00c3\u00a4ttre sent \u00c3\u00a4n aldrig","Bra karl reder sig sj\u00c3\u00a4lv","Man ska inte k\u00c3\u00b6pa grisen i s\u00c3\u00a4cken"],"bin_data":"\u00fe\u0000\u00c3\u00a2\u00f2"}]
產生記憶體報告
運行時會 -c memory產生一個CSV報告,其中包含該密鑰使用的近似記憶體。--bytes C並且‘--largest N可用於將輸出限制為大於C位元組的鍵或N個最大鍵。
> rdb -c memory /var/redis/6379/dump.rdb --bytes 128 -f memory.csv> cat memory.csvdatabase,type,key,size_in_bytes,encoding,num_elements,len_largest_element0,list,lizards,241,quicklist,5,190,list,user_list,190,quicklist,3,72,hash,baloon,138,ziplist,3,112,list,armadillo,231,quicklist,5,202,hash,aroma,129,ziplist,3,11
產生的CSV具有以下列 - 資料庫號,資料類型,密鑰,位元組中使用的記憶體和RDB編碼類別型。記憶體使用量包括密鑰,值和任何其他開銷。
請注意,記憶體使用量情況是近似值。一般來說,使用的實際記憶體將略高於報告的記憶體。
您可以篩選密鑰或資料庫號或資料類型的報告。
記憶體報告應該可以協助您檢測由應用程式邏輯引起的記憶體流失。它還將協助您最佳化Redis記憶體使用量。
尋找單鍵使用的記憶體
有時您只想找到特定密鑰使用的記憶體,並且在轉儲檔案上運行整個記憶體報告是耗時的。
在這種情況下,您可以使用以下redis-memory-for-key命令:
> redis-memory-for-key person:1> redis-memory-for-key -s localhost -p 6379 -a mypassword person:1Key person:1Bytes111TypehashEncodingziplistNumber of Elements2Length of Largest Element8
注意 :
這被添加到redis-rdb-tools版本0.1.3
這個命令依賴於redis-py包
比較RDB檔案
首先,使用--command diff選項,並將輸出管道輸送到標準排序公用程式
> rdb --command diff /var/redis/6379/dump1.rdb | sort > dump1.txt> rdb --command diff /var/redis/6379/dump2.rdb | sort > dump2.txt
然後,運行你最喜歡的diff程式
> kdiff3 dump1.txt dump2.txt
要限制檔案的大小,您可以使用該--key選項過濾鍵
發出Redis協議
您可以使用該命令將RDB檔案轉換為redis協議流protocol。
> rdb --c protocol /var/redis/6379/dump.rdb*4$4HSET$9users:123$9firstname$8Sripathi
您可以將輸出管道傳輸到netcat並重新匯入資料的一個子集。例如,如果要將資料分割成兩個redis執行個體,可以使用--key標誌來選擇一個資料子集,然後將輸出管道傳輸到正在啟動並執行redis執行個體以載入該資料。閱讀Redis Mass Insert瞭解更多資訊。
當列印協議輸出時,該--escape選項可用於printable或utf8避免不可列印/控制字元。
使用解析器
from rdbtools import RdbParser, RdbCallbackfrom rdbtools.encodehelpers import bytes_to_unicodeclass MyCallback(RdbCallback): ‘‘‘ Simple example to show how callback works. See RdbCallback for all available callback methods. See JsonCallback for a concrete example ‘‘‘ def __init__(self): super(MyCallback, self).__init__(string_escape=None) def encode_key(self, key): return bytes_to_unicode(key, self._escape, skip_printable=True) def encode_value(self, val): return bytes_to_unicode(val, self._escape) def set(self, key, value, expiry, info): print(‘%s = %s‘ % (self.encode_key(key), self.encode_value(value))) def hset(self, key, field, value): print(‘%s.%s = %s‘ % (self.encode_key(key), self.encode_key(field), self.encode_value(value))) def sadd(self, key, member): print(‘%s has {%s}‘ % (self.encode_key(key), self.encode_value(member))) def rpush(self, key, value): print(‘%s has [%s]‘ % (self.encode_key(key), self.encode_value(value))) def zadd(self, key, score, member): print(‘%s has {%s : %s}‘ % (str(key), str(member), str(score)))callback = MyCallback()parser = RdbParser(callback)parser.parse(‘/var/redis/6379/dump.rdb‘)
redis快照檔案dump.rdb解析工具--redis-rdb-tools