前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Redis RDB文件离线分析

Redis RDB文件离线分析

原创
作者头像
用户1082366
发布2019-02-22 12:17:50
3.4K0
发布2019-02-22 12:17:50
举报
文章被收录于专栏:西郊手记西郊手记

概述

Redis是一款键值内存数据库,支持丰富的数据类型,在极高的性能下,还支持数据的持久化存储。

持久化机制分为RDB的方式和AOF两种机制。AOF本质上是数据操作的redo log,和RDB相比,有更高的实时性,在Redis启动时也会优先加载AOF格式文件。而RDB则是数据内存的一个snapshots,在存储时使用带压缩的紧凑二进制结构,对比AOF,RDB机制导出的数据量更小,在存储、全量复制和数据离线分析中更好的选择。

今天我们就来重点说说RDB文件的离线分析。

RDB文件格式简述

RDB文件格式为优化读写性能,将内存结构尽可能对齐文件格式,并在能使用压缩都使用压缩以减少文件大小。

先看看官方文档,RDB的文件格式总览如下:

----------------------------# RDB is a binary format. There are no new lines or spaces in the file.
52 45 44 49 53              # Magic String "REDIS"
00 00 00 03                 # RDB Version Number in big endian. In this case, version = 0003 = 3
----------------------------
FE 00                       # FE = code that indicates database selector. db number = 00
----------------------------# Key-Value pair starts
FD $unsigned int            # FD indicates "expiry time in seconds". After that, expiry time is read as a 4 byte unsigned int
$value-type                 # 1 byte flag indicating the type of value - set, map, sorted set etc.
$string-encoded-key         # The key, encoded as a redis string
$encoded-value              # The value. Encoding depends on $value-type
----------------------------
FC $unsigned long           # FC indicates "expiry time in ms". After that, expiry time is read as a 8 byte unsigned long
$value-type                 # 1 byte flag indicating the type of value - set, map, sorted set etc.
$string-encoded-key         # The key, encoded as a redis string
$encoded-value              # The value. Encoding depends on $value-type
----------------------------
$value-type                 # This key value pair doesn't have an expiry. $value_type guaranteed != to FD, FC, FE and FF
$string-encoded-key
$encoded-value
----------------------------
FE $length-encoding         # Previous db ends, next db starts. Database number read using length encoding.
----------------------------
...                         # Key value pairs for this database, additonal database
                            
FF                          ## End of RDB file indicator
8 byte checksum             ## CRC 64 checksum of the entire file.

文件头部以“REDIS” 5个字节开头:52 45 44 49 53

后面4个字节是RDB的版本号,最新的版本5.0.3是9:00 00 00 09

之后2个字节是选择数据库选择数据,比如 FE 00, select 0

然后开始键值数据,每个Key结构包含4个部分:

  1. Key过期时间,这里和存储不一样的是存储的是绝对时间,不是相对时间。
  2. value-type是value的类型标记,具体如下:
  3. Key的值,按String的类型编码。
  4. Value的值,按2指示类型编码。

而其中value-type的编码如下:

  1. 0 = "String Encoding"
  2. 1 = "List Encoding"
  3. 2 = "Set Encoding"
  4. 3 = "Sorted Set Encoding"
  5. 4 = "Hash Encoding"
  6. 9 = "Zipmap Encoding"
  7. 10 = "Ziplist Encoding"
  8. 11 = "Intset Encoding"
  9. 12 = "Sorted Set in Ziplist Encoding"
  10. 13 = "Hashmap in Ziplist Encoding"

而各个value的编码由于复杂度和篇幅原因,这里不在阐述,可以进一步参考:https://github.com/sripathikrishnan/redis-rdb-tools/wiki/Redis-RDB-Dump-File-Format 一文。

RDB文件分析

rdb分析的应用场景较多,比如Redis数据差异对比,大Key的分析,键值的统计等。

熟话说工欲善其事,必先利其器,虽然上述部分我们简单阐述了rdb的文件格式,但要自己写从零写一个分析器还是有较大的工作量。好在开源社区里已经有不少RDB文件分析组件了。其中最著名的莫过于redis-rdb-tools(https://github.com/sripathikrishnan/redis-rdb-tools),支持多个rdb文件数据对比,内存报告,key分析能特性并支持将数据导出为JSON格式。

redis-rdb-tools使用python开发,同时可以运行在python2和python3上。

安装

由于rdb为压缩格式,需要python-lzf,先安装python-lzf:

pip install rdbtools python-lzf

从源码里安装:

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

使用

将数据转为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"}]

生成内存报告:

> rdb -c memory /var/redis/6379/dump.rdb --bytes 128 -f memory.csv
> cat memory.csv

database,type,key,size_in_bytes,encoding,num_elements,len_largest_element
0,list,lizards,241,quicklist,5,19
0,list,user_list,190,quicklist,3,7
2,hash,baloon,138,ziplist,3,11
2,list,armadillo,231,quicklist,5,20
2,hash,aroma,129,ziplist,3,11

查看单个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

多个RDB的对比

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

将rdb转为aof格式流

> rdb --c protocol /var/redis/6379/dump.rdb

*4
$4
HSET
$9
users:123
$9
firstname
$8
Sripathi

如果这些工具还不能满足你的使用需求的话,redis-rdb-tools还提供了高度抽象的Parser供定制使用:

直接上代码:

from rdbtools import RdbParser, RdbCallback
from rdbtools.encodehelpers import bytes_to_unicode

class 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')

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概述
  • RDB文件格式简述
  • RDB文件分析
    • 安装
      • 使用
      相关产品与服务
      云数据库 Redis
      腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档