配置allkeys-lru的GCP Memorystore Redis仍出现内存耗尽问题求助
确认maxmemory配置有效性
用CONFIG GET maxmemory查看当前内存上限设置,确保值不为0(禁用内存限制),且与GCP Memorystore实例的实际可用内存匹配(注意预留系统进程占用的内存,不要设满实例的全部内存)。如果maxmemory设置远低于实例内存,会提前触发OOM;如果设为0,LRU策略完全不生效。检查LRU采样精度
Redis的LRU是基于采样的,默认maxmemory-samples值为5,采样数过低可能导致回收逻辑不够精准,无法及时淘汰最久未使用的键。用CONFIG GET maxmemory-samples查看,可尝试调高到10(CONFIG SET maxmemory-samples 10),提升LRU淘汰的准确性。验证键的TTL实际生效情况
即使代码逻辑里设置了2小时TTL,也可能存在疏漏:- 随机抽查部分键的TTL:
TTL <key>,确认是否存在大量永不过期(返回-1)的键; - 检查是否有操作覆盖TTL:比如用不带TTL的
SET命令更新已设TTL的键,会清除原有TTL,导致键变为永久有效; - 用
SCAN遍历部分键,统计TTL分布,确认是否有大量键未正确设置过期时间。
- 随机抽查部分键的TTL:
排查内存碎片问题
用INFO memory查看mem_fragmentation_ratio指标,如果该值大于1.5,说明内存碎片严重——此时Redis的逻辑内存(used_memory)可能未达maxmemory,但物理内存(used_memory_rss)已耗尽,触发OOM。GCP Memorystore可通过重启实例整理碎片,同时排查是否存在频繁修改的大键(如大哈希、列表)加剧碎片产生。核对内存统计指标
查看INFO memory中的used_memory(逻辑内存使用)、used_memory_peak(历史峰值)、used_memory_rss(物理内存占用),明确是逻辑内存触达maxmemory导致LRU未及时回收,还是物理内存因碎片/系统占用先耗尽。检查慢查询与阻塞操作
慢查询或阻塞命令(如大键删除、KEYS命令、复杂聚合操作)会占用Redis主线程,导致LRU回收任务无法及时执行。用SLOWLOG GET查看慢查询日志,定位耗时过长的命令并优化。确认allkeys-lru策略生效与写入压力
用CONFIG GET maxmemory-policy确认策略确实是allkeys-lru,避免配置被覆盖。如果写入请求量远大于LRU回收速度,即使策略生效,也会出现内存耗尽——这种情况需考虑扩容实例或优化缓存写入逻辑(比如降低非必要缓存的写入频率)。
内容的提问来源于stack exchange,提问作者patb

