当我们想了解一个redis时,除了它的软硬件配置、架构,还想知道这个redis中到底存储了什么?占用了多少内存?是否存在bigkey?
下面我们就用rdbtools工具和SQL来统计生产环境中redis的key分布,步骤如下:
1. 生成rdb快照(从库执行)
#连接redis
redis-cli -p 6379
127.0.0.1:6379> config get dir
1) "dir"
2) "/data/redisdb/redis_6379"
127.0.0.1:6379> config get dbfilename
1) "dbfilename"
2) "dump.rdb"
#生成rdb快照
127.0.0.1:6379> bgsave
Background saving started
2. rdbtools工具解析rdb
#安装pip
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
yum -y install python-pip
pip list
#安装redis-rdb-tools
yum -y install python-devel
pip install python-lzf
pip install rdbtools
#解析rdb文件
nohup rdb -c memory /data/redisdb/redis_6379/dump.rdb > /data/redisdb/redis_6379/dump.csv &
3. 解析结果导入mysql
#创建redis内存分析表
use modb;
drop table if exists memory_6379;
CREATE TABLE `memory_6379` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`database` int(128) DEFAULT NULL,
`type` varchar(128) DEFAULT NULL,
`KEY` varchar(128) NOT NULL,
`size_in_bytes` bigint(20) DEFAULT NULL,
`encoding` varchar(128) DEFAULT NULL,
`num_elements` bigint(20) DEFAULT NULL,
`len_largest_element` varchar(128) DEFAULT NULL,
`expiry` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
#导入csv至mysql表
Load DATA INFILE '/data/redisdb/redis_6379/dump.csv'
Into Table memory_6379
character set utf8
Fields Terminated By ','
Enclosed By '"'
Escaped By '"'
Lines Terminated By '\n'
ignore 1 lines
(`database`,type,`key`,size_in_bytes,encoding,num_elements,len_largest_element,expiry);
4. 自定义SQL统计key分布
#自定义统计SQL
#查看bigkey
use modb;
select * from memory_6379 order by size_in_bytes desc limit 20;
#按Key样式统计(截取开始至第一个数字或'/'之间的字符串)
SELECT
LEFT(`key`, LENGTH(`key`) - LOCATE('/', REVERSE(`key`))) as `key`,
sum(cnt) as cnt,
sum(size_in_bytes) as size_in_bytes
from
(
select
left (`key`, LEAST
(
IF(LOCATE(0,`key`)=0,9999,LOCATE(0,`key`)),
IF(LOCATE(1,`key`)=0,9999,LOCATE(1,`key`)),
IF(LOCATE(2,`key`)=0,9999,LOCATE(2,`key`)),
IF(LOCATE(3,`key`)=0,9999,LOCATE(3,`key`)),
IF(LOCATE(4,`key`)=0,9999,LOCATE(4,`key`)),
IF(LOCATE(5,`key`)=0,9999,LOCATE(5,`key`)),
IF(LOCATE(6,`key`)=0,9999,LOCATE(6,`key`)),
IF(LOCATE(7,`key`)=0,9999,LOCATE(7,`key`)),
IF(LOCATE(8,`key`)=0,9999,LOCATE(8,`key`)),
IF(LOCATE(9,`key`)=0,9999,LOCATE(9,`key`))
)-1) as `key`,
count(*) as cnt,
sum(size_in_bytes) as size_in_bytes
from memory_6379
group by
left (`key`, LEAST
(
IF(LOCATE(0,`key`)=0,9999,LOCATE(0,`key`)),
IF(LOCATE(1,`key`)=0,9999,LOCATE(1,`key`)),
IF(LOCATE(2,`key`)=0,9999,LOCATE(2,`key`)),
IF(LOCATE(3,`key`)=0,9999,LOCATE(3,`key`)),
IF(LOCATE(4,`key`)=0,9999,LOCATE(4,`key`)),
IF(LOCATE(5,`key`)=0,9999,LOCATE(5,`key`)),
IF(LOCATE(6,`key`)=0,9999,LOCATE(6,`key`)),
IF(LOCATE(7,`key`)=0,9999,LOCATE(7,`key`)),
IF(LOCATE(8,`key`)=0,9999,LOCATE(8,`key`)),
IF(LOCATE(9,`key`)=0,9999,LOCATE(9,`key`))
)-1)
) tmp
group by LEFT(`key`, LENGTH(`key`) - LOCATE('/', REVERSE(`key`)))
order by size_in_bytes desc
;
至此,你对这个redis已胸有成竹。
优点:
- 对生产环境影响小
- 内存占用计算值较为准确
- 灵活自定义统计
缺点:
- 耗时较长
最后修改时间:2022-07-18 10:57:37
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




