Redis:内存陡增100%深度复盘 简单回顾

简介: 大KEY随流量激增占满带宽,5分钟内致Redis内存100%,触发全面超时。内存满并非直接致崩,主因或是过期Key集中删除阻塞,或非正常写入导致淘汰机制失灵,引发性能雪崩。

(1)因为大KEY调用量,随着白天自然流量趋势增长而增长,最终在业务高峰最高点期占满带宽使用100%。

(2)从而引发redis的内存使用率,在5min之内从0%->100%。

(3)最终全面GET SET timeout崩溃(11点22分02秒)。

(4)最终导致页面返回timeout。

疑问点:内存使用率100% 就等同于redis不可用吗?
解答:正常使用情况下,不是。
redis有【缓存淘汰机制】,Redis 在内存使用率达到 100% 时不会直接崩溃。相反,它依赖内存淘汰策略来释放内存,确保系统的稳定性。

学习更多:24 替换策略:缓存满了怎么办?
https://time.geekbang.org/column/article/294640
这个配置在哪里?

大部分同学都是不会主动去调整这里的参数的。
因此大概率默认的是:volatile-lru
● 行为: 使用 LRU(Least Recently Used,最近最少使用)算法驱逐键。volatile-lru 仅驱逐设有过期时间的键,allkeys-lru 则驱逐所有键。
● 适用场景: 缓存场景,不介意丢失一些数据。
确保你根据实际需求配置适当的内存淘汰策略,以便在内存达到上限时,系统能够稳定地处理新请求,而不会出现写操作失败的情况(只要不是noeviction)。
也就是说,照理SET GET都应该没啥问题才对(先不考虑其他复杂命令)。
● 尽管 Redis 本身不会轻易崩溃,但如果内存耗尽且没有淘汰策略或者淘汰策略未能生效,Redis 可能拒绝新的写操作,并返回错误:OOM command not allowed when used memory > 'maxmemory'
● 如果系统的配置或者操作系统的内存管理不当,可能会导致 Redis 进程被操作系统杀死。
疑问点:但是事故现象就是:内存使用率100% 时,redis不可用,怎么解释?
猜测1:会是淘汰不及时导致的性能瓶颈吗?
也就是说:写入的速度>>淘汰的速度。
解答:如果是正常的业务写入,不可能!
● redis纯内存,淘汰速度是非常快的;
● 这个业务特性,也并非高频写入;
这个redis实例其实里面存储的KEY很少,最终占了整个实例的内存使用率<5%。

不太符合正常使用下KEY不断增多,最终挤爆内存使用率的问题。
因此,初步结论:Redis 的崩溃一般不会是由于单纯写入速度超过淘汰速度引起的,尤其是使用了合理的内存淘汰策略时;如果写入速度非常高,而淘汰策略无法及时清除旧数据,Redis 可能会非常频繁地进行键的查找和淘汰操作,从而导致性能下降。
18 波动的响应延迟:如何应对变慢的Redis?(上)
https://time.geekbang.org/column/article/286549
具体机制如下:
过期 key 的自动删除机制。它是 Redis 用来回收内存空间的常用机制,应用广泛,本身就会引起 Redis 操作阻塞,导致性能变慢,所以,你必须要知道该机制对性能的影响。
Redis 键值对的 key 可以设置过期时间。默认情况下,Redis 每 100 毫秒会删除一些过期 key,具体的算法如下:
1.采样:
ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP 个数的 key,并将其中过期的 key 全部删除;
2.如果超过 25% 的 key 过期了,则重复删除的过程,直到过期 key 的比例降至 25% 以下。
ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP 是 Redis 的一个参数,默认是 20,那么,一秒内基本有 200 个过期 key 会被删除。这一策略对清除过期 key、释放内存空间很有帮助。如果每秒钟删除 200 个过期 key,并不会对 Redis 造成太大影响。
但是,如果触发了上面这个算法的第二条,Redis 就会一直删除以释放内存空间。注意,删除操作是阻塞的(Redis 4.0 后可以用异步线程机制来减少阻塞影响)。所以,一旦该条件触发,Redis 的线程就会一直执行删除,这样一来,就没办法正常服务其他的键值操作了,就会进一步引起其他键值操作的延迟增加,Redis 就会变慢。
那么,算法的第二条是怎么被触发的呢?其中一个重要来源,就是频繁使用带有相同时间参数的 EXPIREAT 命令设置过期 key,这就会导致,在同一秒内有大量的 key 同时过期。
可以类比JVM频繁GC造成的性能影响。
猜测2:那就是写入太凶猛,且是【非正常业务写入】
那到底是什么导致了内存使用率激增呢??

蛛丝马迹
如何解决Redis内存使用率突然升高:
https://help.aliyun.com/zh/redis/support/how-to-solve-the-sudden-increase-in-redis-memory-usage?spm=a2c4g.11186623.0.i12
因此查阅了资料,发现最为贴近的答案。

证据支撑

相关文章
|
项目管理 Python
深入理解Python中的os.chdir()方法
`os.chdir()`是Python中用于改变当前工作目录的方法,简化文件和目录操作。语法为`os.chdir(path)`,`path`是目标目录路径。示例中展示了如何切换及检查工作目录。它常用于脚本执行、文件操作和多项目管理。注意目标目录必须存在,否则会抛出异常。相关方法有`os.getcwd()`获取当前目录和`os.path.join()`拼接路径。使用时结合异常处理可提升效率。参考[Python官方文档](https://docs.python.org/3/library/os.html)。
1102 3
|
SQL 数据库 数据库管理
数据库SQL函数应用技巧与方法
在数据库管理中,SQL函数是处理和分析数据的强大工具
Request failed with status code 400,使用axios.post要发送参数,认真比对原项目,看看有没有忘记什么?
Request failed with status code 400,使用axios.post要发送参数,认真比对原项目,看看有没有忘记什么?
|
SQL 关系型数据库 MySQL
在 MySQL 中使用 `GROUP BY` 子句
【8月更文挑战第12天】
1489 1
|
前端开发 关系型数据库 测试技术
django集成pytest进行自动化单元测试实战
在Django项目中集成Pytest进行单元测试可以提高测试的灵活性和效率,相比于Django自带的测试框架,Pytest提供了更为丰富和强大的测试功能。本文通过一个实际项目ishareblog介绍django集成pytest进行自动化单元测试实战。
329 3
django集成pytest进行自动化单元测试实战
|
Linux Shell
Linux系统编程:掌握popen函数的使用
记得在使用完 `popen`打开的流后,总是使用 `pclose`来正确关闭它,并回收资源。这种做法符合良好的编程习惯,有助于保持程序的健壮性和稳定性。
478 3
|
监控 Linux
性能分析之 Linux 系统中 ps&top 中 CPU 百分比不一致?
【8月更文挑战第18天】性能分析之 Linux 系统中 ps&top 中 CPU 百分比不一致?
603 5
|
缓存 JavaScript API
全面解析 Pinia:Vue 状态管理的新选择
本文深入探讨了 Pinia,作为 Vuex 的替代品,提供了一种更简洁和高效的状态管理方案。文章涵盖了 Pinia 的核心特性,包括支持 Vue2 和 Vue3、TypeScript 支持、无需嵌套模块的设计,以及对同步和异步操作的支持。详细介绍了如何创建和使用 Store,管理状态、Getters 和 Actions,重置状态以及通过 $patch 方法批量更新状态。最后,探讨了如何在不同 Store 之间共享数据和逻辑,为开发者提供了实用的 Pinia 使用指南。
393 0
|
XML 前端开发 JavaScript
Web的三个主要部分
Web的三个主要部分
2621 1
|
Java
map.getOrDefault
map.getOrDefault
359 0