《玩转Redis》系列文章 by zxiaofan主要讲述Redis的基础及中高级应用。本文是《玩转Redis》系列第【15】篇,最新系列文章请前往 公众号“zxiaofan”(点我点我)查看,或 百度搜索“玩转Redis zxiaofan”(点我点我)即可。
本文关键字:玩转Redis、导出没有设置过期时间的key、删除没有设置过期时间的key;
往期精选:《玩转Redis-生产环境如何导入、导出及删除大量数据》
大纲
- 如何查询Redis中没有设置过期时间的key数量
- 导出Redis中没有设置过期时间的key
- 安全删除Redis中没有设置过期时间的key
前段时间公司有新业务需要使用Redis,于是查看了生产一Redis集群的使用情况,用于评估是否能直接接入新业务。此Redis集群购买的阿里云集群社区版,8节点32G;
不看不知道,一看吓一跳。Redis实例共计 450W key,其中 230W 设置了过期时间,也就是说足足有 220W key没有设置过期时间。 What !!! 接近 50% 的数据没有过期时间,完全不符合常理,严重浪费。
不把这些钉子户揪出来,“誓不为猿”。
文末已放 github 联接。
1、如何查询Redis中未设置过期时间的key数量
1.1、使用阿里云【云数据库Redis版管理控制台】查看
如果Redis集群是云厂商提供的,厂商一般会提供管理控制台的。阿里云控制台搜索“云数据库Redis版”即可进入【云数据库Redis版管理控制台】。
1.1.1、 查看集群或节点的Key变化情况
- 进入【性能监控】,默认选择【数据节点聚合指标】,此处是区间折线图;
- 聚合指标可查看整个集群的数据情况;
- 可通过调整“查询时间”扩大数据分析范围;
- 亦可选择【数据节点】查看指定节点的数据情况;
- 进入【CloudDBA】,进入【性能趋势】,可查看区间折线图
- [Keys]一栏,可查看 key总量、设置过期时间key数量、已过期key数量 的变化信息;
1.1.2、查看全局节点的实时性能
- 进入【CloudDBA】,进入【实时性能】,选择【全局节点实时性能】;
- 默认勾选“自动刷新(5秒)”,即可查看各节点的实时性能;
1.1.3、云数据库Redis监控指标说明
监控指标 | 单位 | 说明 |
---|---|---|
Keys | Counts | Key总数量,实例存储的一级Key总数 |
Expires | Counts | 实例中设置了过期时间的键值对数量,该指标展示的是采集数据时的瞬时值 |
ExpiredKeys | Counts | 历史累计淘汰的Key总数 |
EvictedKeys | Counts | 历史累计驱逐的Key总数 |
ExpiredKeysPerSecond | Counts/s | 每秒被淘汰的Key数量 |
EvictedKeysPerSecond | Counts/s | 每秒被驱逐的Key数量 |
参考地址:https://help.aliyun.com/document_detail/43887.html 。
1.2、使用Redis命令行查看
执行 “info Keyspace” 指令即可,其中 keys 表示 集群中 key 的总量(大约 455W),expires 表示 设置了过期时间的key的总量(大约 240W)。
127.0.0.1:6379> info Keyspace
# Keyspace
db0:keys=4551001,expires=2405155,avg_ttl=219009799007
使用命令行查看的缺点是 无法查阅数据一段时间的变化情况(当然运维可以自行搭建监控体系,普罗米修斯、ELK都是不错的选择),所以云厂商给我们提供了很大的方便。
2、导出Redis中没有设置过期时间的key
一想着快 50% 的资源浪费了就无比痛心,So 必须导出这些钉子户分析罪魁祸首,然后干掉他。
原本想着阿里云应该有类似的功能,结果在官网查看以及询问阿里云技术支持,发现阿里云并未提供此功能,只能自己捣鼓了。
由于是生产环境,所以 【安全性、稳定性】 尤其重要,绝不能影响生产环境的正常使用。网上查询了相关资料,最终形成如下2种脚本解决方案:
- 使用shell脚本导出数据;
- 无长连接,相对较慢,大量连接对Redis有一定影响;
- 数据量较大时注意合理配置休眠时间;
- 使用python脚本导出数据。
2.1、使用shell脚本导出数据
脚本部分参数可配置,可按需修改以下参数:
- db_ip:Redis连接地址;
- db_port:Redis连接端口,可作为参数传入;
- password:Redis连接密码,可作为参数传入;
- cursor:第一次 scan 迭代游标,默认0,首次使用不建议修改;
- cnt:每次 scan 迭代的数量,默认1000,可根据生产情况调整优化。
需要注意的是:
- 脚本默认每scan(ttl) 1000 个key即休眠0.1秒;
- shell 脚本无法维护长连接,所以每次ttl都将创建连接,性能有一定影响;
- 有想法使用lua脚本批量 ttl 提升性能,有兴趣的同学可以实现一下,欢迎分享反馈。
脚本执行:
测试 Redis 单机版 共 30W key,按照默认的休眠频率(scan 1K 个key休眠0.1秒)总计耗时12分钟(可自行优化调整),扫描结果的 key 保存在 当前目录的 no_ttlkey.log 中。
[redis@xxx redis]$ time ./checknottl.sh 6378 password
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
scan_num: 0
real 12m14.810s
user 4m14.343s
sys 5m41.646s
脚本如下,将以下脚本内容保存为 checknottl.sh ,再执行 “chmod u+x *.sh
”授予执行权限;:
#!/bin/bash
# 查询没有设置过期时间的key;
# 脚本地址:https://github.com/zxiaofan/OpenSource_Study/tree/master/redis_scripts;
# 需在redis-cli 目录执行,或者修改脚本中的路径;
# checknottl.sh,默认每scan(ttl) 1000 个key即休眠0.1秒。
# 脚本参考网络,已做一定调整优化,更多Redis系列文章可前往:https://blog.csdn.net/u010887744/category_9356949.html;
# Note:
# shell 脚本无法维护长连接,所以每次ttl都将创建连接,性能有一定影响。
# 有想法使用lua脚本批量 ttl 提升性能,有兴趣的同学可以实现一下,欢迎分享反馈。
db_ip=127.0.0.1 # Redis ip
db_port=$1 # Redis 端口
password=$2 # Redis 密码
cursor=0 # 第一次游标
cnt=1000 # 每次迭代的数量
new_cursor=0 # 下一次游标
scan_num=0 # 已scan的key数量
./redis-cli -h $db_ip -p $db_port -a $password scan $cursor count $cnt > scan_tmp_result
new_cursor=`sed -n '1p' scan_tmp_result` # 获取下一次游标
sed -n '2,$p' scan_tmp_result > scan_result # 获取 keys
cat scan_result |while read line # 循环遍历所有 keys
# 2>/dev/null,将标准错误丢弃,Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
do
ttl_result=