运维
Redis 报内存不足怎么处理
Redis 报内存不足时,通常是因为 Redis 占用的物理内存已经接近或者超过了配置的最大内存限制。这时可以采取以下几种步骤来处理:
第一,使用 INFO memory 命令查看 Redis 的内存使用情况,看看是否真的达到了最大内存限制。
第二,如果服务器还有可用内存的话,修改 redis.conf 中的 maxmemory 参数,增加 Redis 的最大内存限制。比如将最大内存设置为 8GB:
第三,修改 maxmemory-policy 参数来调整内存淘汰策略。比如可以选择 allkeys-lru 策略,让 Redis 自动删除最近最少使用的键。
Redis key过期策略有哪些?
Redis 主要采用了两种过期删除策略来保证过期的 key 能够被及时删除,包括惰性删除和定期删除。
惰性删除是最基本的策略,当客户端访问一个 key 时,Redis 会检查该 key 是否已过期,如果过期就会立即删除并返回 null。
这种策略的优点是不会有额外的 CPU 开销,只在访问 key 时才检查。但问题是如果一个过期的 key 永远不被访问,它就会一直占用内存。
于是就有了定期删除策略,Redis 会定期随机选择一些设置了过期时间的 key 进行检查,删除其中已过期的 key。这个过程默认每秒执行 10 次,每次随机选择 20 个 key 进行检查。
Redis有哪些内存淘汰策略?
当内存使用接近 maxmemory 限制时,Redis 会依据内存淘汰策略来决定删除哪些 key 以缓解内存压力。
常用的内存淘汰策略有八种,分别是默认的 noeviction,内存不足时不会删除任何 key,直接返回错误信息,生产环境下基本上不会使用。
然后是针对所有 key 的 allkeys-lru、allkeys-lfu 和 allkeys-random。lru 会删除最近最少使用的 key,在纯缓存场景中最常用,能自动保留热点数据;lfu 会删除访问频率最低的 key,更适合长期运行的系统;random 会随机删除一些 key,一般不推荐使用。
其次是针对设置了过期时间的 key,有 volatile-lru、volatile-lfu、volatile-ttl 和 volatile-random。
lru 在混合存储场景中经常使用。
lfu 适合需要保护某些重要数据不被淘汰的场景;ttl 优先删除即将过期的 key,在用户会话管理系统中推荐使用;random 仍然很少用。
LRU 和 LFU 的区别是什么?
LRU 是 Least Recently Used 的缩写,基于时间维度,淘汰最近最少访问的键。
LFU 是 Least Frequently Used 的缩写,基于次数维度,淘汰访问频率最低的键。
假设缓存中有三个数据 A、B、C,在 LRU 场景下,如果访问顺序是 A→B→C→A,那么此时的 LRU 顺序是B→C→A,如果需要淘汰,会先删除 B。
但在 LFU 场景下,如果 A 被访问了 5 次,B 被访问了 2 次,C 被访问了 1 次,那么无论最近的访问顺序如何,都会优先淘汰 C,因为它的访问频率最低。
LRU 更适合有明显时间局部性的场景,比如在新闻网站中,用户更关心最新的新闻,而昨天的新闻访问量会急剧下降。这种情况下,LRU 能很好地保留用户当前关心的热点内容。
LFU 则更适合有长期访问模式的场景,更强调“热度”,比如在电商平台中,某些商品可能长期保持热销状态,即使它们的访问时间间隔较长,但由于访问频率高,LFU 会优先保留这些商品的信息。
Redis发生阻塞了怎么解决?
通常情况下,大Key 是导致 Redis 阻塞的主要原因之一。比如说直接 DEL 一个包含几百万个元素的 Set,就会导致 Redis 阻塞几秒钟甚至更久。
这时候可以用 UNLINK 命令替代 DEL 来异步删除,避免阻塞主线程。
对于非常大的集合,可以使用 SCAN 命令分批删除。
另外,当 Redis 使用的内存超过物理内存时,操作系统会将部分内存交换到磁盘,这时候会导致 Redis 响应变慢。我的处理方式是:
使用 free -h 检查内存的使用情况 ;确认 Redis 的 maxmemory 设置是否合理;如果发生了内存交换,立即调整 maxmemory 并清理一些不重要的数据。
大量的客户端连接也可能会导致阻塞,这时候最好检查一下连接池的配置。
