目录
背景
最近sit环境的redis服务器出现了报错信息:XXX失败: OOM command not allowed when used memory > 'maxmemory'.,初步设想是redis内存溢出,导致key无法插入
排查步骤
- 登录redis客户端,通过 ./redis-cli -h IP -p port -a passwd 或者 RedisDesktopManager
- 输入命令行:info memory 查看内存信息
Connected.
xx.x.xx.x@sit:0>info memory
"# Memory
used_memory:915574200 #由Redis分配器分配的内存总量,包含redis进程内部的开销和数据占用的内存(所有key及其value占用的内存)
used_memory_human:873.16M
used_memory_rss:1051254784 #从操作系统的角度,返回Redis已分配的内存总量(俗称常驻集大小)。这个值和 top 、 ps 等命令的输出一致
used_memory_rss_human:1002.55M
used_memory_peak:4297736416 #Redis的内存消耗峰值(字节单位)
used_memory_peak_human:4.00G
used_memory_peak_perc:21.30% # 使用内存与峰值内存的百分比(used_memory / used_memory_peak) *100%
used_memory_overhead:43275440 # Redis维护数据集的内部机制所需的内存开销,包括所有客户端输出缓冲区、查询缓冲区、AOF重写缓冲区和主从复制的backlog
used_memory_startup:35352360 # Redis启动完成使用的内存
used_memory_dataset:872298760 # 数据占用的内存(used_memory-used_memory_overhead)
used_memory_dataset_perc:99.10% # 数据占用的内存大小百分比,(used_memory_dataset / (used_memory - used_memory_startup))*100%
total_system_memory:403513290752 # 主机内存总量(byte)
total_system_memory_human:375.80G
used_memory_lua:47104 # Lua引擎存储占用的内存(byte)
used_memory_lua_human:46.00K
maxmemory:4294967296 # 配置中设置的最大可使用内存值(byte),默认0,不限制
maxmemory_human:4.00G
maxmemory_policy:noeviction # 当达到maxmemory时key的淘汰策略
mem_fragmentation_ratio:1.15 # 碎片率(used_memory_rss / used_memory),正常(1,1.6),大于比例说明内存碎片严重
mem_allocator:jemalloc-4.0.3 # 内存分配器
active_defrag_running:0 # 活动碎片整理是否处于活动状态(0没有,1正在运行)
lazyfree_pending_objects:0 # 0-不存在延迟释放的挂起对象
备注:redis的 info memory命令信息详解:https://blog.csdn.net/lingeio/article/details/104670927/
3.观察主要指标:
used_memory_peak_human 内存峰值,maxmemory 最大内存基本持平,used_memory_dataset_perc 达到99.10%,key没释放内存,
主要原因有maxmemory_policy内存淘汰策略为noeviction 永不过期,返回错误,永远不会淘汰key
改进
Redis的maxmemory_policy内存淘汰策略有:
1、volatile-lru:只对设置了过期时间的key进行LRU(默认值)
2、allkeys-lru : 删除lru算法的key
3、volatile-random:随机删除即将过期key
4、allkeys-random:随机删除
5、volatile-ttl : 删除即将过期的
6、noeviction : 永不过期,返回错误
改进方式有:
a. 将 maxmemory_policy设置为allkeys-lru : 删除lru算法的key ,将最近未被使用的key删除掉,
b.考虑对redis扩容 然后在代码里维护key的删除