Redis 内存占满

1. 问题描述

   阿里云 Redis 实例,内存占满,且在持续的增长。

2. 问题分析

在这里插入图片描述

2.1 可能的原因

  • 正常增长:业务逐渐拓展,导致 Redis 使用率正常增长;
  • 设计不合理:
    a) value 类型不合理;
    b) 存在过多的大 Value;
  • 使用不当
    a) 超期时间过长或无超期时间

2.2 分析原因推断结果

分析业务的增长量后,并不符合 Redis 增长的速度,所以可以排除正常增长;
设计都是沿用以前基础设计,经过长时间考验并不存在这个问题,基本可以排除设计不合理;
聚焦在使用不当,经查询后发现微服务之间用户鉴权的 SESSION 信息都没有设置超时时间,所以是使用不当导致的;

3. 解决问题

3.1 解决问题的大致步骤

  1. 从代码层面上对 key 添加合理的超时时间,逐个升级;
  2. 对 Redis 中的没有超时时间的 key 进行手动摄配置合理的超时时间;

3.2 修改代码,升级工程

此处不赘述

3.3 手动设置超时时间

3.3.1 查询出所有没有设置超时时间的 key

方式一: 阿里云 Redis 实例设置了数据备份的,可以从哪里下载每个 DB 备份的 rdb 文件。
然后通过 python 的 redis-rdb-tools 工具包解析为 csv 文件进行直接编辑(文件小可以),或者导入到关系型数据库中进行分析(文件大)。
python 的安装不赘述。
安装 redis-rdb-tools 工具包:

pip install rdbtools
pip install python-lzf

解析 rdb 文件生成 csv 文件:

rdb -c memory dump.rdb > memory.csv

方式二:
使用 shell 脚本和 redis-cli 查询出所有未设置超期时间的 key

#!/usr/bin/bash sh
##############################################################################
# 功能描述: 获取 Redis 中所有没有设置超时时间的key
# 前提条件: 安装了 Redis Client;网络可以访问到 Redis ;Redis 没有设置密码
##############################################################################
db_ip=IP
db_port=port
cursor=0
cnt=100
new_cursor=0

redis-cli -h $db_ip -p $db_port scan $cursor count $cnt > scan_tmp_result
new_cursor=`sed -n '1p' scan_tmp_result`
sed -n '2,$p' scan_tmp_result > scan_result
cat scan_result |while read line
do
    ttl_result=`redis-cli -h $db_ip -p $db_port ttl $line`
    if [[ $ttl_result == -1 ]];then
        echo $line >> no_ttl.log
    fi
done


while [ $cursor -ne $new_cursor ]
do
    redis-cli -h $db_ip -p $db_port scan $new_cursor count $cnt > scan_tmp_result
    new_cursor=`sed -n '1p' scan_tmp_result`
    sed -n '2,$p' scan_tmp_result > scan_result
    cat scan_result |while read line
    do
        ttl_result=`redis-cli -h $db_ip -p $db_port ttl $line`
        if [[ $ttl_result == -1 ]];then
            echo $line >> no_ttl.log
        fi
    done
done
rm -rf scan_tmp_result
rm -rf scan_result

如果没有存在大量没有设置超时时间的 key,那么这个脚本的执行时间会比较长,执行后 key 存放着在 no_ttl.log 文件里边

3.3.2 批量执行设置超时时间命令

对应方式一:
使用方式一得到的key存放到MySQL关系型数据库中,然后查询出所有未设置超时时间的 key,并组装为redis-cli 可执行的命令

select "expire", `key`, "3600" from db0;

将查询出来的结果导出为txt格式,使用空格进行分割字段值

对应方式二:
使用 shell + redis-cli 生成的 no_ttl.log 文件
将文件中的key组装成可执行的命令:

# 第一步
vim no_ttl.log
# 第二步: 在命令模式下执行, 在每行行首插入 expire
:%s/^/expire/
# 第三步: 在命令模式下执行, 在每行行尾插入超时时间, 单位是秒,示例中是 3600
:%s/$/3600/
# 最后对文件进行保存

redis-cli 安装和执行命令文件请参考:redis-cli 批量执行命令

这一步你可能还需要的命令:
删除不包含"***"字符串的行:

:v/***/d

删除包含"***"字符串的行:

:g/***/d

统计"***"出现的次数:

:%s/xxx//gn

以上几个命令都在vim的命令模式下进行

4. 验证问题是否解决

查看 Redis 中是否还存在没有设置超时时间的微服务之间用户鉴权的 SESSION 信息,
如果没有这些值,表示验证通过,如果存在一部分,说明遗漏了一些没有被修改。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值