前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【最佳实践】如何使用rdbtools分析redis大key

【最佳实践】如何使用rdbtools分析redis大key

原创
作者头像
于航
修改2022-04-14 14:46:37
1.7K0
修改2022-04-14 14:46:37
举报
文章被收录于专栏:腾讯云顾问腾讯云顾问

大key的危害

熟悉redis的朋友都知道,大key是在应用的设计和实践当中应该尽量避免的风险。大key的危险有很多,例如:

  • 导致流量达到瓶颈
  • 造成分片容量的倾斜
  • 更严重的是读写大key导致系统无响应,产生大量慢查询等等

一般我们认为超过10kb大小的string类型的key或者超过1万个元素的set可以称为大key,应该进行合理的拆分

大key的获取

如何获取大key对于使用云数据库的朋友们来说,是比较轻松的一件事情,因为很多云厂商都默认提供了大key的分析工具,例如腾讯云数据库在【控制台】【系统监控】【监控概览】页面提供了大key分析功能,其原理是分析静态RDB文件然后从中抓出大key按照大小顺序排序,本文的重点是分享下如何使用开源工具rdbtools进行大key分析

rdbtools的安装

rdbtools有三个主要的功能

  • 分析静态rdb文件并生成csv格式的内存报告
  • 将rdb文件转储成为json格式
  • 利用diff工具比较两个rdb文件的不同 下面我们开始

1.第一步我们先安装python和pip

由于作者操作系统使用的是centos8.0,默认提供了python3和pip3因此无需额外安装,读者可以自行安装,网上教程很多,不再赘述。

代码语言:txt
复制
>>> import sys
>>> sys.version
'3.6.8 (default, May 21 2019, 23:51:36) \n[GCC 8.2.1 20180905 (Red Hat 8.2.1-3)]'
>>> 

2.获取rdb文件

自建redis的同学可以使用redis-port工具集导出rdb文件。使用云数据库的朋友可以联系云厂商获取下载链接。

腾讯云redis控制台获取备份下载链接
腾讯云redis控制台获取备份下载链接

直接导出到本地或者使用rz/sz导入到自己的机器中

代码语言:txt
复制
[root@VM-4-10-centos ~]# yum install lrzsz
Last metadata expiration check: 0:10:21 ago on Thu 18 Mar 2021 04:31:25 PM CST.
Dependencies resolved.
========================================================================================================================================================================================
 Package                                  Arch                                      Version                                             Repository                                 Size
========================================================================================================================================================================================
Installing:
 lrzsz                                    x86_64                                    0.12.20-43.el8                                      BaseOS                                     84 k

Transaction Summary
========================================================================================================================================================================================
Install  1 Package

Total download size: 84 k
Installed size: 190 k
Is this ok [y/N]: y
Downloading Packages:
lrzsz-0.12.20-43.el8.x86_64.rpm                                                                                                                         2.2 MB/s |  84 kB     00:00    
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Total                                                                                                                                                   2.1 MB/s |  84 kB     00:00     
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
  Preparing        :                                                                                                                                                                1/1 
  Installing       : lrzsz-0.12.20-43.el8.x86_64                                                                                                                                    1/1 
  Running scriptlet: lrzsz-0.12.20-43.el8.x86_64                                                                                                                                    1/1 
  Verifying        : lrzsz-0.12.20-43.el8.x86_64                                                                                                                                    1/1 

Installed:
  lrzsz-0.12.20-43.el8.x86_64                                                                                                                                                           

Complete!

3.安装rdbtools

代码语言:txt
复制
[root@VM-4-10-centos ~]# pip install rdbtools

安装好之后通过help命令简单了解下,注意--command or -c是必选参数

代码语言:txt
复制
[root@VM-4-10-centos ~]# rdb --help
usage: usage: rdb [options] /path/to/dump.rdb

Example : rdb --command json -k "user.*" /var/redis/6379/dump.rdb //表示从dump.rdb文件中分析出所有以`user.`开头的key并输出为jason格式,打印到屏幕上

positional arguments: //位置参数
  dump_file             RDB Dump file to process

optional arguments:
  -h, --help            show this help message and exit//查看命令的帮助信息
  -c CMD, --command CMD//必选参数,-c json表示存储成json格式,最常用的是 -c memory表示生成csv格式的内存快照,还有diff模式进行对比
                        Command to execute. Valid commands are json, diff,
                        justkeys, justkeyvals, memory and protocol
  -f FILE, --file FILE  //输出到文件
                        Output file
  -n DBS, --db DBS      //指定只分析某个编号的db,例如db0,如果不指定默认包含所有
                        Database Number. Multiple databases can be provided.
                        If not specified, all databases will be included.
  -k KEYS, --key KEYS   //指定分析并导出某个前缀的key,支持正则表达式
                        Keys to export. This can be a regular expression
  -o NOT_KEYS, --not-key NOT_KEYS //指定不分析并导出某个前缀的key,支持正则表达式
                        Keys Not to export. This can be a regular expression
  -t TYPES, --type TYPES //指定分析哪些数据类型,例如string、hash、set、list、sortedset等,可以指定多个类型,如果不指定默认分析所有
                        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 //指定输出超过多少Byte的key,例如--bytes 10240表示只输出超过10k大小的key
                        Limit memory output to keys greater to or equal to
                        this value (in bytes)
  -l LARGEST, --largest LARGEST //输出TOP多少的key,例如--largest 100,表示只输出top 100的key
                        Limit memory output to only the top N keys (by size)
  -e {raw,print,utf8,base64}, --escape {raw,print,utf8,base64} //指定输出的默认编码,默认RAW
                        Escape strings to encoding: raw (default), print,
                        utf8, or base64.
  -x, --no-expire       With protocol command, remove expiry from all keys // 只有command为protocol模式才有效,表示不输出所有的可过期的key,只输出哪些永不过期的key
  -a N, --amend-expire N // 只有command为protocol模式才有效,表示给设置过期时间的key增加N秒的过期时间
                        With protocol command, add N seconds to key expiry
                        time

4.接下来我们简单分析下

代码语言:txt
复制
[root@VM-4-10-centos ~]# rdb --command json dump.rdb > ./test
WARNING: python-lzf package NOT detected. Parsing dump file will be very slow unless you install it. To install, run the following command:

pip install python-lzf

这里提示我们由于没有python-lzf包导致分析速度很慢,那我们就安装一下吧。可以先更新一下yum源,防止找不到包

代码语言:txt
复制
[root@VM-4-10-centos ~]# yum update

然后再次安装

代码语言:txt
复制
[root@VM-4-10-centos ~]# pip install python-lzf
WARNING: Running pip install with root privileges is generally not a good idea. Try `pip install --user` instead.
Collecting python-lzf
  Downloading http://mirrors.tencentyun.com/pypi/packages/e3/33/b8f67bbe695ccc39f868ae55378993a7bde1357a0567803a80467c8ce1a4/python-lzf-0.2.4.tar.gz
Installing collected packages: python-lzf
  Running setup.py install for python-lzf ... error
    Complete output from command /usr/bin/python3.6 -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-go178sdk/python-lzf/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-6oauj90r-record/install-record.txt --single-version-externally-managed --compile:
    running install
    running build
    running build_ext
    building 'lzf' extension
    creating build
    creating build/temp.linux-x86_64-3.6
    gcc -pthread -Wno-unused-result -Wsign-compare -DDYNAMIC_ANNOTATIONS_ENABLED=1 -DNDEBUG -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE -fPIC -fwrapv -fPIC -I. -I/usr/include/python3.6m -c lzf_module.c -o build/temp.linux-x86_64-3.6/lzf_module.o -Wall
    gcc: error: /usr/lib/rpm/redhat/redhat-hardened-cc1: No such file or directory
    error: command 'gcc' failed with exit status 1
    
    ----------------------------------------
Command "/usr/bin/python3.6 -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-go178sdk/python-lzf/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-6oauj90r-record/install-record.txt --single-version-externally-managed --compile" failed with error code 1 in /tmp/pip-build-go178sdk/python-lzf/

这里报错gcc编译的时候报错了,上github搜索了一下,是没有安装 redhat-rpm-config,那我们就安装下

代码语言:txt
复制
$ sudo dnf install redhat-rpm-config

安装好redhat-rpm-config之后,再安装python-lzf又报错了,这次提示少了Python.h,上网查了下,原来这次是缺乏python-devel

代码语言:txt
复制
[root@VM-4-10-centos ~]# pip install python-lzf
WARNING: Running pip install with root privileges is generally not a good idea. Try `pip install --user` instead.
Collecting python-lzf
  Downloading http://mirrors.tencentyun.com/pypi/packages/e3/33/b8f67bbe695ccc39f868ae55378993a7bde1357a0567803a80467c8ce1a4/python-lzf-0.2.4.tar.gz
Installing collected packages: python-lzf
  Running setup.py install for python-lzf ... error
    Complete output from command /usr/bin/python3.6 -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-dxcuwlzv/python-lzf/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-9n6nf8r_-record/install-record.txt --single-version-externally-managed --compile:
    running install
    running build
    running build_ext
    building 'lzf' extension
    creating build
    creating build/temp.linux-x86_64-3.6
    gcc -pthread -Wno-unused-result -Wsign-compare -DDYNAMIC_ANNOTATIONS_ENABLED=1 -DNDEBUG -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -D_GNU_SOURCE -fPIC -fwrapv -fPIC -I. -I/usr/include/python3.6m -c lzf_module.c -o build/temp.linux-x86_64-3.6/lzf_module.o -Wall
    lzf_module.c:3:10: fatal error: Python.h: No such file or directory
     #include "Python.h"
              ^~~~~~~~~~
    compilation terminated.
    error: command 'gcc' failed with exit status 1
    
    ----------------------------------------
Command "/usr/bin/python3.6 -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-dxcuwlzv/python-lzf/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-9n6nf8r_-record/install-record.txt --single-version-externally-managed --compile" failed with error code 1 in /tmp/pip-build-dxcuwlzv/python-lzf/

我们直接yum安装可以找不到,例如下面所示,我们尝试搜索一下yum search一下,找到了,python36-devel.x86_64,然后再次安装。

代码语言:txt
复制
[root@VM-4-10-centos ~]# yum install python-devel
Last metadata expiration check: 0:00:58 ago on Thu 18 Mar 2021 05:14:53 PM CST.
No match for argument: python-devel
Error: Unable to find a match: python-devel
代码语言:txt
复制
[root@VM-4-10-centos ~]# yum search python3 | grep devel
Last metadata expiration check: 0:01:29 ago on Thu 18 Mar 2021 05:14:53 PM CST.
python3-qscintilla-qt5-devel.noarch : Development files for QScintilla-qt5 python3 bindings
boost169-mpich-python3-devel.x86_64 : Shared library symbolic links for Boost.MPI Python 3 component
boost169-openmpi-python3-devel.x86_64 : Shared library symbolic links for Boost.MPI Python 3 component
boost169-python3-devel.x86_64 : Shared object symbolic links for Boost.Python 3
python3-TurboGears2.noarch : Next generation front-to-back web development megaframework
python3-cherrypy.noarch : Pythonic, object-oriented web development framework
python3-hupper.noarch : Integrated process monitor for developing servers
python3-idle.i686 : A basic graphical development environment for Python
python3-idle.x86_64 : A basic graphical development environment for Python
python3-kobo.noarch : Python modules for tools development
python3-pycxx-devel.noarch : PyCXX header and source files
python3-werkzeug.noarch : The Swiss Army knife of Python web development
python36-devel.x86_64 : Libraries and header files needed for Python development
python38-devel.x86_64 : Libraries and header files needed for Python development
python38-idle.x86_64 : A basic graphical development environment for Python

搞定了这些依赖,我们再次安装就很顺利了

代码语言:txt
复制
[root@VM-4-10-centos ~]# pip install python-lzf
WARNING: Running pip install with root privileges is generally not a good idea. Try `pip install --user` instead.
Collecting python-lzf
  Downloading http://mirrors.tencentyun.com/pypi/packages/e3/33/b8f67bbe695ccc39f868ae55378993a7bde1357a0567803a80467c8ce1a4/python-lzf-0.2.4.tar.gz
Installing collected packages: python-lzf
  Running setup.py install for python-lzf ... done
Successfully installed python-lzf-0.2.4

5.正式分析

接下来给一个常用的命令,分析rdb文件当中top100的大key,可以使用lrzsz下载到本地,使用Excel进行分析。

代码语言:txt
复制
root@VM-4-10-centos ~]# rdb -c memory dump-6120957-redis-server-ignore-140016731-ignore-1-ignore.rdb -l 100  -f ./dump_memory.csv
Excel分析内存快照CSV文件
Excel分析内存快照CSV文件

CSV中字段说明

database

type

key

size_in_bytes

encoding

num_elements

len_largest_element

expiry

key所属db编号

key的类型例如string list set等

key名

key大小(字节数)

编码方式(hashtable,ziplist,string等)

key中元素的个数

key中最大元素的长度

过期时间

也可以使用LOAD DATA INFILE语句导入到数据库中,使用SQL语句进行分析,诸如查询总内存占用、查询总key个数、查询特定type的key个数等等。不再赘述

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

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

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

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

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