【Redis】线上7000w+ keys && 16G内存100%的排查修复经历

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 起因 我们使用的一直是阿里云的redis, 我们并非高并发应用, 主要也就是拿来做分布式锁和少量的缓存, 基本不怎么需要维护, 昨天下午突然收到一封告警邮件, 线上redis内存使用100%, 瞬间神经绷紧感觉上控台确认.

起因

我们使用的一直是阿里云的redis, 我们并非高并发应用, 主要也就是拿来做分布式锁和少量的缓存, 基本不怎么需要维护, 昨天下午突然收到一封告警邮件,
image
线上redis内存使用100%, 瞬间神经绷紧感觉上控台确认.
image
这是一个16G的线上实例, 平时不到50%

排查修复

info信息

image

基本使用都是默认的db 0, 看到keys已经七千多万, 设置了过期的时间key只有173W..

查找bigkey, 想办法先释放一部分keys

先挂上bigkeys的命令

$ redis-cli -h  xxx.redis.rds.aliyuncs.com -a xxx --bigkeys

image
发现几个出现频率较高的大string key, 和开发同事确认, 是最近添加的redis缓存, 缓存时间为10天, 通知先关闭开关, 避免影响已经运行的任务, 进redis暂时先删除几个比较大的keys看看, 释放了少量内存
image

BoundValueOperations<String, String> contactListCache = kvLockTemplate.boundValueOps("athena.cache.contactlist" + user.getId());

现在key太多, 如果直接keys效率非常低下, 好在redis原生提供了SCAN, 可以迭代遍历, 写个简单的python脚本用scan每次扫描100W,把相关的keys给删掉.

import redis

def clean_excess(host='xxx.redis.rds.aliyuncs.com', port=6379, db=0,
                     password='xxx', pattern=None):
    _redis = redis.StrictRedis(host=host, port=port, db=db, password=password)
    i = None
    while i != 0:
        if i is None: i = 0
        print('>> scan index', i)
        _scan = _redis.scan(i, match=pattern, count="1000000")
        i, l = _scan
        if l:
            for _i in l:
                print("-- delete key {}".format(_i))
                _redis.delete(_i)
if __name__ == '__main__':
    clean_excess(pattern="athena.cache.contactlist*")

运行完成后内存使用率降到了 45%, 到这里内存问题算是解决了.
image

image

用awk快速抽样统计下keys的比例

好在我们都是keyPrefix + 数字id这样的格式, 这里抽样100W看下比例,

redis-cli -h  xxx.redis.rds.aliyuncs.com -a xxx scan 0 count 1000000 | awk -F '[0-9]' '{s=NF>0?$1:$0;print s}' | sort  | uniq -c | sort -n

image
找开发同学确认下, 这里 ip.try.counter 原本是某个版本用来锁定用户ip尝试登陆的..居然没设置过期时间, 其余的key多多少少都带了一些神奇的逻辑, 就基本没法动了....内心是崩溃的 那么先把这些清理掉

import redis

def clean_excess(host='xxx.redis.rds.aliyuncs.com', port=6379, db=0,
                     password='xxx', pattern=None):
    _redis = redis.StrictRedis(host=host, port=port, db=db, password=password)
    i = None
    while i != 0:
        if i is None: i = 0
        print('>> scan index', i)
        _scan = _redis.scan(i, match=pattern, count="1000000")
        i, l = _scan
        if l:
            for _i in l:
                print("-- delete key {}".format(_i))
                _redis.delete(_i)
if __name__ == '__main__':
    clean_excess(pattern="ip.try.counter.*")

image
image

跑了大概九个小时... 清理完后还剩了三千多万key, 内存倒是没怎么释放 其余的问了开发同学基本不能动. 使用率现在维持在50%以下暂时就不动了

结语

  • 关于redis内存逐出策略的问题, 阿里云默认给出的maxmemory刚好是等于你的内存配置大小的,也就是内存使用率100%了才会触发, 逐出策略默认是valatile-ttl只会逐出设置了过期时间的key, 相对于我们的情况, 大部分都是没设置过期时间基本就是杯水车薪. 如果改变策略为allkeys-xx 进行有效逐出,还是会影响到业务的正常运行
    image

说到底还是需要规范使用者的习惯, 该设置过期时间的不能偷懒, 确实有大内存需求的独立分配资源.

  • 其实有很多不错的现成的工具可以对redis进行诊断 可以参考下 https://scalegrid.io/blog/the-top-6-free-redis-memory-analysis-tools/
    不过这里rdb只能分析dump.rdb文件, 其他几个工具试用了下对于keys数量级过大效率都略低下, 好在我们keys命名还算有一定规律所以自己写了个简单脚本去抽样统计, 比较喜欢的是redis-memory-for-key(只是用来统计具体key的内存占用情况),也可能我使用姿势不对吧 欢迎一起探讨
相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
2月前
|
存储 缓存 NoSQL
Redis中的常用命令-get&set&keys&exists&expire&ttl&type的详细解析
总的来说,这些Redis命令提供了处理存储在内存中的键值对的便捷方式。通过理解和运用它们,你可以更有效地在Redis中操作数据,使其更好地服务于你的应用。
221 17
|
1月前
|
存储 Windows
内存卡坏了还能修吗?4种常见修复方法
内存卡出现“无法保存”或“存储异常”等问题时,不一定是硬件损坏,可能是系统错误或文件系统异常导致。本文介绍几种亲测有效的修复方法:1) 更换读卡设备排除接触问题;2) 格式化修复文件系统(需先备份数据);3) 使用DiskGenius检测坏道;4) 借助厂商工具深度修复。同时提供日常保养建议,如避免高温环境、养成数据备份习惯,延长内存卡使用寿命。通过这些方法,多数问题可轻松解决,无需更换硬件。
|
3月前
|
存储 NoSQL Redis
阿里面试:Redis 为啥那么快?怎么实现的100W并发?说出了6大架构,面试官跪地: 纯内存 + 尖端结构 + 无锁架构 + EDA架构 + 异步日志 + 集群架构
阿里面试:Redis 为啥那么快?怎么实现的100W并发?说出了6大架构,面试官跪地: 纯内存 + 尖端结构 + 无锁架构 + EDA架构 + 异步日志 + 集群架构
阿里面试:Redis 为啥那么快?怎么实现的100W并发?说出了6大架构,面试官跪地: 纯内存 + 尖端结构 +  无锁架构 +  EDA架构  + 异步日志 + 集群架构
|
3月前
|
云安全 NoSQL 安全
【Azure Redis】关于Redis的两个安全漏洞在Azure Redis是否修复问题:CVE-2024-51741 和 CVE-2024-46981
本文探讨了两个 Redis 漏洞(CVE-2024-51741 和 CVE-2024-46981)在 Azure Redis 上是否存在安全风险。CVE-2024-51741 可能因格式错误的 ACL 触发拒绝服务,而 CVE-2024-46981 或因恶意 Lua 脚本导致远程代码执行。目前 Azure Redis 使用版本 6.0,不受上述漏洞影响,且 Azure 云服务会及时修复漏洞以确保安全。文章强调 Azure 遵循严格的安全标准,为用户提供可靠保障。
156 4
|
3月前
|
弹性计算 固态存储 ice
阿里云服务器ECS内存型2核16G、4核32G和8核64G配置实例、费用和性能参数表
本文整理了2025年阿里云服务器租赁价格表,涵盖2核16G、4核32G和8核64G配置收费标准。CPU内存比为1:8,提供多种实例规格如ECS内存型r8i、通用算力型u1等。价格由CPU内存、公网带宽及系统盘组成,支持优惠折扣(年付6.7折起)。文中详细列出各配置参考价格、公网带宽与系统盘收费,并对比不同实例规格性能,如Intel Xeon和AMD EPYC处理器系列,帮助用户选择高性价比方案。具体价格以阿里云官网为准。
340 4
|
7月前
|
NoSQL 算法 Redis
redis内存淘汰策略
Redis支持8种内存淘汰策略,包括noeviction、volatile-ttl、allkeys-random、volatile-random、allkeys-lru、volatile-lru、allkeys-lfu和volatile-lfu。这些策略分别针对所有键或仅设置TTL的键,采用随机、LRU(最近最久未使用)或LFU(最少频率使用)等算法进行淘汰。
158 5
|
8月前
|
存储 监控 NoSQL
Redis大Key问题如何排查?如何解决?
Redis大Key问题如何排查?如何解决?
342 0
Redis大Key问题如何排查?如何解决?
|
9月前
|
存储 缓存 NoSQL
Redis Quicklist 竟让内存占用狂降50%?
【10月更文挑战第11天】
159 2
|
8月前
|
弹性计算
阿里云2核16G云服务器多少钱?亲测ECS内存型r8i租赁价格
阿里云2核16G云服务器,内存型r8i实例1年6折优惠后价格为1901元,月付334.19元,按小时计费0.696221元。更多配置及优惠详情,请访问阿里云ECS页面。
110 0
|
9月前
|
设计模式 Java Android开发
安卓应用开发中的内存泄漏检测与修复
【9月更文挑战第30天】在安卓应用开发过程中,内存泄漏是一个常见而又棘手的问题。它不仅会导致应用运行缓慢,还可能引发应用崩溃,严重影响用户体验。本文将深入探讨如何检测和修复内存泄漏,以提升应用性能和稳定性。我们将通过一个具体的代码示例,展示如何使用Android Studio的Memory Profiler工具来定位内存泄漏,并介绍几种常见的内存泄漏场景及其解决方案。无论你是初学者还是有经验的开发者,这篇文章都将为你提供实用的技巧和方法,帮助你打造更优质的安卓应用。

热门文章

最新文章